diff options
Diffstat (limited to 'Source/DirectFB/interfaces/IDirectFBImageProvider')
6 files changed, 3571 insertions, 0 deletions
diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.am b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.am new file mode 100755 index 0000000..f512afd --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.am @@ -0,0 +1,82 @@ +## Makefile.am for DirectFB/interfaces/IDirectFBImageProvider + +idirectfbimageproviderdir = $(MODULEDIR)/interfaces/IDirectFBImageProvider + +if GIF_PROVIDER +GIF_PROVIDER_LTLIB = libidirectfbimageprovider_gif.la +else +GIF_PROVIDER_LTLIB = +endif + +if JPEG_PROVIDER +JPEG_PROVIDER_LTLIB = libidirectfbimageprovider_jpeg.la +else +JPEG_PROVIDER_LTLIB = +endif + +if PNG_PROVIDER +PNG_PROVIDER_LTLIB = libidirectfbimageprovider_png.la +else +PNG_PROVIDER_LTLIB = +endif + + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src + +AM_CPPFLAGS = -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + +idirectfbimageprovider_LTLIBRARIES = \ + libidirectfbimageprovider_dfiff.la \ + $(GIF_PROVIDER_LTLIB) \ + $(JPEG_PROVIDER_LTLIB) \ + $(PNG_PROVIDER_LTLIB) + +if BUILD_STATIC +idirectfbimageprovider_DATA = $(idirectfbimageprovider_LTLIBRARIES:.la=.o) +endif + + +libidirectfbimageprovider_png_la_SOURCES = idirectfbimageprovider_png.c + +libidirectfbimageprovider_png_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBPNG) + +libidirectfbimageprovider_png_la_LDFLAGS = -avoid-version -module + + +libidirectfbimageprovider_dfiff_la_SOURCES = idirectfbimageprovider_dfiff.c + +libidirectfbimageprovider_dfiff_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_dfiff_la_LDFLAGS = -avoid-version -module + + +libidirectfbimageprovider_gif_la_SOURCES = idirectfbimageprovider_gif.c + +libidirectfbimageprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_gif_la_LDFLAGS = -avoid-version -module + + +libidirectfbimageprovider_jpeg_la_SOURCES = idirectfbimageprovider_jpeg.c + +libidirectfbimageprovider_jpeg_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBJPEG) + +libidirectfbimageprovider_jpeg_la_LDFLAGS = -avoid-version -module + + +include $(top_srcdir)/rules/libobject.make diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.in b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.in new file mode 100755 index 0000000..4f7e8d2 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.in @@ -0,0 +1,683 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/rules/libobject.make +subdir = interfaces/IDirectFBImageProvider +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(idirectfbimageproviderdir)" \ + "$(DESTDIR)$(idirectfbimageproviderdir)" +idirectfbimageproviderLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(idirectfbimageprovider_LTLIBRARIES) +libidirectfbimageprovider_dfiff_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbimageprovider_dfiff_la_OBJECTS = \ + idirectfbimageprovider_dfiff.lo +libidirectfbimageprovider_dfiff_la_OBJECTS = \ + $(am_libidirectfbimageprovider_dfiff_la_OBJECTS) +libidirectfbimageprovider_dfiff_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_dfiff_la_LDFLAGS) $(LDFLAGS) -o $@ +libidirectfbimageprovider_gif_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbimageprovider_gif_la_OBJECTS = \ + idirectfbimageprovider_gif.lo +libidirectfbimageprovider_gif_la_OBJECTS = \ + $(am_libidirectfbimageprovider_gif_la_OBJECTS) +libidirectfbimageprovider_gif_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_gif_la_LDFLAGS) $(LDFLAGS) -o $@ +@GIF_PROVIDER_TRUE@am_libidirectfbimageprovider_gif_la_rpath = -rpath \ +@GIF_PROVIDER_TRUE@ $(idirectfbimageproviderdir) +am__DEPENDENCIES_1 = +libidirectfbimageprovider_jpeg_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la $(am__DEPENDENCIES_1) +am_libidirectfbimageprovider_jpeg_la_OBJECTS = \ + idirectfbimageprovider_jpeg.lo +libidirectfbimageprovider_jpeg_la_OBJECTS = \ + $(am_libidirectfbimageprovider_jpeg_la_OBJECTS) +libidirectfbimageprovider_jpeg_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_jpeg_la_LDFLAGS) $(LDFLAGS) -o $@ +@JPEG_PROVIDER_TRUE@am_libidirectfbimageprovider_jpeg_la_rpath = \ +@JPEG_PROVIDER_TRUE@ -rpath $(idirectfbimageproviderdir) +libidirectfbimageprovider_png_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la $(am__DEPENDENCIES_1) +am_libidirectfbimageprovider_png_la_OBJECTS = \ + idirectfbimageprovider_png.lo +libidirectfbimageprovider_png_la_OBJECTS = \ + $(am_libidirectfbimageprovider_png_la_OBJECTS) +libidirectfbimageprovider_png_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_png_la_LDFLAGS) $(LDFLAGS) -o $@ +@PNG_PROVIDER_TRUE@am_libidirectfbimageprovider_png_la_rpath = -rpath \ +@PNG_PROVIDER_TRUE@ $(idirectfbimageproviderdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libidirectfbimageprovider_dfiff_la_SOURCES) \ + $(libidirectfbimageprovider_gif_la_SOURCES) \ + $(libidirectfbimageprovider_jpeg_la_SOURCES) \ + $(libidirectfbimageprovider_png_la_SOURCES) +DIST_SOURCES = $(libidirectfbimageprovider_dfiff_la_SOURCES) \ + $(libidirectfbimageprovider_gif_la_SOURCES) \ + $(libidirectfbimageprovider_jpeg_la_SOURCES) \ + $(libidirectfbimageprovider_png_la_SOURCES) +idirectfbimageproviderDATA_INSTALL = $(INSTALL_DATA) +DATA = $(idirectfbimageprovider_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ASFLAGS = @ASFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@ +DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@ +DFB_LDFLAGS = @DFB_LDFLAGS@ +DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@ +DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@ +DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@ +DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@ +DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@ +DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@ +DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@ +DIRECTFB_VERSION = @DIRECTFB_VERSION@ +DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@ +DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@ +DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@ +DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@ +DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@ +DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@ +DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@ +DSYMUTIL = @DSYMUTIL@ +DYNLIB = @DYNLIB@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +FREETYPE_PROVIDER = @FREETYPE_PROVIDER@ +FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@ +FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@ +FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@ +GIF_PROVIDER = @GIF_PROVIDER@ +GREP = @GREP@ +HAVE_LINUX = @HAVE_LINUX@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@ +JPEG_PROVIDER = @JPEG_PROVIDER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPNG_CONFIG = @LIBPNG_CONFIG@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_BINARY = @LT_BINARY@ +LT_CURRENT = @LT_CURRENT@ +LT_RELEASE = @LT_RELEASE@ +LT_REVISION = @LT_REVISION@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAN2HTML = @MAN2HTML@ +MKDIR_P = @MKDIR_P@ +MODULEDIR = @MODULEDIR@ +MODULEDIRNAME = @MODULEDIRNAME@ +NMEDIT = @NMEDIT@ +OBJEXT = @OBJEXT@ +OSX_LIBS = @OSX_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PNG_PROVIDER = @PNG_PROVIDER@ +RANLIB = @RANLIB@ +RUNTIME_SYSROOT = @RUNTIME_SYSROOT@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOPATH = @SOPATH@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +SYSFS_LIBS = @SYSFS_LIBS@ +THREADFLAGS = @THREADFLAGS@ +THREADLIB = @THREADLIB@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +VERSION = @VERSION@ +VNC_CFLAGS = @VNC_CFLAGS@ +VNC_CONFIG = @VNC_CONFIG@ +VNC_LIBS = @VNC_LIBS@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +idirectfbimageproviderdir = $(MODULEDIR)/interfaces/IDirectFBImageProvider +@GIF_PROVIDER_FALSE@GIF_PROVIDER_LTLIB = +@GIF_PROVIDER_TRUE@GIF_PROVIDER_LTLIB = libidirectfbimageprovider_gif.la +@JPEG_PROVIDER_FALSE@JPEG_PROVIDER_LTLIB = +@JPEG_PROVIDER_TRUE@JPEG_PROVIDER_LTLIB = libidirectfbimageprovider_jpeg.la +@PNG_PROVIDER_FALSE@PNG_PROVIDER_LTLIB = +@PNG_PROVIDER_TRUE@PNG_PROVIDER_LTLIB = libidirectfbimageprovider_png.la +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src + +AM_CPPFLAGS = -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" +idirectfbimageprovider_LTLIBRARIES = \ + libidirectfbimageprovider_dfiff.la \ + $(GIF_PROVIDER_LTLIB) \ + $(JPEG_PROVIDER_LTLIB) \ + $(PNG_PROVIDER_LTLIB) + +@BUILD_STATIC_TRUE@idirectfbimageprovider_DATA = $(idirectfbimageprovider_LTLIBRARIES:.la=.o) +libidirectfbimageprovider_png_la_SOURCES = idirectfbimageprovider_png.c +libidirectfbimageprovider_png_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBPNG) + +libidirectfbimageprovider_png_la_LDFLAGS = -avoid-version -module +libidirectfbimageprovider_dfiff_la_SOURCES = idirectfbimageprovider_dfiff.c +libidirectfbimageprovider_dfiff_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_dfiff_la_LDFLAGS = -avoid-version -module +libidirectfbimageprovider_gif_la_SOURCES = idirectfbimageprovider_gif.c +libidirectfbimageprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_gif_la_LDFLAGS = -avoid-version -module +libidirectfbimageprovider_jpeg_la_SOURCES = idirectfbimageprovider_jpeg.c +libidirectfbimageprovider_jpeg_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBJPEG) + +libidirectfbimageprovider_jpeg_la_LDFLAGS = -avoid-version -module +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.make $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interfaces/IDirectFBImageProvider/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu interfaces/IDirectFBImageProvider/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-idirectfbimageproviderLTLIBRARIES: $(idirectfbimageprovider_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(idirectfbimageproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbimageproviderdir)" + @list='$(idirectfbimageprovider_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbimageproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(idirectfbimageproviderdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbimageproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(idirectfbimageproviderdir)/$$f"; \ + else :; fi; \ + done + +uninstall-idirectfbimageproviderLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbimageprovider_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(idirectfbimageproviderdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(idirectfbimageproviderdir)/$$p"; \ + done + +clean-idirectfbimageproviderLTLIBRARIES: + -test -z "$(idirectfbimageprovider_LTLIBRARIES)" || rm -f $(idirectfbimageprovider_LTLIBRARIES) + @list='$(idirectfbimageprovider_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libidirectfbimageprovider_dfiff.la: $(libidirectfbimageprovider_dfiff_la_OBJECTS) $(libidirectfbimageprovider_dfiff_la_DEPENDENCIES) + $(libidirectfbimageprovider_dfiff_la_LINK) -rpath $(idirectfbimageproviderdir) $(libidirectfbimageprovider_dfiff_la_OBJECTS) $(libidirectfbimageprovider_dfiff_la_LIBADD) $(LIBS) +libidirectfbimageprovider_gif.la: $(libidirectfbimageprovider_gif_la_OBJECTS) $(libidirectfbimageprovider_gif_la_DEPENDENCIES) + $(libidirectfbimageprovider_gif_la_LINK) $(am_libidirectfbimageprovider_gif_la_rpath) $(libidirectfbimageprovider_gif_la_OBJECTS) $(libidirectfbimageprovider_gif_la_LIBADD) $(LIBS) +libidirectfbimageprovider_jpeg.la: $(libidirectfbimageprovider_jpeg_la_OBJECTS) $(libidirectfbimageprovider_jpeg_la_DEPENDENCIES) + $(libidirectfbimageprovider_jpeg_la_LINK) $(am_libidirectfbimageprovider_jpeg_la_rpath) $(libidirectfbimageprovider_jpeg_la_OBJECTS) $(libidirectfbimageprovider_jpeg_la_LIBADD) $(LIBS) +libidirectfbimageprovider_png.la: $(libidirectfbimageprovider_png_la_OBJECTS) $(libidirectfbimageprovider_png_la_DEPENDENCIES) + $(libidirectfbimageprovider_png_la_LINK) $(am_libidirectfbimageprovider_png_la_rpath) $(libidirectfbimageprovider_png_la_OBJECTS) $(libidirectfbimageprovider_png_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_dfiff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_gif.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_jpeg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_png.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-idirectfbimageproviderDATA: $(idirectfbimageprovider_DATA) + @$(NORMAL_INSTALL) + test -z "$(idirectfbimageproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbimageproviderdir)" + @list='$(idirectfbimageprovider_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(idirectfbimageproviderDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(idirectfbimageproviderdir)/$$f'"; \ + $(idirectfbimageproviderDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(idirectfbimageproviderdir)/$$f"; \ + done + +uninstall-idirectfbimageproviderDATA: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbimageprovider_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(idirectfbimageproviderdir)/$$f'"; \ + rm -f "$(DESTDIR)$(idirectfbimageproviderdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(idirectfbimageproviderdir)" "$(DESTDIR)$(idirectfbimageproviderdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-idirectfbimageproviderLTLIBRARIES \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-idirectfbimageproviderDATA \ + install-idirectfbimageproviderLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-idirectfbimageproviderDATA \ + uninstall-idirectfbimageproviderLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-idirectfbimageproviderLTLIBRARIES clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-idirectfbimageproviderDATA \ + install-idirectfbimageproviderLTLIBRARIES install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am \ + uninstall-idirectfbimageproviderDATA \ + uninstall-idirectfbimageproviderLTLIBRARIES + +%.o: .libs/%.a %.la + rm -f $<.tmp/*.o + if test -d $<.tmp; then rmdir $<.tmp; fi + mkdir $<.tmp + (cd $<.tmp && $(AR) x ../../$<) + $(LD) -o $@ -r $<.tmp/*.o + rm -f $<.tmp/*.o && rmdir $<.tmp + +.PHONY: $(LTLIBRARIES:%.la=.libs/%.a) +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_dfiff.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_dfiff.c new file mode 100755 index 0000000..56207e4 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_dfiff.c @@ -0,0 +1,374 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + All rights reserved. + + This file is subject to the terms and conditions of the MIT License: + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include <config.h> + +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <string.h> +#include <unistd.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <direct/debug.h> +#include <direct/interface.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <idirectfb.h> + +#include <display/idirectfbsurface.h> + +#include <misc/gfx_util.h> + +#include <media/idirectfbdatabuffer.h> +#include <media/idirectfbimageprovider.h> + +#include <dfiff.h> + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, DFIFF ) + + +/* + * private data struct of IDirectFBImageProvider_DFIFF + */ +typedef struct { + int ref; /* reference counter */ + + void *ptr; /* pointer to raw file data (mapped) */ + int len; /* data length, i.e. file size */ + + DIRenderCallback render_callback; + void *render_callback_context; + + CoreDFB *core; +} IDirectFBImageProvider_DFIFF_data; + + + + + +static void +IDirectFBImageProvider_DFIFF_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_DFIFF_data *data = thiz->priv; + + munmap( data->ptr, data->len ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_DFIFF_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_DFIFF_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + if (--data->ref == 0) { + IDirectFBImageProvider_DFIFF_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_DFIFF_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + const DFIFFHeader *header; + DFBRectangle rect; + DFBRectangle clipped; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + if (!destination) + return DFB_INVARG; + + DIRECT_INTERFACE_GET_DATA_FROM (destination, dst_data, IDirectFBSurface); + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DEAD; + + if (dest_rect) { + rect.x = dest_rect->x + dst_data->area.wanted.x; + rect.y = dest_rect->y + dst_data->area.wanted.y; + rect.w = dest_rect->w; + rect.h = dest_rect->h; + } + else + rect = dst_data->area.wanted; + + if (rect.w < 1 || rect.h < 1) + return DFB_INVAREA; + + clipped = rect; + + if (!dfb_rectangle_intersect( &clipped, &dst_data->area.current )) + return DFB_INVAREA; + + header = data->ptr; + + if (DFB_RECTANGLE_EQUAL( rect, clipped ) && + rect.w == header->width && rect.h == header->height && + dst_surface->config.format == header->format) + { + ret = dfb_surface_write_buffer( dst_surface, CSBR_BACK, + data->ptr + sizeof(DFIFFHeader), header->pitch, &rect ); + if (ret) + return ret; + } + else { + IDirectFBSurface *source; + DFBSurfaceDescription desc; + DFBSurfaceCapabilities caps; + DFBRegion clip = DFB_REGION_INIT_FROM_RECTANGLE( &clipped ); + DFBRegion old_clip; + + thiz->GetSurfaceDescription( thiz, &desc ); + + desc.flags |= DSDESC_PREALLOCATED; + desc.preallocated[0].data = data->ptr + sizeof(DFIFFHeader); + desc.preallocated[0].pitch = header->pitch; + + ret = idirectfb_singleton->CreateSurface( idirectfb_singleton, &desc, &source ); + if (ret) + return ret; + + destination->GetCapabilities( destination, &caps ); + + if (caps & DSCAPS_PREMULTIPLIED && DFB_PIXELFORMAT_HAS_ALPHA(desc.pixelformat)) + destination->SetBlittingFlags( destination, DSBLIT_SRC_PREMULTIPLY ); + else + destination->SetBlittingFlags( destination, DSBLIT_NOFX ); + + destination->GetClip( destination, &old_clip ); + destination->SetClip( destination, &clip ); + + destination->StretchBlit( destination, source, NULL, &rect ); + + destination->SetClip( destination, &old_clip ); + + destination->SetBlittingFlags( destination, DSBLIT_NOFX ); + + destination->ReleaseSource( destination ); + + source->Release( source ); + } + + if (data->render_callback) { + DFBRectangle rect = { 0, 0, clipped.w, clipped.h }; + data->render_callback( &rect, data->render_callback_context ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_DFIFF_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +/* Loading routines */ + +static DFBResult +IDirectFBImageProvider_DFIFF_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + const DFIFFHeader *header; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + header = data->ptr; + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->width = header->width; + dsc->height = header->height; + dsc->pixelformat = header->format; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_DFIFF_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *desc ) +{ + const DFIFFHeader *header; + + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_DFIFF) + + if (!desc) + return DFB_INVARG; + + header = data->ptr; + + desc->caps = DICAPS_NONE; + + if (DFB_PIXELFORMAT_HAS_ALPHA( header->format )) + desc->caps |= DICAPS_ALPHACHANNEL; + + return DFB_OK; +} + + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (!strncmp( (const char*) ctx->header, "DFIFF", 5 )) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + DFBResult ret; + struct stat stat; + void *ptr; + int fd = -1; + IDirectFBDataBuffer_data *buffer_data; + + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_DFIFF) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + D_MAGIC_ASSERT( (IAny*) buffer, DirectInterface ); + + /* Get the buffer's private data. */ + buffer_data = buffer->priv; + if (!buffer_data) { + ret = DFB_DEAD; + goto error; + } + + /* Check for valid filename. */ + if (!buffer_data->filename) { + ret = DFB_UNSUPPORTED; + goto error; + } + + /* Open the file. */ + fd = open( buffer_data->filename, O_RDONLY ); + if (fd < 0) { + ret = errno2result( errno ); + D_PERROR( "ImageProvider/DFIFF: Failure during open() of '%s'!\n", buffer_data->filename ); + goto error; + } + + /* Query file size etc. */ + if (fstat( fd, &stat ) < 0) { + ret = errno2result( errno ); + D_PERROR( "ImageProvider/DFIFF: Failure during fstat() of '%s'!\n", buffer_data->filename ); + goto error; + } + + /* Memory map the file. */ + ptr = mmap( NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0 ); + if (ptr == MAP_FAILED) { + ret = errno2result( errno ); + D_PERROR( "ImageProvider/DFIFF: Failure during mmap() of '%s'!\n", buffer_data->filename ); + goto error; + } + + /* Already close, we still have the map. */ + close( fd ); + + data->ref = 1; + data->ptr = ptr; + data->len = stat.st_size; + data->core = core; + + thiz->AddRef = IDirectFBImageProvider_DFIFF_AddRef; + thiz->Release = IDirectFBImageProvider_DFIFF_Release; + thiz->RenderTo = IDirectFBImageProvider_DFIFF_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_DFIFF_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_DFIFF_GetImageDescription; + thiz->GetSurfaceDescription = IDirectFBImageProvider_DFIFF_GetSurfaceDescription; + + return DFB_OK; + +error: + if (fd != -1) + close( fd ); + + DIRECT_DEALLOCATE_INTERFACE(thiz); + + return ret; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_gif.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_gif.c new file mode 100755 index 0000000..f9e8229 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_gif.c @@ -0,0 +1,924 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbimageprovider.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/layers.h> +#include <core/surface.h> + +#include <misc/gfx_util.h> +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <misc/util.h> + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, GIF ) + + +#ifndef NODEBUG +#define GIFERRORMSG(x...) { fprintf( stderr, "(GIFLOADER) "x ); \ + fprintf( stderr, "\n" ); } +#else +#define GIFERRORMSG(x...) +#endif + +#define MAXCOLORMAPSIZE 256 + +#define CM_RED 0 +#define CM_GREEN 1 +#define CM_BLUE 2 + +#define MAX_LWZ_BITS 12 + +#define INTERLACE 0x40 +#define LOCALCOLORMAP 0x80 + +#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) + +#define LM_to_uint(a,b) (((b)<<8)|(a)) + +/* + * private data struct of IDirectFBImageProvider_GIF + */ +typedef struct { + int ref; /* reference counter */ + + IDirectFBDataBuffer *buffer; + + u32 *image; + int image_width; + int image_height; + bool image_transparency; + u32 image_colorkey; + + unsigned int Width; + unsigned int Height; + u8 ColorMap[3][MAXCOLORMAPSIZE]; + unsigned int BitPixel; + unsigned int ColorResolution; + u32 Background; + unsigned int AspectRatio; + + + int GrayScale; + int transparent; + int delayTime; + int inputFlag; + int disposal; + + + u8 buf[280]; + int curbit, lastbit, done, last_byte; + + + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1<< MAX_LWZ_BITS)]; + int stack[(1<<(MAX_LWZ_BITS))*2], *sp; + + DIRenderCallback render_callback; + void *render_callback_ctx; + + CoreDFB *core; +} IDirectFBImageProvider_GIF_data; + +static bool verbose = false; +static bool showComment = false; +static bool ZeroDataBlock = false; + +static u32* ReadGIF( IDirectFBImageProvider_GIF_data *data, int imageNumber, + int *width, int *height, bool *transparency, + u32 *key_rgb, bool alpha, bool headeronly); + +static bool ReadOK( IDirectFBDataBuffer *buffer, void *data, unsigned int len ); + + +static DirectResult +IDirectFBImageProvider_GIF_AddRef ( IDirectFBImageProvider *thiz ); + +static DirectResult +IDirectFBImageProvider_GIF_Release ( IDirectFBImageProvider *thiz ); + +static DFBResult +IDirectFBImageProvider_GIF_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *destination_rect ); + +static DFBResult +IDirectFBImageProvider_GIF_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ); + +static DFBResult +IDirectFBImageProvider_GIF_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ); + +static DFBResult +IDirectFBImageProvider_GIF_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ); + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (strncmp ((char*) ctx->header, "GIF8", 4) == 0) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_GIF) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + data->ref = 1; + + data->GrayScale = -1; + data->transparent = -1; + data->delayTime = -1; + + data->core = core; + data->buffer = buffer; + buffer->AddRef( buffer ); + + data->image = ReadGIF( data, 1, &data->image_width, &data->image_height, + &data->image_transparency, &data->image_colorkey, + true, false ); + + buffer->Release( buffer ); + data->buffer = NULL; + + if (!data->image) { + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + + thiz->AddRef = IDirectFBImageProvider_GIF_AddRef; + thiz->Release = IDirectFBImageProvider_GIF_Release; + thiz->RenderTo = IDirectFBImageProvider_GIF_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_GIF_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_GIF_GetImageDescription; + thiz->GetSurfaceDescription = + IDirectFBImageProvider_GIF_GetSurfaceDescription; + + return DFB_OK; +} + +static void +IDirectFBImageProvider_GIF_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_GIF_data *data = + (IDirectFBImageProvider_GIF_data*)thiz->priv; + + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_GIF_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_GIF) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_GIF_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_GIF) + + if (--data->ref == 0) { + IDirectFBImageProvider_GIF_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + DFBRegion clip; + DFBRectangle rect; + DFBSurfacePixelFormat format; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + dst_data = (IDirectFBSurface_data*) destination->priv; + if (!dst_data) + return DFB_DEAD; + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + else { + rect = dst_data->area.wanted; + } + + ret = destination->GetPixelFormat( destination, &format ); + if (ret) + return ret; + + /* actual loading and rendering */ + if (dfb_rectangle_region_intersects( &rect, &clip )) { + CoreSurfaceBufferLock lock; + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + dfb_scale_linear_32( data->image, data->image_width, data->image_height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + + dfb_surface_unlock_buffer( dst_surface, &lock ); + + if (data->render_callback) { + DIRenderCallbackResult r; + + rect.x = 0; + rect.y = 0; + rect.w = data->image_width; + rect.h = data->image_height; + + r = data->render_callback( &rect, data->render_callback_ctx ); + + if (r != DIRCR_OK) + return DFB_INTERRUPTED; + } + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + data->render_callback = callback; + data->render_callback_ctx = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->width = data->image_width; + dsc->height = data->image_height; + dsc->pixelformat = dfb_primary_layer_pixelformat(); + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + if (data->image_transparency) { + dsc->caps = DICAPS_COLORKEY; + + dsc->colorkey_r = (data->image_colorkey & 0xff0000) >> 16; + dsc->colorkey_g = (data->image_colorkey & 0x00ff00) >> 8; + dsc->colorkey_b = (data->image_colorkey & 0x0000ff); + } + else + dsc->caps = DICAPS_NONE; + + return DFB_OK; +} + + +/********************************** + GIF Loader Code + **********************************/ + +static int ReadColorMap( IDirectFBDataBuffer *buffer, int number, + u8 buf[3][MAXCOLORMAPSIZE] ) +{ + int i; + u8 rgb[3]; + + for (i = 0; i < number; ++i) { + if (! ReadOK( buffer, rgb, sizeof(rgb) )) { + GIFERRORMSG("bad colormap" ); + return true; + } + + buf[CM_RED][i] = rgb[0] ; + buf[CM_GREEN][i] = rgb[1] ; + buf[CM_BLUE][i] = rgb[2] ; + } + return false; +} + +static int GetDataBlock(IDirectFBDataBuffer *buffer, u8 *buf) +{ + unsigned char count; + + if (! ReadOK( buffer, &count, 1 )) { + GIFERRORMSG("error in getting DataBlock size" ); + return -1; + } + ZeroDataBlock = count == 0; + + if ((count != 0) && (! ReadOK( buffer, buf, count ))) { + GIFERRORMSG("error in reading DataBlock" ); + return -1; + } + + return count; +} + +static int GetCode(IDirectFBImageProvider_GIF_data *data, int code_size, int flag) +{ + int i, j, ret; + unsigned char count; + + if (flag) { + data->curbit = 0; + data->lastbit = 0; + data->done = false; + return 0; + } + + if ( (data->curbit+code_size) >= data->lastbit) { + if (data->done) { + if (data->curbit >= data->lastbit) { + GIFERRORMSG("ran off the end of my bits" ); + } + return -1; + } + data->buf[0] = data->buf[data->last_byte-2]; + data->buf[1] = data->buf[data->last_byte-1]; + + if ((count = GetDataBlock( data->buffer, &data->buf[2] )) == 0) { + data->done = true; + } + + data->last_byte = 2 + count; + data->curbit = (data->curbit - data->lastbit) + 16; + data->lastbit = (2+count) * 8; + } + + ret = 0; + for (i = data->curbit, j = 0; j < code_size; ++i, ++j) { + ret |= ((data->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + } + data->curbit += code_size; + + return ret; +} + +static int DoExtension( IDirectFBImageProvider_GIF_data *data, int label ) +{ + unsigned char buf[256] = { 0 }; + char *str; + + switch (label) { + case 0x01: /* Plain Text Extension */ + str = "Plain Text Extension"; + break; + case 0xff: /* Application Extension */ + str = "Application Extension"; + break; + case 0xfe: /* Comment Extension */ + str = "Comment Extension"; + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) { + if (showComment) + GIFERRORMSG("gif comment: %s", buf ); + } + return false; + case 0xf9: /* Graphic Control Extension */ + str = "Graphic Control Extension"; + (void) GetDataBlock( data->buffer, (u8*) buf ); + data->disposal = (buf[0] >> 2) & 0x7; + data->inputFlag = (buf[0] >> 1) & 0x1; + data->delayTime = LM_to_uint( buf[1], buf[2] ); + if ((buf[0] & 0x1) != 0) { + data->transparent = buf[3]; + } + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + ; + return false; + default: + str = (char*) buf; + snprintf(str, 256, "UNKNOWN (0x%02x)", label); + break; + } + + if (verbose) + GIFERRORMSG("got a '%s' extension", str ); + + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + ; + + return false; +} + +static int LWZReadByte( IDirectFBImageProvider_GIF_data *data, int flag, int input_code_size ) +{ + int code, incode; + int i; + + if (flag) { + data->set_code_size = input_code_size; + data->code_size = data->set_code_size+1; + data->clear_code = 1 << data->set_code_size ; + data->end_code = data->clear_code + 1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + + GetCode(data, 0, true); + + data->fresh = true; + + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<<MAX_LWZ_BITS); ++i) { + data->table[0][i] = data->table[1][0] = 0; + } + data->sp = data->stack; + + return 0; + } + else if (data->fresh) { + data->fresh = false; + do { + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + } while (data->firstcode == data->clear_code); + + return data->firstcode; + } + + if (data->sp > data->stack) { + return *--data->sp; + } + + while ((code = GetCode( data, data->code_size, false )) >= 0) { + if (code == data->clear_code) { + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<<MAX_LWZ_BITS); ++i) { + data->table[0][i] = data->table[1][i] = 0; + } + data->code_size = data->set_code_size+1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + data->sp = data->stack; + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + + return data->firstcode; + } + else if (code == data->end_code) { + int count; + u8 buf[260]; + + if (ZeroDataBlock) { + return -2; + } + + while ((count = GetDataBlock( data->buffer, buf )) > 0) + ; + + if (count != 0) + GIFERRORMSG("missing EOD in data stream " + "(common occurence)"); + + return -2; + } + + incode = code; + + if (code >= data->max_code) { + *data->sp++ = data->firstcode; + code = data->oldcode; + } + + while (code >= data->clear_code) { + *data->sp++ = data->table[1][code]; + if (code == data->table[0][code]) { + GIFERRORMSG("circular table entry BIG ERROR"); + } + code = data->table[0][code]; + } + + *data->sp++ = data->firstcode = data->table[1][code]; + + if ((code = data->max_code) <(1<<MAX_LWZ_BITS)) { + data->table[0][code] = data->oldcode; + data->table[1][code] = data->firstcode; + ++data->max_code; + if ((data->max_code >= data->max_code_size) + && (data->max_code_size < (1<<MAX_LWZ_BITS))) + { + data->max_code_size *= 2; + ++data->code_size; + } + } + + data->oldcode = incode; + + if (data->sp > data->stack) { + return *--data->sp; + } + } + return code; +} + +static int SortColors (const void *a, const void *b) +{ + return (*((const u8 *) a) - *((const u8 *) b)); +} + +/* looks for a color that is not in the colormap and ideally not + even close to the colors used in the colormap */ +static u32 FindColorKey( int n_colors, u8 cmap[3][MAXCOLORMAPSIZE] ) +{ + u32 color = 0xFF000000; + u8 csort[MAXCOLORMAPSIZE]; + int i, j, index, d; + + if (n_colors < 1) + return color; + + D_ASSERT( n_colors <= MAXCOLORMAPSIZE ); + + for (i = 0; i < 3; i++) { + direct_memcpy( csort, cmap[i], n_colors ); + qsort( csort, n_colors, 1, SortColors ); + + for (j = 1, index = 0, d = 0; j < n_colors; j++) { + if (csort[j] - csort[j-1] > d) { + d = csort[j] - csort[j-1]; + index = j; + } + } + if ((csort[0] - 0x0) > d) { + d = csort[0] - 0x0; + index = n_colors; + } + if (0xFF - (csort[n_colors - 1]) > d) { + index = n_colors + 1; + } + + if (index < n_colors) + csort[0] = csort[index] - (d/2); + else if (index == n_colors) + csort[0] = 0x0; + else + csort[0] = 0xFF; + + color |= (csort[0] << (8 * (2 - i))); + } + + return color; +} + +static u32* ReadImage( IDirectFBImageProvider_GIF_data *data, int width, int height, + u8 cmap[3][MAXCOLORMAPSIZE], u32 key_rgb, + bool interlace, bool ignore ) +{ + u8 c; + int v; + int xpos = 0, ypos = 0, pass = 0; + u32 *image; + + /* + ** Initialize the decompression routines + */ + if (! ReadOK( data->buffer, &c, 1 )) + GIFERRORMSG("EOF / read error on image data" ); + + if (LWZReadByte( data, true, c ) < 0) + GIFERRORMSG("error reading image" ); + + /* + ** If this is an "uninteresting picture" ignore it. + */ + if (ignore) { + if (verbose) + GIFERRORMSG("skipping image..." ); + + while (LWZReadByte( data, false, c ) >= 0) + ; + return NULL; + } + + // FIXME: allocates four additional bytes because the scaling functions + // in src/misc/gfx_util.c have an off-by-one bug which causes + // segfaults on darwin/osx (not on linux) + if ((image = D_MALLOC(width * height * 4 + 4)) == NULL) { + GIFERRORMSG("couldn't alloc space for image" ); + } + + if (verbose) { + GIFERRORMSG("reading %d by %d%s GIF image", width, height, + interlace ? " interlaced" : "" ); + } + + while ((v = LWZReadByte( data, false, c )) >= 0 ) { + u32 *dst = image + (ypos * width + xpos); + + if (v == data->transparent) { + *dst++ = key_rgb; + } + else { + *dst++ = (0xFF000000 | + cmap[CM_RED][v] << 16 | + cmap[CM_GREEN][v] << 8 | + cmap[CM_BLUE][v]); + } + + ++xpos; + if (xpos == width) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; + break; + case 2: + ypos += 4; + break; + case 3: + ypos += 2; + break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; + break; + case 2: + ypos = 2; + break; + case 3: + ypos = 1; + break; + default: + goto fini; + } + } + } + else { + ++ypos; + } + } + if (ypos >= height) { + break; + } + } + +fini: + + if (LWZReadByte( data, false, c ) >= 0) { + GIFERRORMSG("too much input data, ignoring extra..."); + } + return image; +} + + +static u32* ReadGIF( IDirectFBImageProvider_GIF_data *data, int imageNumber, + int *width, int *height, bool *transparency, + u32 *key_rgb, bool alpha, bool headeronly) +{ + u8 buf[16]; + u8 c; + u8 localColorMap[3][MAXCOLORMAPSIZE]; + u32 colorKey = 0; + bool useGlobalColormap; + int bitPixel; + int imageCount = 0; + char version[4]; + + if (! ReadOK( data->buffer, buf, 6 )) { + GIFERRORMSG("error reading magic number" ); + } + + if (strncmp( (char *)buf, "GIF", 3 ) != 0) { + GIFERRORMSG("not a GIF file" ); + } + + direct_snputs( version, (char *)buf + 3, 4 ); + + if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { + GIFERRORMSG("bad version number, not '87a' or '89a'" ); + } + + if (! ReadOK(data->buffer,buf,7)) { + GIFERRORMSG("failed to read screen descriptor" ); + } + + data->Width = LM_to_uint( buf[0], buf[1] ); + data->Height = LM_to_uint( buf[2], buf[3] ); + data->BitPixel = 2 << (buf[4] & 0x07); + data->ColorResolution = (((buf[4] & 0x70) >> 3) + 1); + data->Background = buf[5]; + data->AspectRatio = buf[6]; + + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap( data->buffer, data->BitPixel, data->ColorMap )) { + GIFERRORMSG("error reading global colormap" ); + } + } + + if (data->AspectRatio != 0 && data->AspectRatio != 49) { + /* float r = ( (float) data->AspectRatio + 15.0 ) / 64.0; */ + GIFERRORMSG("warning - non-square pixels"); + } + + data->transparent = -1; + data->delayTime = -1; + data->inputFlag = -1; + data->disposal = 0; + + for (;;) { + if (! ReadOK( data->buffer, &c, 1)) { + GIFERRORMSG("EOF / read error on image data" ); + } + + if (c == ';') { /* GIF terminator */ + if (imageCount < imageNumber) { + GIFERRORMSG("only %d image%s found in file", + imageCount, imageCount>1?"s":"" ); + } + return NULL; + } + + if (c == '!') { /* Extension */ + if (! ReadOK( data->buffer, &c, 1)) { + GIFERRORMSG("OF / read error on extention function code"); + } + DoExtension( data, c ); + continue; + } + + if (c != ',') { /* Not a valid start character */ + GIFERRORMSG("bogus character 0x%02x, ignoring", (int) c ); + continue; + } + + ++imageCount; + + if (! ReadOK( data->buffer, buf, 9 )) { + GIFERRORMSG("couldn't read left/top/width/height"); + } + + *width = LM_to_uint( buf[4], buf[5] ); + *height = LM_to_uint( buf[6], buf[7] ); + *transparency = (data->transparent != -1); + + if (headeronly && !(*transparency && key_rgb)) + return NULL; + + useGlobalColormap = ! BitSet( buf[8], LOCALCOLORMAP ); + + if (useGlobalColormap) { + if (*transparency && (key_rgb || !headeronly)) + colorKey = FindColorKey( data->BitPixel, + data->ColorMap ); + } + else { + bitPixel = 2 << (buf[8] & 0x07); + if (ReadColorMap( data->buffer, bitPixel, localColorMap )) + GIFERRORMSG("error reading local colormap" ); + + if (*transparency && (key_rgb || !headeronly)) + colorKey = FindColorKey( bitPixel, localColorMap ); + } + + if (key_rgb) + *key_rgb = colorKey; + + if (headeronly) + return NULL; + + if (alpha) + colorKey &= 0x00FFFFFF; + + return ReadImage( data, *width, *height, + (useGlobalColormap ? + data->ColorMap : localColorMap), colorKey, + BitSet( buf[8], INTERLACE ), + imageCount != imageNumber); + } +} + +static bool +ReadOK( IDirectFBDataBuffer *buffer, void *data, unsigned int len ) +{ + DFBResult ret; + + ret = buffer->WaitForData( buffer, len ); + if (ret) { + DirectFBError( "(DirectFB/ImageProvider_GIF) WaitForData failed", ret ); + return false; + } + + ret = buffer->GetData( buffer, len, data, NULL ); + if (ret) { + DirectFBError( "(DirectFB/ImageProvider_GIF) GetData failed", ret ); + return false; + } + + return true; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c new file mode 100755 index 0000000..e67da17 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c @@ -0,0 +1,640 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbimageprovider.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/layers.h> +#include <core/surface.h> + +#include <misc/gfx_util.h> +#include <misc/util.h> +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> + +#include <setjmp.h> +#include <math.h> + +#undef HAVE_STDLIB_H +#include <jpeglib.h> + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, JPEG ) + +/* + * private data struct of IDirectFBImageProvider_JPEG + */ +typedef struct { + int ref; /* reference counter */ + + IDirectFBDataBuffer *buffer; + + DIRenderCallback render_callback; + void *render_callback_context; + + u32 *image; + int width; + int height; + + CoreDFB *core; +} IDirectFBImageProvider_JPEG_data; + +static DirectResult +IDirectFBImageProvider_JPEG_AddRef ( IDirectFBImageProvider *thiz ); + +static DirectResult +IDirectFBImageProvider_JPEG_Release ( IDirectFBImageProvider *thiz ); + +static DFBResult +IDirectFBImageProvider_JPEG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *destination_rect ); + +static DFBResult +IDirectFBImageProvider_JPEG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ); + +static DFBResult +IDirectFBImageProvider_JPEG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc); + +static DFBResult +IDirectFBImageProvider_JPEG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ); + + +#define JPEG_PROG_BUF_SIZE 0x10000 + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + JOCTET *data; /* start of buffer */ + + IDirectFBDataBuffer *buffer; + + int peekonly; + int peekoffset; +} buffer_source_mgr; + +typedef buffer_source_mgr * buffer_src_ptr; + +static void +buffer_init_source (j_decompress_ptr cinfo) +{ + buffer_src_ptr src = (buffer_src_ptr) cinfo->src; + IDirectFBDataBuffer *buffer = src->buffer; + + buffer->SeekTo( buffer, 0 ); /* ignore return value */ +} + +static boolean +buffer_fill_input_buffer (j_decompress_ptr cinfo) +{ + DFBResult ret; + unsigned int nbytes = 0; + buffer_src_ptr src = (buffer_src_ptr) cinfo->src; + IDirectFBDataBuffer *buffer = src->buffer; + + buffer->WaitForDataWithTimeout( buffer, JPEG_PROG_BUF_SIZE, 1, 0 ); + + if (src->peekonly) { + ret = buffer->PeekData( buffer, JPEG_PROG_BUF_SIZE, + src->peekoffset, src->data, &nbytes ); + src->peekoffset += MAX( nbytes, 0 ); + } + else { + ret = buffer->GetData( buffer, JPEG_PROG_BUF_SIZE, src->data, &nbytes ); + } + + if (ret || nbytes <= 0) { + /* Insert a fake EOI marker */ + src->data[0] = (JOCTET) 0xFF; + src->data[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + + if (ret && ret != DFB_EOF) + DirectFBError( "(DirectFB/ImageProvider_JPEG) GetData failed", ret ); + } + + src->pub.next_input_byte = src->data; + src->pub.bytes_in_buffer = nbytes; + + return TRUE; +} + +static void +buffer_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + buffer_src_ptr src = (buffer_src_ptr) cinfo->src; + + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void)buffer_fill_input_buffer(cinfo); + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void +buffer_term_source (j_decompress_ptr cinfo) +{ +} + +static void +jpeg_buffer_src (j_decompress_ptr cinfo, IDirectFBDataBuffer *buffer, int peekonly) +{ + buffer_src_ptr src; + + cinfo->src = (struct jpeg_source_mgr *) + cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof (buffer_source_mgr)); + + src = (buffer_src_ptr) cinfo->src; + + src->data = (JOCTET *) + cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_PERMANENT, + JPEG_PROG_BUF_SIZE * sizeof (JOCTET)); + + src->buffer = buffer; + src->peekonly = peekonly; + src->peekoffset = 0; + + src->pub.init_source = buffer_init_source; + src->pub.fill_input_buffer = buffer_fill_input_buffer; + src->pub.skip_input_data = buffer_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = buffer_term_source; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +}; + +static void +jpeglib_panic(j_common_ptr cinfo) +{ + struct my_error_mgr *myerr = (struct my_error_mgr*) cinfo->err; + longjmp(myerr->setjmp_buffer, 1); +} + +static inline void +copy_line32( u32 *argb, const u8 *rgb, int width ) +{ + while (width--) { + *argb++ = 0xFF000000 | (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; + + rgb += 3; + } +} + +static inline void +copy_line_nv16( u16 *yy, u16 *cbcr, const u8 *src_ycbcr, int width ) +{ + int x; + + for (x=0; x<width/2; x++) { +#ifdef WORDS_BIGENDIAN + yy[x] = (src_ycbcr[0] << 8) | src_ycbcr[3]; + + cbcr[x] = (((src_ycbcr[1] + src_ycbcr[4]) << 7) & 0xff00) | + ((src_ycbcr[2] + src_ycbcr[5]) >> 1); +#else + yy[x] = (src_ycbcr[3] << 8) | src_ycbcr[0]; + + cbcr[x] = (((src_ycbcr[2] + src_ycbcr[5]) << 7) & 0xff00) | + ((src_ycbcr[1] + src_ycbcr[4]) >> 1); +#endif + + src_ycbcr += 6; + } + + if (width & 1) { + u8 *y = (u8*) yy; + + y[width-1] = src_ycbcr[0]; + +#ifdef WORDS_BIGENDIAN + cbcr[x] = (src_ycbcr[1] << 8) | src_ycbcr[2]; +#else + cbcr[x] = (src_ycbcr[2] << 8) | src_ycbcr[1]; +#endif + } +} + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (ctx->header[0] == 0xff && ctx->header[1] == 0xd8) { + if (strncmp ((char*) ctx->header + 6, "JFIF", 4) == 0 || + strncmp ((char*) ctx->header + 6, "Exif", 4) == 0) + return DFB_OK; + + if (ctx->filename && strchr (ctx->filename, '.' ) && + (strcasecmp ( strchr (ctx->filename, '.' ), ".jpg" ) == 0 || + strcasecmp ( strchr (ctx->filename, '.' ), ".jpeg") == 0)) + return DFB_OK; + } + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_JPEG) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + data->ref = 1; + data->buffer = buffer; + data->core = core; + + buffer->AddRef( buffer ); + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = jpeglib_panic; + + if (setjmp(jerr.setjmp_buffer)) { + D_ERROR( "ImageProvider/JPEG: Error while reading headers!\n" ); + + jpeg_destroy_decompress(&cinfo); + buffer->Release( buffer ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + + jpeg_create_decompress(&cinfo); + jpeg_buffer_src(&cinfo, buffer, 1); + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + data->width = cinfo.output_width; + data->height = cinfo.output_height; + + jpeg_abort_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + thiz->AddRef = IDirectFBImageProvider_JPEG_AddRef; + thiz->Release = IDirectFBImageProvider_JPEG_Release; + thiz->RenderTo = IDirectFBImageProvider_JPEG_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_JPEG_SetRenderCallback; + thiz->GetImageDescription =IDirectFBImageProvider_JPEG_GetImageDescription; + thiz->GetSurfaceDescription = + IDirectFBImageProvider_JPEG_GetSurfaceDescription; + + return DFB_OK; +} + +static void +IDirectFBImageProvider_JPEG_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_JPEG_data *data = + (IDirectFBImageProvider_JPEG_data*)thiz->priv; + + data->buffer->Release( data->buffer ); + + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_JPEG_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_JPEG_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + if (--data->ref == 0) { + IDirectFBImageProvider_JPEG_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + bool direct = false; + DFBRegion clip; + DFBRectangle rect; + DFBSurfacePixelFormat format; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + CoreSurfaceBufferLock lock; + DIRenderCallbackResult cb_result = DIRCR_OK; + + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + dst_data = (IDirectFBSurface_data*) destination->priv; + if (!dst_data) + return DFB_DEAD; + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + ret = destination->GetPixelFormat( destination, &format ); + if (ret) + return ret; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + + if (!dfb_rectangle_region_intersects( &rect, &clip )) + return DFB_OK; + } + else { + rect = dst_data->area.wanted; + } + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + /* actual loading and rendering */ + if (!data->image) { + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + u32 *row_ptr; + int y = 0; + int uv_offset = 0; + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = jpeglib_panic; + + if (setjmp(jerr.setjmp_buffer)) { + D_ERROR( "ImageProvider/JPEG: Error during decoding!\n" ); + + jpeg_destroy_decompress(&cinfo); + + if (data->image) { + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + dfb_surface_unlock_buffer( dst_surface, &lock ); + if (data->render_callback) { + DFBRectangle r = { 0, 0, data->width, data->height }; + + if (data->render_callback( &r, data->render_callback_context ) != DIRCR_OK) + return DFB_INTERRUPTED; + } + + return DFB_INCOMPLETE; + } + else + dfb_surface_unlock_buffer( dst_surface, &lock ); + + return DFB_FAILURE; + } + + jpeg_create_decompress(&cinfo); + jpeg_buffer_src(&cinfo, data->buffer, 0); + jpeg_read_header(&cinfo, TRUE); + jpeg_calc_output_dimensions(&cinfo); + + if (cinfo.output_width == rect.w && cinfo.output_height == rect.h) + direct = true; + + cinfo.output_components = 3; + + switch (dst_surface->config.format) { + case DSPF_NV16: + uv_offset = dst_surface->config.size.h * lock.pitch; + + if (direct && !rect.x && !rect.y) { + D_INFO( "JPEG: Using YCbCr color space directly! (%dx%d)\n", + cinfo.output_width, cinfo.output_height ); + cinfo.out_color_space = JCS_YCbCr; + break; + } + D_INFO( "JPEG: Going through RGB color space! (%dx%d -> %dx%d @%d,%d)\n", + cinfo.output_width, cinfo.output_height, rect.w, rect.h, rect.x, rect.y ); + + default: + cinfo.out_color_space = JCS_RGB; + break; + } + + jpeg_start_decompress(&cinfo); + + data->width = cinfo.output_width; + data->height = cinfo.output_height; + + row_stride = cinfo.output_width * 3; + + buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, + JPOOL_IMAGE, row_stride, 1); + + data->image = D_CALLOC( data->height, data->width * 4 ); + if (!data->image) { + dfb_surface_unlock_buffer( dst_surface, &lock ); + return D_OOM(); + } + row_ptr = data->image; + + while (cinfo.output_scanline < cinfo.output_height && cb_result == DIRCR_OK) { + jpeg_read_scanlines(&cinfo, buffer, 1); + + switch (dst_surface->config.format) { + case DSPF_NV16: + if (direct) { + copy_line_nv16( lock.addr, lock.addr + uv_offset, *buffer, rect.w ); + + lock.addr += lock.pitch; + + if (data->render_callback) { + DFBRectangle r = { 0, y, data->width, 1 }; + + cb_result = data->render_callback( &r, + data->render_callback_context ); + } + break; + } + + default: + copy_line32( row_ptr, *buffer, data->width); + + if (direct) { + DFBRectangle r = { rect.x, rect.y+y, rect.w, 1 }; + dfb_copy_buffer_32( row_ptr, lock.addr, lock.pitch, + &r, dst_surface, &clip ); + if (data->render_callback) { + r = (DFBRectangle){ 0, y, data->width, 1 }; + cb_result = data->render_callback( &r, + data->render_callback_context ); + } + } + break; + } + + row_ptr += data->width; + y++; + } + + if (!direct) { + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + if (data->render_callback) { + DFBRectangle r = { 0, 0, data->width, data->height }; + cb_result = data->render_callback( &r, data->render_callback_context ); + } + } + + if (cb_result != DIRCR_OK) { + jpeg_abort_decompress(&cinfo); + D_FREE( data->image ); + data->image = NULL; + } + else { + jpeg_finish_decompress(&cinfo); + } + jpeg_destroy_decompress(&cinfo); + } + else { + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + if (data->render_callback) { + DFBRectangle r = { 0, 0, data->width, data->height }; + data->render_callback( &r, data->render_callback_context ); + } + } + + dfb_surface_unlock_buffer( dst_surface, &lock ); + + if (cb_result != DIRCR_OK) + return DFB_INTERRUPTED; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_JPEG) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->height = data->height; + dsc->width = data->width; + dsc->pixelformat = dfb_primary_layer_pixelformat(); + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + if (!dsc) + return DFB_INVARG; + + dsc->caps = DICAPS_NONE; + + return DFB_OK; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c new file mode 100755 index 0000000..3e7769d --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c @@ -0,0 +1,868 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <png.h> +#include <string.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbimageprovider.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/layers.h> +#include <core/palette.h> +#include <core/surface.h> + +#include <misc/gfx_util.h> +#include <misc/util.h> + +#include <gfx/clip.h> +#include <gfx/convert.h> + +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include "config.h" + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, PNG ) + + +enum { + STAGE_ABORT = -2, + STAGE_ERROR = -1, + STAGE_START = 0, + STAGE_INFO, + STAGE_IMAGE, + STAGE_END +}; + +/* + * private data struct of IDirectFBImageProvider_PNG + */ +typedef struct { + int ref; /* reference counter */ + IDirectFBDataBuffer *buffer; + + int stage; + int rows; + + png_structp png_ptr; + png_infop info_ptr; + + png_uint_32 width; + png_uint_32 height; + int bpp; + int color_type; + png_uint_32 color_key; + bool color_keyed; + + void *image; + int pitch; + u32 palette[256]; + DFBColor colors[256]; + + DIRenderCallback render_callback; + void *render_callback_context; + + CoreDFB *core; +} IDirectFBImageProvider_PNG_data; + +static DirectResult +IDirectFBImageProvider_PNG_AddRef ( IDirectFBImageProvider *thiz ); + +static DirectResult +IDirectFBImageProvider_PNG_Release ( IDirectFBImageProvider *thiz ); + +static DFBResult +IDirectFBImageProvider_PNG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *destination_rect ); + +static DFBResult +IDirectFBImageProvider_PNG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ); + +static DFBResult +IDirectFBImageProvider_PNG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ); + +static DFBResult +IDirectFBImageProvider_PNG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ); + +/* Called at the start of the progressive load, once we have image info */ +static void +png_info_callback (png_structp png_read_ptr, + png_infop png_info_ptr); + +/* Called for each row; note that you will get duplicate row numbers + for interlaced PNGs */ +static void +png_row_callback (png_structp png_read_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass_num); + +/* Called after reading the entire image */ +static void +png_end_callback (png_structp png_read_ptr, + png_infop png_info_ptr); + +/* Pipes data into libpng until stage is different from the one specified. */ +static DFBResult +push_data_until_stage (IDirectFBImageProvider_PNG_data *data, + int stage, + int buffer_size); + +/**********************************************************************************************************************/ + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (png_check_sig( ctx->header, 8 )) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + DFBResult ret = DFB_FAILURE; + + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_PNG) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + data->ref = 1; + data->buffer = buffer; + data->core = core; + + /* Increase the data buffer reference counter. */ + buffer->AddRef( buffer ); + + /* Create the PNG read handle. */ + data->png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL ); + if (!data->png_ptr) + goto error; + + if (setjmp( data->png_ptr->jmpbuf )) { + D_ERROR( "ImageProvider/PNG: Error reading header!\n" ); + goto error; + } + + /* Create the PNG info handle. */ + data->info_ptr = png_create_info_struct( data->png_ptr ); + if (!data->info_ptr) + goto error; + + /* Setup progressive image loading. */ + png_set_progressive_read_fn( data->png_ptr, data, + png_info_callback, + png_row_callback, + png_end_callback ); + + + /* Read until info callback is called. */ + ret = push_data_until_stage( data, STAGE_INFO, 64 ); + if (ret) + goto error; + + thiz->AddRef = IDirectFBImageProvider_PNG_AddRef; + thiz->Release = IDirectFBImageProvider_PNG_Release; + thiz->RenderTo = IDirectFBImageProvider_PNG_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_PNG_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_PNG_GetImageDescription; + thiz->GetSurfaceDescription = IDirectFBImageProvider_PNG_GetSurfaceDescription; + + return DFB_OK; + +error: + if (data->png_ptr) + png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL ); + + buffer->Release( buffer ); + + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE(thiz); + + return ret; +} + +/**********************************************************************************************************************/ + +static void +IDirectFBImageProvider_PNG_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_PNG_data *data = + (IDirectFBImageProvider_PNG_data*)thiz->priv; + + png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL ); + + /* Decrease the data buffer reference counter. */ + data->buffer->Release( data->buffer ); + + /* Deallocate image data. */ + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_PNG_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_PNG_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + if (--data->ref == 0) { + IDirectFBImageProvider_PNG_Destruct( thiz ); + } + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static DFBResult +IDirectFBImageProvider_PNG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret = DFB_OK; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + DFBRegion clip; + DFBRectangle rect; + png_infop info; + int x, y; + DFBRectangle clipped; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + info = data->info_ptr; + + dst_data = (IDirectFBSurface_data*) destination->priv; + if (!dst_data) + return DFB_DEAD; + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + else { + rect = dst_data->area.wanted; + } + + if (setjmp( data->png_ptr->jmpbuf )) { + D_ERROR( "ImageProvider/PNG: Error during decoding!\n" ); + + if (data->stage < STAGE_IMAGE) + return DFB_FAILURE; + + data->stage = STAGE_ERROR; + } + + /* Read until image is completely decoded. */ + if (data->stage != STAGE_ERROR) { + ret = push_data_until_stage( data, STAGE_END, 16384 ); + if (ret) + return ret; + } + + clipped = rect; + + if (!dfb_rectangle_intersect_by_region( &clipped, &clip )) + return DFB_INVAREA; + + /* actual rendering */ + if (rect.w == data->width && rect.h == data->height && + (data->color_type == PNG_COLOR_TYPE_RGB || data->color_type == PNG_COLOR_TYPE_RGBA) && + (dst_surface->config.format == DSPF_RGB32 || dst_surface->config.format == DSPF_ARGB)) + { + ret = dfb_surface_write_buffer( dst_surface, CSBR_BACK, + data->image + + (clipped.x - rect.x) * 4 + + (clipped.y - rect.y) * data->width * 4, + data->width * 4, &clipped ); + } + else { + CoreSurfaceBufferLock lock; + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + switch (data->color_type) { + case PNG_COLOR_TYPE_PALETTE: + if (dst_surface->config.format == DSPF_LUT8 && data->info_ptr->bit_depth == 8) { + /* + * Special indexed PNG to LUT8 loading. + */ + + /* FIXME: Limitation for LUT8 is to load complete surface only. */ + dfb_clip_rectangle( &clip, &rect ); + if (rect.x == 0 && rect.y == 0 && + rect.w == dst_surface->config.size.w && + rect.h == dst_surface->config.size.h && + rect.w == data->width && + rect.h == data->height) + { + for (y=0; y<data->height; y++) + direct_memcpy( lock.addr + lock.pitch * y, + data->image + data->pitch * y, + data->width ); + + break; + } + } + /* fall through */ + + case PNG_COLOR_TYPE_GRAY: { + /* + * Convert to ARGB and use generic loading code. + */ + + // FIXME: allocates four additional bytes because the scaling functions + // in src/misc/gfx_util.c have an off-by-one bug which causes + // segfaults on darwin/osx (not on linux) + int size = data->width * data->height * 4 + 4; + + /* allocate image data */ + void *image_argb = D_MALLOC( size ); + + if (!image_argb) { + D_ERROR( "DirectFB/ImageProvider_PNG: Could not " + "allocate %d bytes of system memory!\n", size ); + ret = DFB_NOSYSTEMMEMORY; + } + else { + if (data->color_type == PNG_COLOR_TYPE_GRAY) { + int num = 1 << data->info_ptr->bit_depth; + + for (x=0; x<num; x++) { + int value = x * 255 / (num - 1); + + data->palette[x] = 0xff000000 | (value << 16) | (value << 8) | value; + } + } + + switch (data->info_ptr->bit_depth) { + case 8: + for (y=0; y<data->height; y++) { + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) + D[x] = data->palette[ S[x] ]; + } + break; + + case 4: + for (y=0; y<data->height; y++) { + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) { + if (x & 1) + D[x] = data->palette[ S[x>>1] & 0xf ]; + else + D[x] = data->palette[ S[x>>1] >> 4 ]; + } + } + break; + + case 2: + for (y=0; y<data->height; y++) { + int n = 6; + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) { + D[x] = data->palette[ (S[x>>2] >> n) & 3 ]; + + n = (n ? n - 2 : 6); + } + } + break; + + case 1: + for (y=0; y<data->height; y++) { + int n = 7; + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) { + D[x] = data->palette[ (S[x>>3] >> n) & 1 ]; + + n = (n ? n - 1 : 7); + } + } + break; + + default: + D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n", + data->info_ptr->bit_depth ); + } + + dfb_scale_linear_32( image_argb, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + + D_FREE( image_argb ); + } + break; + } + default: + /* + * Generic loading code. + */ + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + break; + } + + dfb_surface_unlock_buffer( dst_surface, &lock ); + } + + if (data->stage != STAGE_END) + ret = DFB_INCOMPLETE; + + return ret; +} + +static DFBResult +IDirectFBImageProvider_PNG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_PNG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + DFBSurfacePixelFormat primary_format = dfb_primary_layer_pixelformat(); + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->width = data->width; + dsc->height = data->height; + + if (data->color_type & PNG_COLOR_MASK_ALPHA) + dsc->pixelformat = DFB_PIXELFORMAT_HAS_ALPHA(primary_format) ? primary_format : DSPF_ARGB; + else + dsc->pixelformat = primary_format; + + if (data->color_type == PNG_COLOR_TYPE_PALETTE) { + dsc->flags |= DSDESC_PALETTE; + + dsc->palette.entries = data->colors; /* FIXME */ + dsc->palette.size = 256; + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_PNG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_PNG) + + if (!dsc) + return DFB_INVARG; + + dsc->caps = DICAPS_NONE; + + if (data->color_type & PNG_COLOR_MASK_ALPHA) + dsc->caps |= DICAPS_ALPHACHANNEL; + + if (data->color_keyed) { + dsc->caps |= DICAPS_COLORKEY; + + dsc->colorkey_r = (data->color_key & 0xff0000) >> 16; + dsc->colorkey_g = (data->color_key & 0x00ff00) >> 8; + dsc->colorkey_b = (data->color_key & 0x0000ff); + } + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +#define MAXCOLORMAPSIZE 256 + +static int SortColors (const void *a, const void *b) +{ + return (*((const u8 *) a) - *((const u8 *) b)); +} + +/* looks for a color that is not in the colormap and ideally not + even close to the colors used in the colormap */ +static u32 FindColorKey( int n_colors, u8 *cmap ) +{ + u32 color = 0xFF000000; + u8 csort[n_colors]; + int i, j, index, d; + + if (n_colors < 1) + return color; + + for (i = 0; i < 3; i++) { + direct_memcpy( csort, cmap + (n_colors * i), n_colors ); + qsort( csort, n_colors, 1, SortColors ); + + for (j = 1, index = 0, d = 0; j < n_colors; j++) { + if (csort[j] - csort[j-1] > d) { + d = csort[j] - csort[j-1]; + index = j; + } + } + if ((csort[0] - 0x0) > d) { + d = csort[0] - 0x0; + index = n_colors; + } + if (0xFF - (csort[n_colors - 1]) > d) { + index = n_colors + 1; + } + + if (index < n_colors) + csort[0] = csort[index] - (d/2); + else if (index == n_colors) + csort[0] = 0x0; + else + csort[0] = 0xFF; + + color |= (csort[0] << (8 * (2 - i))); + } + + return color; +} + +/* Called at the start of the progressive load, once we have image info */ +static void +png_info_callback( png_structp png_read_ptr, + png_infop png_info_ptr ) +{ + int i; + IDirectFBImageProvider_PNG_data *data; + + data = png_get_progressive_ptr( png_read_ptr ); + + /* error stage? */ + if (data->stage < 0) + return; + + /* set info stage */ + data->stage = STAGE_INFO; + + png_get_IHDR( data->png_ptr, data->info_ptr, + &data->width, &data->height, &data->bpp, &data->color_type, + NULL, NULL, NULL ); + + if (png_get_valid( data->png_ptr, data->info_ptr, PNG_INFO_tRNS )) { + data->color_keyed = true; + + /* generate color key based on palette... */ + if (data->color_type == PNG_COLOR_TYPE_PALETTE) { + u32 key; + png_colorp palette = data->info_ptr->palette; + png_bytep trans = data->info_ptr->trans; + int num_colors = MIN( MAXCOLORMAPSIZE, + data->info_ptr->num_palette ); + u8 cmap[3][num_colors]; + + for (i=0; i<num_colors; i++) { + cmap[0][i] = palette[i].red; + cmap[1][i] = palette[i].green; + cmap[2][i] = palette[i].blue; + } + + key = FindColorKey( num_colors, &cmap[0][0] ); + + for (i=0; i<data->info_ptr->num_trans; i++) { + if (!trans[i]) { + palette[i].red = (key & 0xff0000) >> 16; + palette[i].green = (key & 0x00ff00) >> 8; + palette[i].blue = (key & 0x0000ff); + } + } + + data->color_key = key; + } + else { + /* ...or based on trans rgb value */ + png_color_16p trans = &data->info_ptr->trans_values; + + data->color_key = (((trans->red & 0xff00) << 8) | + ((trans->green & 0xff00)) | + ((trans->blue & 0xff00) >> 8)); + } + } + + switch (data->color_type) { + case PNG_COLOR_TYPE_PALETTE: { + png_colorp palette = data->info_ptr->palette; + png_bytep trans = data->info_ptr->trans; + int num_trans = data->info_ptr->num_trans; + int num_colors = MIN( MAXCOLORMAPSIZE, data->info_ptr->num_palette ); + + for (i=0; i<num_colors; i++) { + data->colors[i].a = (i < num_trans) ? trans[i] : 0xff; + data->colors[i].r = palette[i].red; + data->colors[i].g = palette[i].green; + data->colors[i].b = palette[i].blue; + + data->palette[i] = PIXEL_ARGB( data->colors[i].a, + data->colors[i].r, + data->colors[i].g, + data->colors[i].b ); + } + + data->pitch = (data->width + 7) & ~7; + break; + } + + case PNG_COLOR_TYPE_GRAY: + data->pitch = data->width; + + if (data->bpp == 16) + png_set_strip_16( data->png_ptr ); + + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_set_gray_to_rgb( data->png_ptr ); + /* fall through */ + + default: + data->pitch = data->width * 4; + + if (data->bpp == 16) + png_set_strip_16( data->png_ptr ); + +#ifdef WORDS_BIGENDIAN + if (!(data->color_type & PNG_COLOR_MASK_ALPHA)) + png_set_filler( data->png_ptr, 0xFF, PNG_FILLER_BEFORE ); + + png_set_swap_alpha( data->png_ptr ); +#else + if (!(data->color_type & PNG_COLOR_MASK_ALPHA)) + png_set_filler( data->png_ptr, 0xFF, PNG_FILLER_AFTER ); + + png_set_bgr( data->png_ptr ); +#endif + break; + } + + png_set_interlace_handling( data->png_ptr ); + + /* Update the info to reflect our transformations */ + png_read_update_info( data->png_ptr, data->info_ptr ); +} + +/* Called for each row; note that you will get duplicate row numbers + for interlaced PNGs */ +static void +png_row_callback( png_structp png_read_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass_num ) +{ + IDirectFBImageProvider_PNG_data *data; + + data = png_get_progressive_ptr( png_read_ptr ); + + /* error stage? */ + if (data->stage < 0) + return; + + /* set image decoding stage */ + data->stage = STAGE_IMAGE; + + /* check image data pointer */ + if (!data->image) { + // FIXME: allocates four additional bytes because the scaling functions + // in src/misc/gfx_util.c have an off-by-one bug which causes + // segfaults on darwin/osx (not on linux) + int size = data->pitch * data->height + 4; + + /* allocate image data */ + data->image = D_CALLOC( 1, size ); + if (!data->image) { + D_ERROR("DirectFB/ImageProvider_PNG: Could not " + "allocate %d bytes of system memory!\n", size); + + /* set error stage */ + data->stage = STAGE_ERROR; + + return; + } + } + + /* write to image data */ + png_progressive_combine_row( data->png_ptr, (png_bytep) (data->image + + row_num * data->pitch), new_row ); + + /* increase row counter, FIXME: interlaced? */ + data->rows++; + + if (data->render_callback) { + DIRenderCallbackResult r; + DFBRectangle rect = { 0, row_num, data->width, 1 }; + + r = data->render_callback( &rect, data->render_callback_context ); + if (r != DIRCR_OK) + data->stage = STAGE_ABORT; + } +} + +/* Called after reading the entire image */ +static void +png_end_callback (png_structp png_read_ptr, + png_infop png_info_ptr) +{ + IDirectFBImageProvider_PNG_data *data; + + data = png_get_progressive_ptr( png_read_ptr ); + + /* error stage? */ + if (data->stage < 0) + return; + + /* set end stage */ + data->stage = STAGE_END; +} + +/* Pipes data into libpng until stage is different from the one specified. */ +static DFBResult +push_data_until_stage (IDirectFBImageProvider_PNG_data *data, + int stage, + int buffer_size) +{ + DFBResult ret; + IDirectFBDataBuffer *buffer = data->buffer; + + while (data->stage < stage) { + unsigned int len; + unsigned char buf[buffer_size]; + + if (data->stage < 0) + return DFB_FAILURE; + + while (buffer->HasData( buffer ) == DFB_OK) { + D_DEBUG( "ImageProvider/PNG: Retrieving data (up to %d bytes)...\n", buffer_size ); + + ret = buffer->GetData( buffer, buffer_size, buf, &len ); + if (ret) + return ret; + + D_DEBUG( "ImageProvider/PNG: Got %d bytes...\n", len ); + + png_process_data( data->png_ptr, data->info_ptr, buf, len ); + + D_DEBUG( "ImageProvider/PNG: ...processed %d bytes.\n", len ); + + /* are we there yet? */ + if (data->stage < 0 || data->stage >= stage) { + switch (data->stage) { + case STAGE_ABORT: return DFB_INTERRUPTED; + case STAGE_ERROR: return DFB_FAILURE; + default: return DFB_OK; + } + } + } + + D_DEBUG( "ImageProvider/PNG: Waiting for data...\n" ); + + if (buffer->WaitForData( buffer, 1 ) == DFB_EOF) + return DFB_FAILURE; + } + + return DFB_OK; +} |