forked from enlightenment/efl
Merge evas generic loaders and emotion generic players
We decided to merge these into the efl. They are now part of the repo and build as port of the normal makefiles. History is fully retained.
This commit is contained in:
commit
92cfd074aa
40
AUTHORS
40
AUTHORS
|
@ -149,6 +149,25 @@ Michelle Legrand <legrand.michelle@outlook.com>
|
|||
Romain Perier <romain.perier@openwide.fr>
|
||||
Subodh Kumar <s7158.kumar@samsung.com>
|
||||
|
||||
Evas Generic Loaders
|
||||
--------------------
|
||||
|
||||
The Rasterman (Carsten Haitzler) <raster@rasterman.com>
|
||||
Christian Kreibich <cK@whoop.org>
|
||||
Vincent Torri <vtorri at univ-evry dot fr>
|
||||
Michael Bouchaud <michael.bouchaud@gmail.com>
|
||||
Fanina "cippp" Cristian <fancris3@gmail.com>
|
||||
Cedric BAIL <cedric.bail@free.fr>
|
||||
Jérémy Zurcher <jeremy@asynk.ch>
|
||||
Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
Daniel Juyung Seo <seojuyung2@gmail.com>
|
||||
Doug Newgard <scimmia22@outlook.com>
|
||||
Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
|
||||
Alex-P. Natsios <drakevr@linuxteam.teilar.gr>
|
||||
Jihoon Kim <imfine98@gmail.com>
|
||||
Samuel F. Baggen <thanatermesis.elive@gmail.com>
|
||||
Sebastian Dransfeld <sd@tango.flipp.net>
|
||||
|
||||
Ecore
|
||||
-----
|
||||
|
||||
|
@ -344,6 +363,27 @@ Leandro Dorileo <dorileo@profusion.mobi>
|
|||
Michael Bouchaud (yoz) <yoz@efl.so>
|
||||
Aymeric Dumaz <aymeric.dumaz@gmail.com>
|
||||
|
||||
Emotion Generic VLC
|
||||
---
|
||||
Cedric Bail <cedric.bail@free.fr>
|
||||
Hugo Camboulive <hugo.camboulive@zodiacaerospace.com>
|
||||
Leandro Dorileo <dorileo@profusion.mobi>
|
||||
Pierre Le Magourou <pierre.lemagourou@openwide.fr>
|
||||
Rafael Antognolli <antognolli@profusion.mobi>
|
||||
Sohyun Kim <anna1014.kim@samsung.com>
|
||||
Carsten Haitzler (Rasterman) <raster@rasterman.com>
|
||||
Davide Andreoli <dave@gurumeditation.it>
|
||||
Gustavo Sverzut Barbieri <barbieri@gmail.com>
|
||||
Stefan Schmidt <s.schmidt@samsung.com>
|
||||
Bruno Dilly <bdilly@profusion.mobi>
|
||||
ChunEon Park <hermet@hermet.pe.kr>
|
||||
Daniel Juyung Seo <juyung.seo@samsung.com>
|
||||
Doug Newgard <scimmia22@outlook.com>
|
||||
Jerome Pinot <ngc891@gmail.com>
|
||||
Mike Blumenkrantz <zmike@samsung.com>
|
||||
Sebastian Dransfeld <sd@tango.flipp.net>
|
||||
Vincent Torri <vincent.torri@gmail.com>
|
||||
|
||||
Ethumb
|
||||
------
|
||||
Rafael Antognolli <antognolli@profusion.mobi>
|
||||
|
|
2
COPYING
2
COPYING
|
@ -34,6 +34,8 @@ ethumb: licenses/COPYING.LGPL
|
|||
eolian: licenses/COPYING.BSD
|
||||
elua: licenses/COPYING.BSD
|
||||
elementary: licenses/COPYING.LGPL
|
||||
generic/evas: licenses/COPYING.GPL (separate binary/executable)
|
||||
generic/emotion: licenses/COPYING.GPL (separate binary/executable)
|
||||
|
||||
NOTE: If linked together, the result will be effectively be LGPL (or
|
||||
GPL if escape is used) due to license characteristics.
|
||||
|
|
98
configure.ac
98
configure.ac
|
@ -2807,6 +2807,99 @@ EFL_ADD_FEATURE([EVAS], [tile-rotate])
|
|||
EFL_ADD_FEATURE([EVAS], [dither-mask], [${build_evas_dither_mask}])
|
||||
EFL_ADD_FEATURE([EVAS], [hyphen])
|
||||
|
||||
#### Generic backend
|
||||
|
||||
### Option to turn on generic loader for evas
|
||||
want_poppler="no"
|
||||
want_spectre="no"
|
||||
want_libraw="no"
|
||||
want_rsvg="no"
|
||||
|
||||
AC_ARG_ENABLE([poppler],
|
||||
[AC_HELP_STRING([--enable-poppler], [enable poppler support @<:@default==disabled@:>@])],
|
||||
[want_poppler=$enableval])
|
||||
|
||||
AC_ARG_ENABLE([spectre],
|
||||
[AC_HELP_STRING([--enable-spectre], [enable spectre support @<:@default==disabled@:>@])],
|
||||
[want_spectre=$enableval])
|
||||
|
||||
AC_ARG_ENABLE([libraw],
|
||||
[AC_HELP_STRING([--enable-libraw], [enable libraw support @<:@default==disabled@:>@])],
|
||||
[want_libraw=$enableval])
|
||||
|
||||
AC_ARG_ENABLE([librsvg],
|
||||
[AC_HELP_STRING([--enable-librsvg], [enable svg support @<:@default==disabled@:>@])],
|
||||
[want_rsvg=$enableval])
|
||||
|
||||
have_poppler="no"
|
||||
have_spectre="no"
|
||||
have_raw="no"
|
||||
have_rsvg="no"
|
||||
|
||||
### Check needed dependency for each generic loader
|
||||
if test "x${want_poppler}" = "xyes"; then
|
||||
PKG_CHECK_EXISTS([poppler >= 0.12 poppler < 0.20],
|
||||
[
|
||||
poppler_pc="poppler >= 0.12 poppler < 0.20"
|
||||
have_poppler="yes"
|
||||
],
|
||||
[have_poppler="no"])
|
||||
|
||||
if test "x${have_poppler}" = "xno" ; then
|
||||
PKG_CHECK_EXISTS([poppler >= 0.20 poppler < 0.31],
|
||||
[
|
||||
poppler_pc="poppler >= 0.20 poppler < 0.31"
|
||||
AC_DEFINE(HAVE_POPPLER_020, 1, [Have poppler 0.20])
|
||||
have_poppler="yes"
|
||||
],
|
||||
[have_poppler="no"])
|
||||
fi
|
||||
|
||||
if test "x${have_poppler}" = "xno" ; then
|
||||
PKG_CHECK_EXISTS([poppler >= 0.31],
|
||||
[
|
||||
poppler_pc="poppler >= 0.31"
|
||||
AC_DEFINE(HAVE_POPPLER_031, 1, [Have poppler 0.31])
|
||||
have_poppler="yes"
|
||||
],
|
||||
[have_poppler="no"])
|
||||
fi
|
||||
|
||||
if test "x${have_poppler}" = "xyes" ; then
|
||||
PKG_CHECK_MODULES([POPPLER], [${poppler_pc}],
|
||||
[have_poppler="yes"])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x${want_spectre}" = "xyes"; then
|
||||
PKG_CHECK_MODULES([SPECTRE], [libspectre], [have_spectre="yes"])
|
||||
fi
|
||||
|
||||
if test "x${want_libraw}" = "xyes"; then
|
||||
PKG_CHECK_MODULES([LIBRAW], [libraw], [have_raw="yes"])
|
||||
fi
|
||||
|
||||
if test "x${want_librsvg}" = "xyes"; then
|
||||
PKG_CHECK_MODULES([RSVG], [librsvg-2.0 >= 2.14.0 cairo >= 1.0.0], [have_rsvg="yes"])
|
||||
PKG_CHECK_MODULES(
|
||||
[SVG_2_36], [librsvg-2.0 >= 2.36.0 cairo >= 1.0.0],
|
||||
[
|
||||
have_rsvg_2_36="yes"
|
||||
AC_DEFINE(HAVE_SVG_2_36, 1, [Have librsvg >= 2.36])
|
||||
],
|
||||
[have_rsvg_2_36="no"])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([HAVE_POPPLER], [test "x${have_poppler}" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_SPECTRE], [test "x${have_spectre}" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_LIBRAW], [test "x${have_raw}" = "xyes"])
|
||||
AM_CONDITIONAL([HAVE_RSVG], [test "x${have_rsvg}" = "xyes"])
|
||||
|
||||
EFL_ADD_FEATURE([EVAS_LOADER], [poppler], [${want_poppler}])
|
||||
EFL_ADD_FEATURE([EVAS_LOADER], [spectre], [${want_spectre}])
|
||||
EFL_ADD_FEATURE([EVAS_LOADER], [raw], [${want_libraw}])
|
||||
EFL_ADD_FEATURE([EVAS_LOADER], [rsvg], [${want_rsvg}])
|
||||
|
||||
EFL_LIB_END([Evas])
|
||||
#### End of Evas
|
||||
|
||||
|
@ -4902,10 +4995,13 @@ fi
|
|||
|
||||
### Check availability
|
||||
|
||||
## Generic player
|
||||
EMOTION_GENERIC_PLAYER([GENERIC_VLC], [yes], [libvlc >= 2.0 eina >= 1.1.99 ecore >= 1.7.99])
|
||||
EFL_ADD_FEATURE([EMOTION], [generic_vlc], [${with_generic_vlc}])
|
||||
|
||||
EFL_LIB_END([Emotion])
|
||||
#### End of Emotion
|
||||
|
||||
|
||||
#### Ethumb
|
||||
EFL_LIB_START([Ethumb])
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
dnl EMOTION_GENERIC_PLAYER(NAME, DEFAULT_STATE, [PKG_CONFIG_DEPS])
|
||||
dnl Does the following:
|
||||
dnl * AC_ARG_WITH(NAME)
|
||||
dnl * define with_name to yes or no
|
||||
dnl * PKG_CHECK_MODULES(NAME, PKG_CONFIG_DEPS)
|
||||
dnl * AC_DEFINE([HAVE_NAME])
|
||||
dnl * AM_CONDITIONAL([HAVE_NAME])
|
||||
AC_DEFUN([EMOTION_GENERIC_PLAYER],
|
||||
[dnl
|
||||
m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl
|
||||
m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl
|
||||
|
||||
AC_ARG_WITH([DOWN],
|
||||
[AC_HELP_STRING([--with-]m4_defn([DOWN]),
|
||||
[build generic player ]m4_defn([UP])[. @<:@default=$2@:>@])],
|
||||
[], [with_]m4_defn([DOWN])[="$2"])
|
||||
|
||||
if test "${with_[]m4_defn([DOWN])}" = "yes"; then
|
||||
m4_ifval([$3], [dnl
|
||||
PKG_CHECK_MODULES(m4_defn([UP]), [$3])
|
||||
], [dnl
|
||||
m4_defn([UP])_LIBS="${m4_defn([UP])_LIBS}"
|
||||
m4_defn([UP])_CFLAGS="${m4_defn([UP])_CFLAGS}"
|
||||
AC_SUBST(m4_defn([UP])[_LIBS])
|
||||
AC_SUBST(m4_defn([UP])[_CFLAGS])
|
||||
])
|
||||
|
||||
AC_SEARCH_LIBS([shm_open], [rt], [], [AC_MSG_ERROR([unable to find the shm_open() function])])
|
||||
if test "${ac_cv_search_shm_open}" != "none required"; then
|
||||
m4_defn([UP])_LIBS="${m4_defn([UP])_LIBS} ${ac_cv_search_shm_open}"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_]m4_defn([UP]), [test "$with_[]m4_defn([DOWN])" = "yes"])
|
||||
|
||||
m4_popdef([UP])dnl
|
||||
m4_popdef([DOWN])dnl
|
||||
])
|
|
@ -354,3 +354,24 @@ CLEANFILES += $(generated_emotion_js_bindings)
|
|||
GENERATED_JS_BINDINGS += $(generated_emotion_js_bindings)
|
||||
|
||||
endif
|
||||
|
||||
emotiongenericplayersdir = \
|
||||
$(libdir)/emotion/generic_players/$(MODULE_ARCH)
|
||||
|
||||
emotiongenericplayers_PROGRAMS =
|
||||
|
||||
if HAVE_GENERIC_VLC
|
||||
|
||||
emotiongenericplayers_PROGRAMS += generic/emotion/vlc/vlc
|
||||
generic_emotion_vlc_vlc_SOURCES = generic/emotion/vlc/emotion_generic_vlc.c
|
||||
generic_emotion_vlc_vlc_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/modules/emotion/generic \
|
||||
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
|
||||
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
|
||||
-DPACKAGE_DATA_DIR=\"$(datadir)/emotion\" \
|
||||
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)\" \
|
||||
-DEMOTION_GENERIC_PLAYERS_DIR=\"$(libdir)/emotion/generic_players/$(MODULE_ARCH)\" \
|
||||
@GENERIC_VLC_CFLAGS@
|
||||
generic_emotion_vlc_vlc_LDADD = @GENERIC_VLC_LIBS@
|
||||
|
||||
endif
|
||||
|
|
|
@ -2377,3 +2377,156 @@ if HAVE_CXX11
|
|||
evas_eolian_cxx_hh = $(evas_eolian_pub_files:%.eo=%.eo.hh)
|
||||
evas_eolian_cxx_impl = $(evas_eolian_pub_files:%.eo=%.eo.impl.hh)
|
||||
endif
|
||||
|
||||
EXTRA_DIST += \
|
||||
generic/evas/common/shmfile.c \
|
||||
generic/evas/common/shmfile.h \
|
||||
generic/evas/common/timeout.c \
|
||||
generic/evas/common/timeout.h
|
||||
|
||||
evasgenericloadersdir = \
|
||||
$(libdir)/evas/utils
|
||||
|
||||
evasgenericloaders_PROGRAMS =
|
||||
evasgenericloaders_SCRIPT =
|
||||
|
||||
### Libreoffice converter to pdf
|
||||
EXTRA_DIST += generic/evas/pdf/evas_generic_pdf_loader.libreoffice
|
||||
|
||||
if HAVE_POPPLER
|
||||
|
||||
evasgenericloaders_SCRIPT += generic/evas/pdf/evas_generic_pdf_loader.libreoffice
|
||||
evasgenericloaders_PROGRAMS += generic/evas/pdf/evas_image_loader.pdf
|
||||
|
||||
generic_evas_pdf_evas_image_loader_pdf_SOURCES = \
|
||||
generic/evas/pdf/main.cpp \
|
||||
generic/evas/common/shmfile.c \
|
||||
generic/evas/common/timeout.c
|
||||
generic_evas_pdf_evas_image_loader_pdf_CFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/generic/evas/common \
|
||||
@POPPLER_CFLAGS@
|
||||
generic_evas_pdf_evas_image_loader_pdf_CXXFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/generic/evas/common \
|
||||
@POPPLER_CFLAGS@
|
||||
generic_evas_pdf_evas_image_loader_pdf_LDADD = @POPPLER_LIBS@ @USE_EINA_INTERNAL_LIBS@ @SHM_LIBS@
|
||||
|
||||
EFL_INSTALL_EXEC_HOOK += \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ppt; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.pptx; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.odp; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xls; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xlsx; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ods; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.doc; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.docx; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.odt; \
|
||||
ln -sf evas_image_loader.pdf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rtf; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.ppt; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.pptx; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.odp; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.xls; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.xlsx; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.ods; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.doc; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.docx; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.odt; \
|
||||
ln -sf evas_generic_pdf_loader.libreoffice $(DESTDIR)$(libdir)/evas/utils/evas_generic_pdf_loader.rtf;
|
||||
|
||||
endif
|
||||
|
||||
if HAVE_SPECTRE
|
||||
|
||||
evasgenericloaders_PROGRAMS += generic/evas/ps/evas_image_loader.ps
|
||||
|
||||
generic_evas_ps_evas_image_loader_ps_SOURCES = \
|
||||
generic/evas/ps/main.c \
|
||||
generic/evas/common/shmfile.c \
|
||||
generic/evas/common/timeout.c
|
||||
generic_evas_ps_evas_image_loader_ps_LDADD = @SPECTRE_LIBS@ @USE_EINA_INTERNAL_LIBS@ @SHM_LIBS@
|
||||
generic_evas_ps_evas_image_loader_ps_CFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/generic/evas/common
|
||||
|
||||
endif
|
||||
|
||||
if HAVE_LIBRAW
|
||||
|
||||
evasgenericloaders_PROGRAMS += generic/evas/raw/evas_image_loader.raw
|
||||
|
||||
generic_evas_raw_evas_image_loader_raw_SOURCES = \
|
||||
generic/evas/raw/main.c \
|
||||
generic/evas/common/shmfile.c \
|
||||
generic/evas/common/timeout.c
|
||||
generic_evas_raw_evas_image_loader_raw_LDADD = @SHM_LIBS@ @USE_EINA_INTERNAL_LIBS@ @LIBRAW_LIBS@ -lm
|
||||
generic_evas_raw_evas_image_loader_raw_CFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/generic/evas/common \
|
||||
@LIBRAW_CFLAGS@
|
||||
|
||||
EFL_INSTALL_EXEC_HOOK += \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.arw; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.cr2; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.crw; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.dcr; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.dng; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.k25; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.kdc; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.erf; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mrw; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nef; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nrf; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nrw; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.orf; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rw2; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.pef; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.raf; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.sr2; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.srf; \
|
||||
ln -sf evas_image_loader.raw $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.x3f;
|
||||
|
||||
endif
|
||||
|
||||
if HAVE_RSVG
|
||||
|
||||
evasgenericloaders_PROGRAMS += generic/evas/svg/evas_image_loader.svg
|
||||
|
||||
generic_evas_svg_evas_image_loader_svg_SOURCES = \
|
||||
generic/evas/svg/main.c \
|
||||
generic/evas/common/shmfile.c \
|
||||
generic/evas/common/timeout.c
|
||||
generic_evas_svg_evas_image_loader_svg_CFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/generic/evas/common \
|
||||
@RSVG_CFLAGS@
|
||||
generic_evas_svg_evas_image_loader_svg_LDADD = @RSVG_LIBS@ @USE_EINA_INTERNAL_LIBS@ @SHM_LIBS@ -lm
|
||||
|
||||
EFL_INSTALL_EXEC_HOOK += \
|
||||
ln -sf evas_image_loader.svg $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.svgz; \
|
||||
ln -sf evas_image_loader.svg $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.svg.gz;
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST += generic/evas/xcf/common.h
|
||||
|
||||
evasgenericloaders_PROGRAMS += generic/evas/xcf/evas_image_loader.xcf
|
||||
|
||||
generic_evas_xcf_evas_image_loader_xcf_SOURCES = \
|
||||
generic/evas/xcf/main.c \
|
||||
generic/evas/xcf/pixelfuncs.c \
|
||||
generic/evas/common/shmfile.c \
|
||||
generic/evas/common/timeout.c
|
||||
generic_evas_xcf_evas_image_loader_xcf_CFLAGS = \
|
||||
-I$(top_srcdir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/generic/evas/common
|
||||
generic_evas_xcf_evas_image_loader_xcf_LDADD = @USE_EINA_INTERNAL_LIBS@ @SHM_LIBS@ -lm -lz
|
||||
|
||||
EFL_INSTALL_EXEC_HOOK += \
|
||||
ln -sf evas_image_loader.xcf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xcf.gz;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/emotion/vlc/vlc
|
||||
/evas/pdf/evas_image_loader.pdf
|
||||
/evas/ps/evas_image_loader.ps
|
||||
/evas/raw/evas_image_loader.raw
|
||||
/evas/xcf/evas_image_loader.xcf
|
|
@ -0,0 +1,790 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <vlc/vlc.h>
|
||||
|
||||
#include <Emotion_Generic_Plugin.h>
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
static int _em_vlc_log_dom = -1;
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_em_vlc_log_dom, __VA_ARGS__)
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_em_vlc_log_dom, __VA_ARGS__)
|
||||
#define INF(...) EINA_LOG_DOM_INFO(_em_vlc_log_dom, __VA_ARGS__)
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_em_vlc_log_dom, __VA_ARGS__)
|
||||
#define CRIT(...) EINA_LOG_DOM_CRIT(_em_vlc_log_dom, __VA_ARGS__)
|
||||
|
||||
|
||||
typedef struct _App App;
|
||||
struct _App {
|
||||
Emotion_Generic_Video_Shared *vs;
|
||||
Emotion_Generic_Video_Frame vf;
|
||||
|
||||
libvlc_instance_t *libvlc;
|
||||
libvlc_media_t *m;
|
||||
libvlc_media_player_t *mp;
|
||||
libvlc_event_manager_t *event_mgr;
|
||||
|
||||
Ecore_Pipe *fd_read; // read commands from emotion here
|
||||
Ecore_Pipe *fd_write; // write commands for emotion here
|
||||
Eina_Lock cmd_mutex;// lock used to send just one command at a time
|
||||
int last_order; // current command received from emotion
|
||||
|
||||
char *filename;
|
||||
char *subtitle_path;
|
||||
char *shmname;
|
||||
unsigned w, h;
|
||||
int volume;
|
||||
Eina_Bool audio_muted;
|
||||
|
||||
Eina_Bool opening;
|
||||
Eina_Bool closing;
|
||||
Eina_Bool playing;
|
||||
Eina_Bool inited;
|
||||
};
|
||||
|
||||
static void _player_setup(App *app);
|
||||
|
||||
|
||||
/* Utilities to send commands back to emotion */
|
||||
#define SEND_CMD_PARAM(app, i) \
|
||||
if ((app)->fd_write) \
|
||||
if (!ecore_pipe_write((app)->fd_write, &(i), sizeof((i)))) \
|
||||
ecore_main_loop_quit();
|
||||
|
||||
static void
|
||||
_send_cmd(App *app, int cmd)
|
||||
{
|
||||
if (!app->fd_write)
|
||||
return;
|
||||
|
||||
eina_lock_take(&app->cmd_mutex); /* LOCK HERE */
|
||||
|
||||
if (!ecore_pipe_write(app->fd_write, &cmd, sizeof(cmd)))
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
_send_cmd_str(App *app, const char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = str ? strlen(str) + 1 : 0;
|
||||
if (app->fd_write)
|
||||
if (!ecore_pipe_write(app->fd_write, &len, sizeof(len)))
|
||||
ecore_main_loop_quit();
|
||||
if (app->fd_write)
|
||||
if (!ecore_pipe_write(app->fd_write, str, len))
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
_send_cmd_finish(App *app)
|
||||
{
|
||||
eina_lock_release(&app->cmd_mutex); /* UNLOCK HERE */
|
||||
}
|
||||
|
||||
/* Commands sent to the emotion pipe */
|
||||
static void
|
||||
_send_file_closed(App *app)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_FILE_CLOSE);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_time_changed(App *app)
|
||||
{
|
||||
float new_time;
|
||||
|
||||
if (app->vs->frame_drop > 1)
|
||||
return;
|
||||
|
||||
new_time = libvlc_media_player_get_time(app->mp);
|
||||
new_time /= 1000;
|
||||
_send_cmd(app, EM_RESULT_POSITION_CHANGED);
|
||||
SEND_CMD_PARAM(app, new_time);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_resize(App *app, int width, int height)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_FRAME_SIZE);
|
||||
SEND_CMD_PARAM(app, width);
|
||||
SEND_CMD_PARAM(app, height);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_track_info(App *app, int cmd, int current, int count, libvlc_track_description_t *desc)
|
||||
{
|
||||
_send_cmd(app, cmd);
|
||||
SEND_CMD_PARAM(app, current);
|
||||
SEND_CMD_PARAM(app, count);
|
||||
while (desc)
|
||||
{
|
||||
int tid = desc->i_id;
|
||||
const char *name = desc->psz_name;
|
||||
SEND_CMD_PARAM(app, tid);
|
||||
_send_cmd_str(app, name);
|
||||
desc = desc->p_next;
|
||||
}
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_all_track_info(App *app)
|
||||
{
|
||||
int track_count, current;
|
||||
libvlc_track_description_t *desc;
|
||||
|
||||
current = libvlc_audio_get_track(app->mp);
|
||||
track_count = libvlc_audio_get_track_count(app->mp);
|
||||
desc = libvlc_audio_get_track_description(app->mp);
|
||||
|
||||
_send_track_info(app, EM_RESULT_AUDIO_TRACK_INFO,
|
||||
current, track_count, desc);
|
||||
|
||||
current = libvlc_video_get_track(app->mp);
|
||||
track_count = libvlc_video_get_track_count(app->mp);
|
||||
desc = libvlc_video_get_track_description(app->mp);
|
||||
|
||||
_send_track_info(app, EM_RESULT_VIDEO_TRACK_INFO,
|
||||
current, track_count, desc);
|
||||
|
||||
current = libvlc_video_get_spu(app->mp);
|
||||
track_count = libvlc_video_get_spu_count(app->mp);
|
||||
desc = libvlc_video_get_spu_description(app->mp);
|
||||
|
||||
_send_track_info(app, EM_RESULT_SPU_TRACK_INFO,
|
||||
current, track_count, desc);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_all_meta_info(App *app)
|
||||
{
|
||||
const char *meta;
|
||||
|
||||
_send_cmd(app, EM_RESULT_META_INFO);
|
||||
|
||||
/*
|
||||
* Will send in this order: title, artist, album, year,
|
||||
* genre, comments, disc id and track count.
|
||||
*/
|
||||
meta = libvlc_media_get_meta(app->m, libvlc_meta_Title);
|
||||
_send_cmd_str(app, meta);
|
||||
meta = libvlc_media_get_meta(app->m, libvlc_meta_Artist);
|
||||
_send_cmd_str(app, meta);
|
||||
meta = libvlc_media_get_meta(app->m, libvlc_meta_Album);
|
||||
_send_cmd_str(app, meta);
|
||||
meta = libvlc_media_get_meta(app->m, libvlc_meta_Date);
|
||||
_send_cmd_str(app, meta);
|
||||
meta = libvlc_media_get_meta(app->m, libvlc_meta_Genre);
|
||||
_send_cmd_str(app, meta);
|
||||
meta = NULL; // sending empty comments
|
||||
_send_cmd_str(app, meta);
|
||||
meta = NULL; // sending empty disc id
|
||||
_send_cmd_str(app, meta);
|
||||
meta = libvlc_media_get_meta(app->m, libvlc_meta_TrackNumber);
|
||||
_send_cmd_str(app, meta);
|
||||
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_length_changed(App *app)
|
||||
{
|
||||
float length = libvlc_media_player_get_length(app->mp);
|
||||
|
||||
length /= 1000;
|
||||
_send_cmd(app, EM_RESULT_LENGTH_CHANGED);
|
||||
SEND_CMD_PARAM(app, length);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_seekable_changed(App *app, const struct libvlc_event_t *ev)
|
||||
{
|
||||
int seekable = ev->u.media_player_seekable_changed.new_seekable;
|
||||
|
||||
_send_cmd(app, EM_RESULT_SEEKABLE_CHANGED);
|
||||
SEND_CMD_PARAM(app, seekable);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_playback_started(App *app)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_PLAYBACK_STARTED);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_playback_stopped(App *app)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_PLAYBACK_STOPPED);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_init(App *app)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_INIT);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_file_set(App *app)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_FILE_SET);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_send_file_set_done(App *app, int success)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_FILE_SET_DONE);
|
||||
SEND_CMD_PARAM(app, success);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
|
||||
|
||||
/* VLC events and callbacks */
|
||||
static void
|
||||
_event_cb(const struct libvlc_event_t *ev, void *data)
|
||||
{
|
||||
App *app = data;
|
||||
|
||||
ecore_thread_main_loop_begin();
|
||||
switch (ev->type)
|
||||
{
|
||||
case libvlc_MediaPlayerTimeChanged:
|
||||
// DBG("libvlc_MediaPlayerTimeChanged");
|
||||
_send_time_changed(app);
|
||||
break;
|
||||
case libvlc_MediaPlayerLengthChanged:
|
||||
DBG("libvlc_MediaPlayerLengthChanged");
|
||||
_send_length_changed(app);
|
||||
break;
|
||||
case libvlc_MediaPlayerSeekableChanged:
|
||||
DBG("libvlc_MediaPlayerSeekableChanged");
|
||||
_send_seekable_changed(app, ev);
|
||||
break;
|
||||
case libvlc_MediaPlayerPlaying:
|
||||
DBG("libvlc_MediaPlayerPlaying");
|
||||
libvlc_audio_set_volume(app->mp, app->volume);
|
||||
libvlc_audio_set_mute(app->mp, app->audio_muted);
|
||||
_send_playback_started(app);
|
||||
break;
|
||||
case libvlc_MediaPlayerStopped:
|
||||
DBG("libvlc_MediaPlayerStopped");
|
||||
_send_playback_stopped(app);
|
||||
if (app->closing)
|
||||
{
|
||||
free(app->filename);
|
||||
app->filename = NULL;
|
||||
free(app->subtitle_path);
|
||||
app->subtitle_path = NULL;
|
||||
libvlc_media_release(app->m);
|
||||
app->m = NULL;
|
||||
libvlc_media_player_release(app->mp);
|
||||
app->mp = NULL;
|
||||
emotion_generic_shm_free(app->vs);
|
||||
app->playing = EINA_FALSE;
|
||||
app->closing = EINA_FALSE;
|
||||
_send_file_closed(app);
|
||||
}
|
||||
break;
|
||||
case libvlc_MediaPlayerEndReached:
|
||||
DBG("libvlc_MediaPlayerEndReached");
|
||||
app->playing = EINA_FALSE;
|
||||
/* vlc had released the media_playere here, we create a new one */
|
||||
app->mp = libvlc_media_player_new_from_media(app->m);
|
||||
_player_setup(app);
|
||||
_send_playback_stopped(app);
|
||||
break;
|
||||
}
|
||||
ecore_thread_main_loop_end();
|
||||
}
|
||||
|
||||
static void
|
||||
_tmp_playing_event_cb(const struct libvlc_event_t *ev, void *data)
|
||||
{
|
||||
App *app = data;
|
||||
|
||||
if (ev->type != libvlc_MediaPlayerPlaying)
|
||||
return;
|
||||
|
||||
/* pause and stop listening the temporary event */
|
||||
libvlc_event_detach(app->event_mgr,libvlc_MediaPlayerPlaying,
|
||||
_tmp_playing_event_cb, app);
|
||||
libvlc_media_player_set_pause(app->mp, 1);
|
||||
|
||||
/* sending size info */
|
||||
libvlc_video_get_size(app->mp, 0, &app->w, &app->h);
|
||||
_send_resize(app, app->w, app->h);
|
||||
|
||||
/* sending total lenght */
|
||||
_send_length_changed(app);
|
||||
|
||||
/* sending audio track info */
|
||||
_send_all_track_info(app);
|
||||
|
||||
/* sending meta info */
|
||||
_send_all_meta_info(app);
|
||||
|
||||
/* ok, we are done! Now let emotion create the shmem for us */
|
||||
_send_file_set(app);
|
||||
}
|
||||
|
||||
static void *
|
||||
_lock(void *data, void **pixels)
|
||||
{
|
||||
App *app = data;
|
||||
|
||||
if (app->playing)
|
||||
*pixels = app->vf.frames[app->vs->frame.player];
|
||||
else
|
||||
*pixels = NULL;
|
||||
|
||||
return NULL; // picture identifier, not needed here
|
||||
}
|
||||
|
||||
static void
|
||||
_unlock(void *data EINA_UNUSED, void *id EINA_UNUSED, void *const *pixels EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_display(void *data, void *id EINA_UNUSED)
|
||||
{
|
||||
App *app = data;
|
||||
|
||||
if (!app->playing)
|
||||
return;
|
||||
|
||||
eina_semaphore_lock(&app->vs->lock);
|
||||
app->vs->frame.last = app->vs->frame.player;
|
||||
app->vs->frame.player = app->vs->frame.next;
|
||||
app->vs->frame.next = app->vs->frame.last;
|
||||
if (!app->vs->frame_drop++)
|
||||
{
|
||||
_send_cmd(app, EM_RESULT_FRAME_NEW);
|
||||
_send_cmd_finish(app);
|
||||
}
|
||||
eina_semaphore_release(&app->vs->lock, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_player_setup(App *app)
|
||||
{
|
||||
|
||||
libvlc_video_set_format(app->mp, "RV32", app->w, app->h, app->w * 4);
|
||||
libvlc_video_set_callbacks(app->mp, _lock, _unlock, _display, app);
|
||||
|
||||
app->event_mgr = libvlc_media_player_event_manager(app->mp);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerPlaying,
|
||||
_event_cb, app);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerTimeChanged,
|
||||
_event_cb, app);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerLengthChanged,
|
||||
_event_cb, app);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerSeekableChanged,
|
||||
_event_cb, app);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerEndReached,
|
||||
_event_cb, app);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerStopped,
|
||||
_event_cb, app);
|
||||
}
|
||||
|
||||
/* Commands received from the emotion pipe */
|
||||
static void
|
||||
_file_set(App *app)
|
||||
{
|
||||
DBG("Path: %s", app->filename);
|
||||
app->m = libvlc_media_new_path(app->libvlc, app->filename);
|
||||
if (!app->m)
|
||||
{
|
||||
ERR("could not open path: \"%s\"", app->filename);
|
||||
return;
|
||||
}
|
||||
|
||||
app->mp = libvlc_media_player_new_from_media(app->m);
|
||||
if (!app->mp)
|
||||
{
|
||||
ERR("could not create new player from media.");
|
||||
return;
|
||||
}
|
||||
|
||||
app->opening = EINA_TRUE;
|
||||
|
||||
/* Here we start playing and connect a temporary callback to know when
|
||||
* the file is parsed and ready to be played for real.
|
||||
*/
|
||||
app->event_mgr = libvlc_media_player_event_manager(app->mp);
|
||||
libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerPlaying,
|
||||
_tmp_playing_event_cb, app);
|
||||
|
||||
libvlc_media_player_play(app->mp);
|
||||
}
|
||||
|
||||
static void
|
||||
_file_set_done(App *app)
|
||||
{
|
||||
int r;
|
||||
|
||||
DBG("Path: %s", app->filename);
|
||||
app->opening = EINA_FALSE;
|
||||
|
||||
r = emotion_generic_shm_get(app->shmname, &app->vs, &app->vf);
|
||||
if (!r)
|
||||
{
|
||||
free(app->filename);
|
||||
libvlc_media_release(app->m);
|
||||
libvlc_media_player_release(app->mp);
|
||||
app->filename = NULL;
|
||||
app->m = NULL;
|
||||
app->mp = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_player_setup(app);
|
||||
}
|
||||
|
||||
_send_file_set_done(app, r);
|
||||
}
|
||||
|
||||
static void
|
||||
_file_close(App *app)
|
||||
{
|
||||
DBG("closing file");
|
||||
|
||||
if (!app->mp)
|
||||
return;
|
||||
|
||||
app->closing = EINA_TRUE;
|
||||
libvlc_media_player_stop(app->mp);
|
||||
}
|
||||
|
||||
static void
|
||||
_stop(App *app)
|
||||
{
|
||||
DBG("Stop");
|
||||
if (app->mp)
|
||||
libvlc_media_player_set_pause(app->mp, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_play(App *app, float pos)
|
||||
{
|
||||
DBG("Play at %.3f", pos);
|
||||
|
||||
if (!app->mp)
|
||||
return;
|
||||
|
||||
if (app->playing)
|
||||
{
|
||||
libvlc_media_player_set_pause(app->mp, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
libvlc_time_t new_time = pos * 1000;
|
||||
libvlc_media_player_set_time(app->mp, new_time);
|
||||
libvlc_media_player_play(app->mp);
|
||||
|
||||
if (app->subtitle_path)
|
||||
libvlc_video_set_subtitle_file(app->mp, app->subtitle_path);
|
||||
|
||||
app->playing = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_position_set(App *app, float position)
|
||||
{
|
||||
libvlc_time_t new_time;
|
||||
|
||||
DBG("Position set %.3f", position);
|
||||
if (!app->mp)
|
||||
return;
|
||||
|
||||
new_time = position * 1000;
|
||||
libvlc_media_player_set_time(app->mp, new_time);
|
||||
|
||||
if (libvlc_media_player_get_state(app->mp) == libvlc_Paused)
|
||||
_send_time_changed(app);
|
||||
}
|
||||
|
||||
static void
|
||||
_speed_set(App *app, float rate)
|
||||
{
|
||||
DBG("Speed set %.3f", rate);
|
||||
if (!app->mp)
|
||||
return;
|
||||
|
||||
libvlc_media_player_set_rate(app->mp, rate);
|
||||
}
|
||||
|
||||
static void
|
||||
_mute_set(App *app, int mute)
|
||||
{
|
||||
DBG("Mute %d", mute);
|
||||
if (!app->mp)
|
||||
return;
|
||||
|
||||
app->audio_muted = mute;
|
||||
libvlc_audio_set_mute(app->mp, mute);
|
||||
}
|
||||
|
||||
static void
|
||||
_volume_set(App *app, float volume)
|
||||
{
|
||||
DBG("Volume set %.2f", volume);
|
||||
if (!app->mp)
|
||||
return;
|
||||
|
||||
app->volume = volume * 100;
|
||||
libvlc_audio_set_volume(app->mp, app->volume);
|
||||
}
|
||||
|
||||
static void
|
||||
_spu_track_set(App *app, int track)
|
||||
{
|
||||
DBG("SPU track %d", track);
|
||||
libvlc_video_set_spu(app->mp, track);
|
||||
}
|
||||
|
||||
static void
|
||||
_audio_track_set(App *app, int track)
|
||||
{
|
||||
DBG("Audio track %d", track);
|
||||
libvlc_audio_set_track(app->mp, track);
|
||||
}
|
||||
|
||||
static void
|
||||
_video_track_set(App *app, int track)
|
||||
{
|
||||
DBG("Video Track %d", track);
|
||||
libvlc_video_set_track(app->mp, track);
|
||||
}
|
||||
|
||||
static void
|
||||
_remote_command(void *data, void *buffer, unsigned int nbyte)
|
||||
{
|
||||
App *app = data;
|
||||
|
||||
if (nbyte == 0)
|
||||
{
|
||||
ecore_main_loop_quit();
|
||||
return ;
|
||||
}
|
||||
|
||||
if (app->last_order == EM_CMD_LAST)
|
||||
{
|
||||
if (nbyte != sizeof (int))
|
||||
{
|
||||
ERR("didn't receive a valid command from emotion (%i) !", nbyte);
|
||||
ecore_main_loop_quit();
|
||||
return ;
|
||||
}
|
||||
|
||||
app->last_order = *((int*) buffer);
|
||||
|
||||
if (!app->inited &&
|
||||
app->last_order != EM_CMD_INIT)
|
||||
{
|
||||
ERR("wrong init command!");
|
||||
ecore_main_loop_quit();
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (app->last_order)
|
||||
{
|
||||
case EM_CMD_FILE_SET:
|
||||
if (app->opening)
|
||||
{
|
||||
libvlc_media_release(app->m);
|
||||
libvlc_media_player_release(app->mp);
|
||||
free(app->filename);
|
||||
app->opening = EINA_FALSE;
|
||||
}
|
||||
break;
|
||||
case EM_CMD_FILE_SET_DONE:
|
||||
_file_set_done(app);
|
||||
app->last_order = EM_CMD_LAST;
|
||||
break;
|
||||
case EM_CMD_FILE_CLOSE:
|
||||
_file_close(app);
|
||||
app->last_order = EM_CMD_LAST;
|
||||
break;
|
||||
case EM_CMD_STOP:
|
||||
_stop(app);
|
||||
app->last_order = EM_CMD_LAST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (app->last_order)
|
||||
{
|
||||
case EM_CMD_INIT:
|
||||
app->shmname = strdup(buffer);
|
||||
app->inited = EINA_TRUE;
|
||||
_send_init(app);
|
||||
break;
|
||||
case EM_CMD_FILE_SET:
|
||||
app->filename = strdup(buffer);
|
||||
_file_set(app);
|
||||
break;
|
||||
case EM_CMD_SUBTITLE_SET:
|
||||
app->subtitle_path = strdup(buffer);
|
||||
break;
|
||||
case EM_CMD_PLAY:
|
||||
_play(app, *(float*) buffer);
|
||||
break;
|
||||
case EM_CMD_POSITION_SET:
|
||||
_position_set(app, *(float*) buffer);
|
||||
break;
|
||||
case EM_CMD_SPEED_SET:
|
||||
_speed_set(app, *(float*) buffer);
|
||||
break;
|
||||
case EM_CMD_AUDIO_MUTE_SET:
|
||||
_mute_set(app, *(int*) buffer);
|
||||
break;
|
||||
case EM_CMD_VOLUME_SET:
|
||||
_volume_set(app, *(float*) buffer);
|
||||
break;
|
||||
case EM_CMD_SPU_TRACK_SET:
|
||||
_spu_track_set(app, *(int*) buffer);
|
||||
break;
|
||||
case EM_CMD_AUDIO_TRACK_SET:
|
||||
_audio_track_set(app, *(int*) buffer);
|
||||
break;
|
||||
case EM_CMD_VIDEO_TRACK_SET:
|
||||
_video_track_set(app, *(int*) buffer);
|
||||
break;
|
||||
}
|
||||
app->last_order = EM_CMD_LAST;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_dummy(void *data EINA_UNUSED, void *buffer EINA_UNUSED, unsigned int nbyte EINA_UNUSED)
|
||||
{
|
||||
/* This function is useless for the pipe we use to send message back
|
||||
to emotion, but still needed */
|
||||
}
|
||||
|
||||
/* Main */
|
||||
static Eina_Bool
|
||||
exit_func(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
|
||||
{
|
||||
DBG("Quit signal received !");
|
||||
ecore_main_loop_quit();
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
App app;
|
||||
Ecore_Event_Handler *hld;
|
||||
int vlc_argc;
|
||||
|
||||
const char *vlc_argv[] =
|
||||
{
|
||||
"--quiet",
|
||||
"--intf", "dummy", /* no interface */
|
||||
"--vout", "dummy", /* we don't want video (output) */
|
||||
"--no-video-title-show", /* nor the filename displayed */
|
||||
"--no-sub-autodetect-file", /* we don't want automatic subtitles */
|
||||
"--no-stats", /* no stats */
|
||||
"--no-inhibit", /* we don't want interfaces */
|
||||
"--no-disable-screensaver", /* we don't want interfaces */
|
||||
// XXX: causes newer vlcs to segv!
|
||||
// "--codec", "avcodec",
|
||||
// XXX: disable this just in case
|
||||
// "--demux", "avformat"
|
||||
};
|
||||
vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
|
||||
|
||||
memset(&app, 0, sizeof(app));
|
||||
if (!eina_init())
|
||||
{
|
||||
EINA_LOG_CRIT("Can't initialize generic vlc player, eina failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
_em_vlc_log_dom = eina_log_domain_register("emotion_generic_vlc",
|
||||
EINA_COLOR_CYAN);
|
||||
if (_em_vlc_log_dom < 0)
|
||||
{
|
||||
EINA_LOG_CRIT("Unable to register emotion_generic_vlc log domain.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!eina_log_domain_level_check(_em_vlc_log_dom, EINA_LOG_LEVEL_WARN))
|
||||
eina_log_domain_level_set("emotion_generic_vlc", EINA_LOG_LEVEL_WARN);
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
ERR("missing parameters.");
|
||||
ERR("syntax:\n\t%s <fd read> <fd write>", argv[0]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ecore_init();
|
||||
|
||||
eina_lock_new(&app.cmd_mutex);
|
||||
|
||||
app.fd_read = ecore_pipe_full_add(_remote_command, &app,
|
||||
atoi(argv[1]), -1, EINA_FALSE, EINA_FALSE);
|
||||
app.fd_write = ecore_pipe_full_add(_dummy, NULL,
|
||||
-1, atoi(argv[2]), EINA_FALSE, EINA_FALSE);
|
||||
|
||||
hld = ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP, exit_func, NULL);
|
||||
|
||||
app.libvlc = libvlc_new(vlc_argc, vlc_argv);
|
||||
app.mp = NULL;
|
||||
app.filename = NULL;
|
||||
app.subtitle_path = NULL;
|
||||
app.w = 0;
|
||||
app.h = 0;
|
||||
app.opening = EINA_FALSE;
|
||||
app.playing = EINA_FALSE;
|
||||
app.inited = EINA_FALSE;
|
||||
app.last_order = EM_CMD_LAST;
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
libvlc_release(app.libvlc);
|
||||
ecore_pipe_del(app.fd_read);
|
||||
ecore_pipe_del(app.fd_write);
|
||||
ecore_event_handler_del(hld);
|
||||
eina_lock_free(&app.cmd_mutex);
|
||||
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
eina_shutdown();
|
||||
return -1;
|
||||
}
|
||||
#undef SEND_CMD_PARAM
|
|
@ -0,0 +1,87 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <netinet/in.h>
|
||||
#include <time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int shm_fd = -1;
|
||||
static int shm_size = 0;
|
||||
void *shm_addr = NULL;
|
||||
char *shmfile = NULL;
|
||||
|
||||
void
|
||||
shm_alloc(unsigned long dsize)
|
||||
{
|
||||
#ifdef HAVE_SHM_OPEN
|
||||
if (!shmfile) shmfile = malloc(1024);
|
||||
if (!shmfile) goto failed;
|
||||
shmfile[0] = 0;
|
||||
srand(time(NULL));
|
||||
do
|
||||
{
|
||||
snprintf(shmfile, 1024, "/evas-loader.%i.%i",
|
||||
(int)getpid(), (int)rand());
|
||||
shm_fd = shm_open(shmfile, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
}
|
||||
while (shm_fd < 0);
|
||||
|
||||
if (ftruncate(shm_fd, dsize) < 0)
|
||||
{
|
||||
close(shm_fd);
|
||||
shm_unlink(shmfile);
|
||||
shm_fd = -1;
|
||||
goto failed;
|
||||
}
|
||||
shm_addr = mmap(NULL, dsize, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
||||
if (shm_addr == MAP_FAILED)
|
||||
{
|
||||
close(shm_fd);
|
||||
shm_unlink(shmfile);
|
||||
shm_fd = -1;
|
||||
goto failed;
|
||||
}
|
||||
shm_size = dsize;
|
||||
return;
|
||||
failed:
|
||||
#endif
|
||||
shm_addr = malloc(dsize);
|
||||
}
|
||||
|
||||
void
|
||||
shm_free(void)
|
||||
{
|
||||
#ifdef HAVE_SHM_OPEN
|
||||
if (shm_fd >= 0)
|
||||
{
|
||||
munmap(shm_addr, shm_size);
|
||||
close(shm_fd);
|
||||
shm_fd = -1;
|
||||
shm_addr = NULL;
|
||||
if (shmfile) free(shmfile);
|
||||
shmfile = NULL;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
free(shm_addr);
|
||||
shm_addr = NULL;
|
||||
shm_fd = -1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef SHMFILE_H
|
||||
#define SHMFILE_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int shm_fd;
|
||||
extern int shm_size;
|
||||
extern void *shm_addr;
|
||||
extern char *shmfile;
|
||||
|
||||
void shm_alloc (unsigned long dsize);
|
||||
void shm_free (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
static void
|
||||
_timeout(int val)
|
||||
{
|
||||
_exit(-1);
|
||||
if (val) return;
|
||||
}
|
||||
|
||||
void
|
||||
timeout_init(int seconds)
|
||||
{
|
||||
signal(SIGALRM, _timeout);
|
||||
alarm(seconds);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef TIMEOUT_H
|
||||
#define TIMEOUT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void timeout_init(int seconds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
LOBIN=soffice
|
||||
if [ -x /usr/lib/libreoffice/program/soffice.bin ]; then
|
||||
LOBIN=/usr/lib/libreoffice/program/soffice.bin
|
||||
elif [ -x /usr/lib64/libreoffice/program/soffice.bin ]; then
|
||||
LOBIN=/usr/lib64/libreoffice/program/soffice.bin
|
||||
fi
|
||||
$LOBIN --headless --convert-to pdf --outdir "$2" "$1"
|
|
@ -0,0 +1,353 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <GlobalParams.h>
|
||||
#include <PDFDoc.h>
|
||||
#include <ErrorCodes.h>
|
||||
#include <Page.h>
|
||||
#include <SplashOutputDev.h>
|
||||
#include <splash/SplashBitmap.h>
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#include "shmfile.h"
|
||||
#include "timeout.h"
|
||||
|
||||
#define DATA32 unsigned int
|
||||
|
||||
//#define PDF_DBG
|
||||
|
||||
#ifdef PDF_DBG
|
||||
#define D(fmt, args...) fprintf(stderr, fmt, ## args)
|
||||
#else
|
||||
#define D(fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
PDFDoc *pdfdoc;
|
||||
bool locked = false;
|
||||
|
||||
::Page *page;
|
||||
int width = 0, height = 0;
|
||||
int crop_width = 0, crop_height = 0;
|
||||
void *data = NULL;
|
||||
double dpi = -1.0;
|
||||
|
||||
#define DEF_DPI 72.0
|
||||
|
||||
Eina_Bool poppler_init(const char *file, int page_nbr, int size_w, int size_h)
|
||||
{
|
||||
Object obj;
|
||||
double w, h, cw, ch;
|
||||
int rot;
|
||||
|
||||
if (!file || !*file)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (page_nbr < 0)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (!(globalParams = new GlobalParams()))
|
||||
return EINA_FALSE;
|
||||
|
||||
if (!eina_init())
|
||||
goto del_global_param;
|
||||
|
||||
#ifndef HAVE_POPPLER_031
|
||||
if (globalParams->getAntialias())
|
||||
globalParams->setAntialias((char *)"yes");
|
||||
if (globalParams->getVectorAntialias())
|
||||
globalParams->setVectorAntialias((char *)"yes");
|
||||
#endif
|
||||
|
||||
pdfdoc = new PDFDoc(new GooString(file), NULL);
|
||||
if (!pdfdoc)
|
||||
goto del_global_param;
|
||||
|
||||
if (!pdfdoc->isOk() || (pdfdoc->getErrorCode() == errEncrypted))
|
||||
goto del_pdfdoc;
|
||||
|
||||
if (page_nbr >= pdfdoc->getNumPages())
|
||||
goto del_pdfdoc;
|
||||
|
||||
/* load the page */
|
||||
|
||||
page = pdfdoc->getCatalog()->getPage(page_nbr + 1);
|
||||
if (!page || !page->isOk())
|
||||
goto del_pdfdoc;
|
||||
|
||||
w = page->getMediaWidth();
|
||||
h = page->getMediaHeight();
|
||||
cw = page->getCropWidth();
|
||||
ch = page->getCropHeight();
|
||||
rot = page->getRotate();
|
||||
if (cw > w) cw = w;
|
||||
if (ch > h) ch = h;
|
||||
if ((rot == 90) || (rot == 270))
|
||||
{
|
||||
double t;
|
||||
// swap width & height
|
||||
t = w; w = h; h = t;
|
||||
// swap crop width & height
|
||||
t = cw; cw = ch; ch = t;
|
||||
}
|
||||
|
||||
if ((size_w > 0) || (size_h > 0))
|
||||
{
|
||||
double w2 = cw, h2 = ch;
|
||||
|
||||
w2 = size_w;
|
||||
h2 = (size_w * ch) / cw;
|
||||
if (h2 > size_h)
|
||||
{
|
||||
h2 = size_h;
|
||||
w2 = (size_h * cw) / ch;
|
||||
}
|
||||
D("XXXXXXXXXXXXXXXXXXXXx %3.3fx%3.3f\n", w2, h2);
|
||||
if (w2 > h2) dpi = (w2 * DEF_DPI) / cw;
|
||||
else dpi = (h2 * DEF_DPI) / ch;
|
||||
}
|
||||
|
||||
if (dpi > 0.0)
|
||||
{
|
||||
cw = (cw * dpi) / DEF_DPI;
|
||||
ch = (ch * dpi) / DEF_DPI;
|
||||
w = (w * dpi) / DEF_DPI;
|
||||
h = (h * dpi) / DEF_DPI;
|
||||
}
|
||||
width = w;
|
||||
height = h;
|
||||
crop_width = cw;
|
||||
crop_height = ch;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
del_pdfdoc:
|
||||
delete pdfdoc;
|
||||
del_global_param:
|
||||
delete globalParams;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void poppler_shutdown()
|
||||
{
|
||||
delete pdfdoc;
|
||||
eina_shutdown();
|
||||
delete globalParams;
|
||||
}
|
||||
|
||||
void poppler_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED)
|
||||
{
|
||||
SplashOutputDev *output_dev;
|
||||
SplashColor white;
|
||||
SplashColorPtr color_ptr;
|
||||
DATA32 *src, *dst;
|
||||
int y;
|
||||
|
||||
white[0] = 255;
|
||||
white[1] = 255;
|
||||
white[2] = 255;
|
||||
white[3] = 255;
|
||||
|
||||
output_dev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, white);
|
||||
if (!output_dev)
|
||||
return;
|
||||
|
||||
#if defined(HAVE_POPPLER_020) || defined(HAVE_POPPLER_031)
|
||||
output_dev->startDoc(pdfdoc);
|
||||
#else
|
||||
output_dev->startDoc(pdfdoc->getXRef());
|
||||
#endif
|
||||
|
||||
if (dpi <= 0.0) dpi = DEF_DPI;
|
||||
|
||||
#ifdef HAVE_POPPLER_031
|
||||
output_dev->setFontAntialias(EINA_TRUE);
|
||||
output_dev->setVectorAntialias(EINA_TRUE);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_POPPLER_020) || defined(HAVE_POPPLER_031)
|
||||
page->displaySlice(output_dev, dpi, dpi,
|
||||
0, false, false,
|
||||
0, 0, width, height,
|
||||
false, NULL, NULL);
|
||||
#else
|
||||
page->displaySlice(output_dev, dpi, dpi,
|
||||
0, false, false,
|
||||
0, 0, width, height,
|
||||
false, pdfdoc->getCatalog());
|
||||
#endif
|
||||
color_ptr = output_dev->getBitmap()->getDataPtr();
|
||||
|
||||
shm_alloc(crop_width * crop_height * sizeof(DATA32));
|
||||
if (!shm_addr) goto del_outpput_dev;
|
||||
data = shm_addr;
|
||||
src = (DATA32 *)color_ptr;
|
||||
dst = (DATA32 *)data;
|
||||
for (y = 0; y < crop_height; y++)
|
||||
{
|
||||
memcpy(dst, src, crop_width * sizeof(DATA32));
|
||||
src += width;
|
||||
dst += crop_width;
|
||||
}
|
||||
|
||||
del_outpput_dev:
|
||||
delete output_dev;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
Eina_Tmpstr *tmpdir = NULL;
|
||||
Eina_Tmpstr *generated = NULL;
|
||||
char *extension;
|
||||
char *dir;
|
||||
char *file;
|
||||
int i;
|
||||
int size_w = 0, size_h = 0;
|
||||
int head_only = 0;
|
||||
int page_num = 0;
|
||||
|
||||
if (argc < 2) return -1;
|
||||
// file is ALWAYS first arg, other options come after
|
||||
file = argv[1];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (!strcmp(argv[i], "-head"))
|
||||
// asked to only load header, not body/data
|
||||
head_only = 1;
|
||||
else if (!strcmp(argv[i], "-key"))
|
||||
{
|
||||
i++;
|
||||
page_num = atoi(argv[i]);
|
||||
i++;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-scale-down-by"))
|
||||
{ // not used by pdf loader
|
||||
i++;
|
||||
// int scale_down = atoi(argv[i]);
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-dpi"))
|
||||
{
|
||||
i++;
|
||||
dpi = ((double)atoi(argv[i])) / 1000.0; // dpi is an int multiplied by 1000 (so 72dpi is 72000)
|
||||
i++;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-size"))
|
||||
{ // not used by pdf loader
|
||||
i++;
|
||||
size_w = atoi(argv[i]);
|
||||
i++;
|
||||
size_h = atoi(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
D("dpi....: %f\n", dpi);
|
||||
D("page...: %d\n", page_num);
|
||||
|
||||
// This is a funny hack to call an external tool to generate a pdf that will then be processed by poppler
|
||||
extension = strrchr(file, '.');
|
||||
dir = dirname(argv[0]);
|
||||
if (extension && dir && strcmp(extension, ".pdf"))
|
||||
{
|
||||
if (eina_file_mkdtemp("evas_generic_pdf_loaderXXXXXX", &tmpdir))
|
||||
{
|
||||
Eina_Strbuf *tmp;
|
||||
FILE *cmd;
|
||||
|
||||
tmp = eina_strbuf_new();
|
||||
eina_strbuf_append_printf(tmp, "%s/evas_generic_pdf_loader.%s '%s' %s", dir, extension + 1, file, tmpdir);
|
||||
|
||||
cmd = popen(eina_strbuf_string_get(tmp), "r");
|
||||
D("running preprocessing process '%s'...\n", eina_strbuf_string_get(tmp));
|
||||
eina_strbuf_reset(tmp);
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
struct stat st;
|
||||
const char *filename;
|
||||
char buf[1024];
|
||||
|
||||
while (fgets(buf, sizeof (buf), cmd))
|
||||
;
|
||||
pclose(cmd);
|
||||
|
||||
filename = basename(file);
|
||||
generated = eina_tmpstr_add_length(filename, strlen(filename) - strlen(extension));
|
||||
|
||||
eina_strbuf_append_printf(tmp, "%s/%s.pdf", tmpdir, generated);
|
||||
|
||||
eina_tmpstr_del(generated);
|
||||
generated = NULL;
|
||||
|
||||
if (stat(eina_strbuf_string_get(tmp), &st) == 0)
|
||||
{
|
||||
generated = eina_tmpstr_add_length(eina_strbuf_string_get(tmp),
|
||||
eina_strbuf_length_get(tmp));
|
||||
file = (char*) generated;
|
||||
}
|
||||
}
|
||||
|
||||
D("generated file: '%s'\n", generated);
|
||||
eina_strbuf_free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
// Let's force a timeout if things go wrong
|
||||
timeout_init(10);
|
||||
|
||||
// Now process the pdf (or the generated pdf)
|
||||
D("poppler_file_init\n");
|
||||
if (!poppler_init(file, page_num, size_w, size_h))
|
||||
return -1;
|
||||
D("poppler_file_init done\n");
|
||||
|
||||
D("dpi2...: %f\n", dpi);
|
||||
if (!head_only)
|
||||
{
|
||||
poppler_load_image(size_w, size_h);
|
||||
}
|
||||
|
||||
D("size...: %ix%i\n", width, height);
|
||||
D("crop...: %ix%i\n", crop_width, crop_height);
|
||||
D("alpha..: 1\n");
|
||||
|
||||
printf("size %i %i\n", crop_width, crop_height);
|
||||
printf("alpha 0\n");
|
||||
|
||||
if (!head_only)
|
||||
{
|
||||
if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
|
||||
else
|
||||
{
|
||||
// could also to "tmpfile %s\n" like shmfile but just
|
||||
// a mmaped tmp file on the system
|
||||
printf("data\n");
|
||||
fwrite(data, crop_width * crop_height * sizeof(DATA32), 1, stdout);
|
||||
}
|
||||
shm_free();
|
||||
}
|
||||
else
|
||||
printf("done\n");
|
||||
|
||||
poppler_shutdown();
|
||||
|
||||
if (tmpdir)
|
||||
{
|
||||
if (generated) unlink(generated);
|
||||
rmdir(tmpdir);
|
||||
|
||||
eina_tmpstr_del(tmpdir);
|
||||
eina_tmpstr_del(generated);
|
||||
}
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libspectre/spectre.h>
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#include "shmfile.h"
|
||||
#include "timeout.h"
|
||||
|
||||
#define DATA32 unsigned int
|
||||
|
||||
#define PS_DBG
|
||||
|
||||
#ifdef PS_DBG
|
||||
#define D(fmt, args...) fprintf(stderr, fmt, ## args)
|
||||
#else
|
||||
#define D(fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
static SpectreDocument *psdoc;
|
||||
static int page_count;
|
||||
|
||||
static SpectrePage *page;
|
||||
|
||||
static int width = 0;
|
||||
static int height = 0;
|
||||
static void *data = NULL;
|
||||
static double dpi = -1.0;
|
||||
|
||||
#define DEF_DPI 72.0
|
||||
|
||||
static Eina_Bool
|
||||
_spectre_init(const char *file, int page_nbr, int size_w, int size_h)
|
||||
{
|
||||
double w, h;
|
||||
int ww, hh;
|
||||
SpectreOrientation rot;
|
||||
SpectreStatus status;
|
||||
|
||||
if (!file || !*file)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (page_nbr < 0)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (!eina_init())
|
||||
return EINA_FALSE;
|
||||
|
||||
psdoc = spectre_document_new();
|
||||
if (!psdoc)
|
||||
goto shutdown_eina;
|
||||
|
||||
spectre_document_load(psdoc, file);
|
||||
status = spectre_document_status (psdoc);
|
||||
if (status != SPECTRE_STATUS_SUCCESS)
|
||||
{
|
||||
D("[ps] %s\n", spectre_status_to_string(status));
|
||||
goto free_psdoc;
|
||||
}
|
||||
|
||||
page_count = spectre_document_get_n_pages(psdoc);
|
||||
status = spectre_document_status(psdoc);
|
||||
if (status != SPECTRE_STATUS_SUCCESS)
|
||||
{
|
||||
D("[eps] %s\n", spectre_status_to_string (status));
|
||||
goto free_psdoc;
|
||||
}
|
||||
|
||||
if (page_nbr >= page_count)
|
||||
goto free_psdoc;
|
||||
|
||||
/* load the page */
|
||||
|
||||
page = spectre_document_get_page(psdoc, page_nbr);
|
||||
status = spectre_document_status(psdoc);
|
||||
if (status != SPECTRE_STATUS_SUCCESS)
|
||||
{
|
||||
D("[eps] %s\n", spectre_status_to_string (status));
|
||||
goto free_page;
|
||||
}
|
||||
|
||||
spectre_page_get_size(page, &ww, &hh);
|
||||
w = ww;
|
||||
h = hh;
|
||||
rot = spectre_page_get_orientation(page);
|
||||
|
||||
if ((rot == SPECTRE_ORIENTATION_LANDSCAPE) || (rot == SPECTRE_ORIENTATION_REVERSE_LANDSCAPE))
|
||||
{
|
||||
double t;
|
||||
// swap width & height
|
||||
t = w; w = h; h = t;
|
||||
}
|
||||
|
||||
if ((size_w > 0) || (size_h > 0))
|
||||
{
|
||||
double w2 = w, h2 = h;
|
||||
|
||||
w2 = size_w;
|
||||
h2 = (size_w * h) / w;
|
||||
if (h2 > size_h)
|
||||
{
|
||||
h2 = size_h;
|
||||
w2 = (size_h * w) / h;
|
||||
}
|
||||
D("XXXXXXXXXXXXXXXXXXXXx %3.3fx%3.3f\n", w2, h2);
|
||||
if (w2 > h2) dpi = (w2 * DEF_DPI) / w;
|
||||
else dpi = (h2 * DEF_DPI) / h;
|
||||
}
|
||||
|
||||
if (dpi > 0.0)
|
||||
{
|
||||
w = (w * dpi) / DEF_DPI;
|
||||
h = (h * dpi) / DEF_DPI;
|
||||
}
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
free_page:
|
||||
spectre_page_free(page);
|
||||
free_psdoc:
|
||||
spectre_document_free(psdoc);
|
||||
shutdown_eina:
|
||||
eina_shutdown();
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_spectre_shutdown()
|
||||
{
|
||||
spectre_page_free(page);
|
||||
spectre_document_free(psdoc);
|
||||
eina_shutdown();
|
||||
}
|
||||
|
||||
static void
|
||||
_pixcopy(DATA32 *dst, unsigned char *src, int size)
|
||||
{
|
||||
DATA32 *d;
|
||||
unsigned char *s, *e;
|
||||
|
||||
d = dst;
|
||||
s = src;
|
||||
e = s + size;
|
||||
while (s < e)
|
||||
{
|
||||
d[0] =
|
||||
0xff000000 |
|
||||
(s[2] << 16) |
|
||||
(s[1] << 8 ) |
|
||||
(s[0] );
|
||||
d++;
|
||||
s += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_spectre_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED)
|
||||
{
|
||||
SpectreRenderContext *rc;
|
||||
unsigned char *psdata;
|
||||
int stride;
|
||||
unsigned char *src;
|
||||
DATA32 *dst;
|
||||
int yy;
|
||||
SpectreStatus status;
|
||||
|
||||
rc = spectre_render_context_new();
|
||||
if (!rc)
|
||||
return;
|
||||
|
||||
spectre_page_render(page, rc, &psdata, &stride);
|
||||
spectre_render_context_set_page_size (rc, width, height);
|
||||
status = spectre_page_status(page);
|
||||
if (status != SPECTRE_STATUS_SUCCESS)
|
||||
{
|
||||
D("[eps] %s\n", spectre_status_to_string (status));
|
||||
return;
|
||||
}
|
||||
|
||||
shm_alloc(width * height * sizeof(DATA32));
|
||||
if (!shm_addr) return;
|
||||
data = shm_addr;
|
||||
|
||||
if (stride == 4 * width)
|
||||
_pixcopy(data, psdata, height * stride);
|
||||
else
|
||||
{
|
||||
src = psdata;
|
||||
dst = (DATA32 *)data;
|
||||
for (yy = 0; yy < height; src += stride, dst += width, ++yy)
|
||||
_pixcopy (dst, src, width * 4);
|
||||
}
|
||||
|
||||
spectre_render_context_free(rc);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *file;
|
||||
int i;
|
||||
int size_w = 0, size_h = 0;
|
||||
int head_only = 0;
|
||||
int page_nbr = 0;
|
||||
|
||||
if (argc < 2) return -1;
|
||||
// file is ALWAYS first arg, other options come after
|
||||
file = argv[1];
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
if (!strcmp(argv[i], "-head"))
|
||||
// asked to only load header, not body/data
|
||||
head_only = 1;
|
||||
else if (!strcmp(argv[i], "-key"))
|
||||
{
|
||||
i++;
|
||||
page_nbr = atoi(argv[i]);
|
||||
i++;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-scale-down-by"))
|
||||
{ // not used by ps loader
|
||||
i++;
|
||||
// int scale_down = atoi(argv[i]);
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-dpi"))
|
||||
{
|
||||
i++;
|
||||
dpi = ((double)atoi(argv[i])) / 1000.0; // dpi is an int multiplied by 1000 (so 72dpi is 72000)
|
||||
i++;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-size"))
|
||||
{ // not used by ps loader
|
||||
i++;
|
||||
size_w = atoi(argv[i]);
|
||||
i++;
|
||||
size_h = atoi(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
D("_spectre_init_file\n");
|
||||
D("dpi....: %f\n", dpi);
|
||||
D("page...: %d\n", page_nbr);
|
||||
|
||||
timeout_init(10);
|
||||
|
||||
if (!_spectre_init(file, page_nbr, size_w, size_h))
|
||||
return -1;
|
||||
D("_spectre_init done\n");
|
||||
|
||||
D("dpi2...: %f\n", dpi);
|
||||
if (!head_only)
|
||||
{
|
||||
_spectre_load_image(size_w, size_h);
|
||||
}
|
||||
|
||||
D("size...: %ix%i\n", width, height);
|
||||
D("alpha..: 0\n");
|
||||
|
||||
printf("size %i %i\n", width, height);
|
||||
printf("alpha 0\n");
|
||||
|
||||
if (!head_only)
|
||||
{
|
||||
if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
|
||||
else
|
||||
{
|
||||
// could also to "tmpfile %s\n" like shmfile but just
|
||||
// a mmaped tmp file on the system
|
||||
printf("data\n");
|
||||
fwrite(data, width * height * sizeof(DATA32), 1, stdout);
|
||||
}
|
||||
shm_free();
|
||||
}
|
||||
else
|
||||
printf("done\n");
|
||||
|
||||
_spectre_shutdown();
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <libraw.h>
|
||||
#include "shmfile.h"
|
||||
#include "timeout.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
|
||||
#define DATA32 unsigned int
|
||||
#define DATA8 unsigned char
|
||||
|
||||
#define ARGB_JOIN(a,r,g,b) \
|
||||
(((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
|
||||
|
||||
//#define RAW_DBG 1
|
||||
|
||||
#ifdef RAW_DBG
|
||||
#define D(fmt, args...) fprintf(stderr, fmt, ## args)
|
||||
#else
|
||||
#define D(fmt, args...)
|
||||
#endif
|
||||
|
||||
static int fd = -1;
|
||||
static size_t seg_size = 0;
|
||||
static unsigned char *seg = MAP_FAILED;
|
||||
static libraw_data_t *raw_data = NULL;
|
||||
static void *data = NULL;
|
||||
static int width = 0;
|
||||
static int height = 0;
|
||||
|
||||
static int
|
||||
_raw_init(const char *file)
|
||||
{
|
||||
struct stat ss;
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) return EINA_FALSE;
|
||||
|
||||
if (stat(file, &ss)) goto close_file;
|
||||
seg_size = ss.st_size;
|
||||
seg = mmap(NULL, seg_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (seg == MAP_FAILED) goto close_file;
|
||||
|
||||
D("raw_init\n");
|
||||
raw_data = libraw_init(0);
|
||||
raw_data->params.half_size = 0;
|
||||
raw_data->params.user_qual = 2;
|
||||
|
||||
D("raw_open_buffer\n");
|
||||
if (libraw_open_buffer(raw_data, seg, seg_size) != LIBRAW_SUCCESS)
|
||||
return EINA_FALSE;
|
||||
return EINA_TRUE;
|
||||
|
||||
close_file:
|
||||
close(fd);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_raw_shutdown()
|
||||
{
|
||||
D("raw_shutdown\n");
|
||||
if (raw_data)
|
||||
libraw_close(raw_data);
|
||||
if (seg != MAP_FAILED) munmap(seg, seg_size);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int
|
||||
read_raw_header()
|
||||
{
|
||||
int ret;
|
||||
|
||||
D("raw_open_buffer\n");
|
||||
if ((ret = libraw_open_buffer(raw_data, seg, seg_size)) != LIBRAW_SUCCESS)
|
||||
return 0;
|
||||
|
||||
D("raw_adjust_size\n");
|
||||
if ((ret = libraw_adjust_sizes_info_only(raw_data)) != LIBRAW_SUCCESS)
|
||||
{
|
||||
if (LIBRAW_FATAL_ERROR(ret))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((raw_data->sizes.width < 1) || (raw_data->sizes.height < 1))
|
||||
return 0;
|
||||
|
||||
width = raw_data->sizes.iwidth;
|
||||
height = raw_data->sizes.iheight;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
read_raw_data()
|
||||
{
|
||||
int ret;
|
||||
unsigned int count;
|
||||
libraw_processed_image_t *image = NULL;
|
||||
DATA8 *bufptr;
|
||||
DATA32 *dataptr;
|
||||
|
||||
|
||||
D("raw_open_unpack\n");
|
||||
if ((ret = libraw_unpack(raw_data)) != LIBRAW_SUCCESS)
|
||||
return 0;
|
||||
|
||||
D("raw_dcraw_process\n");
|
||||
if ((ret = libraw_dcraw_process(raw_data)) != LIBRAW_SUCCESS)
|
||||
{
|
||||
if (LIBRAW_FATAL_ERROR(ret))
|
||||
return 0;;
|
||||
}
|
||||
|
||||
D("raw_make_mem_image\n");
|
||||
image = libraw_dcraw_make_mem_image(raw_data, &ret);
|
||||
if (image)
|
||||
{
|
||||
if ((image->width < 1) || (image->height < 1))
|
||||
goto clean_image;
|
||||
width = image->width;
|
||||
height = image->height;
|
||||
if (image->type != LIBRAW_IMAGE_BITMAP)
|
||||
goto clean_image;
|
||||
if (image->colors != 3)
|
||||
goto clean_image;
|
||||
#define SWAP(a, b) { a ^= b; a = (b ^=a); }
|
||||
if ((image->bits == 16) && (htons(0x55aa) != 0x55aa))
|
||||
for (count = 0; count < image->data_size; count +=2)
|
||||
SWAP(image->data[count], image->data[count + 1]);
|
||||
#undef SWAP
|
||||
shm_alloc((unsigned int)(image->width * image->height) * (sizeof(DATA32)));
|
||||
if (!shm_addr)
|
||||
goto clean_image;
|
||||
data = shm_addr;
|
||||
memset(shm_addr, 0, (unsigned int)(image->width * image->height) * (sizeof(DATA32)));
|
||||
dataptr = data;
|
||||
bufptr = image->data;
|
||||
for (count = (unsigned int)(image->width * image->height); count > 0; --count)
|
||||
{
|
||||
*dataptr = ARGB_JOIN(0xff, bufptr[0], bufptr[1], bufptr[2]);
|
||||
dataptr++;
|
||||
bufptr += 3;
|
||||
}
|
||||
|
||||
free(image);
|
||||
}
|
||||
return 1;
|
||||
|
||||
clean_image:
|
||||
free(image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *file;
|
||||
int i;
|
||||
int head_only = 0;
|
||||
|
||||
if (argc < 2) return -1;
|
||||
file = argv[1];
|
||||
|
||||
for (i = 2; i < argc; ++i)
|
||||
{
|
||||
if (!strcmp(argv[i], "-head"))
|
||||
head_only = 1;
|
||||
else if (!strcmp(argv[i], "-key"))
|
||||
{ // not used by raw loader
|
||||
i++;
|
||||
// const char *key = argv[i];
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-scale-down-by"))
|
||||
{ // not used by raw loader
|
||||
i++;
|
||||
// int scale_down = atoi(argv[i]);
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-dpi"))
|
||||
{ // not used by raw loader
|
||||
i++;
|
||||
// double dpi = ((double)atoi(argv[i])) / 1000.0;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-size"))
|
||||
{ // not used by raw loader
|
||||
i++;
|
||||
// int size_w = atoi(argv[i]);
|
||||
i++;
|
||||
// int size_h = atoi(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
timeout_init(4);
|
||||
|
||||
if (!_raw_init(file)) return -1;
|
||||
if (head_only != 0)
|
||||
{
|
||||
if (read_raw_header())
|
||||
{
|
||||
printf("size %d %d\n", width, height);
|
||||
printf("alpha 1\n");
|
||||
}
|
||||
printf("done\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read_raw_data())
|
||||
{
|
||||
printf("size %d %d\n", width, height);
|
||||
printf("alpha 1\n");
|
||||
if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
|
||||
else
|
||||
{
|
||||
printf("data\n");
|
||||
fwrite(data, (unsigned int)(width * height) * sizeof(DATA32), 1, stdout);
|
||||
}
|
||||
shm_free();
|
||||
}
|
||||
}
|
||||
_raw_shutdown();
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include "shmfile.h"
|
||||
#include "timeout.h"
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#include <librsvg/rsvg.h>
|
||||
#ifndef LIBRSVG_CHECK_VERSION
|
||||
# include <librsvg/librsvg-features.h>
|
||||
#endif
|
||||
#if LIBRSVG_CHECK_VERSION(2,36,2)
|
||||
#else
|
||||
# include <librsvg/rsvg-cairo.h>
|
||||
#endif
|
||||
|
||||
#define DATA32 unsigned int
|
||||
|
||||
static RsvgHandle *rsvg = NULL;
|
||||
static int width = 0;
|
||||
static int height = 0;
|
||||
static RsvgDimensionData dim;
|
||||
|
||||
static inline Eina_Bool evas_image_load_file_is_svg(const char *file)
|
||||
{
|
||||
int i, len = strlen(file);
|
||||
Eina_Bool is_gz = EINA_FALSE;
|
||||
|
||||
for (i = len - 1; i > 0; i--)
|
||||
{
|
||||
if (file[i] == '.')
|
||||
{
|
||||
if (is_gz)
|
||||
break;
|
||||
else if (strcasecmp(file + i + 1, "gz") == 0)
|
||||
is_gz = EINA_TRUE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < 1) return EINA_FALSE;
|
||||
i++;
|
||||
if (i >= len) return EINA_FALSE;
|
||||
if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
|
||||
i += 3;
|
||||
if (is_gz)
|
||||
{
|
||||
if (file[i] == '.') return EINA_TRUE;
|
||||
else return EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (file[i] == '\0') return EINA_TRUE;
|
||||
else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
|
||||
else return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_svg_init(const char *file)
|
||||
{
|
||||
#ifdef HAVE_SVG_2_36
|
||||
# if !defined(GLIB_VERSION_2_36)
|
||||
g_type_init();
|
||||
# endif
|
||||
#else
|
||||
rsvg_init();
|
||||
#endif
|
||||
|
||||
if (!evas_image_load_file_is_svg(file)) return 0;
|
||||
|
||||
rsvg = rsvg_handle_new_from_file(file, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_svg_shutdown(void)
|
||||
{
|
||||
if (rsvg)
|
||||
{
|
||||
rsvg_handle_close(rsvg, NULL);
|
||||
g_object_unref(rsvg);
|
||||
}
|
||||
// Maybe it's not crashing anymore, let's try it.
|
||||
#ifndef HAVE_SVG_2_36
|
||||
rsvg_term();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
read_svg_header(int scale_down, double dpi, int size_w, int size_h)
|
||||
{
|
||||
rsvg_handle_set_dpi(rsvg, 75.0);
|
||||
rsvg_handle_get_dimensions(rsvg, &dim);
|
||||
width = dim.width;
|
||||
height = dim.height;
|
||||
|
||||
if ((width < 1) || (height < 1)) return 0;
|
||||
|
||||
if (scale_down > 1)
|
||||
{
|
||||
width /= scale_down;
|
||||
height /= scale_down;
|
||||
}
|
||||
else if (dpi > 0.0)
|
||||
{
|
||||
width = (width * dpi) / 75;
|
||||
height = (height * dpi) / 75;
|
||||
}
|
||||
else if (size_w > 0 && size_h > 0)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
w = size_w;
|
||||
h = (size_w * height) / width;
|
||||
if (h > size_h)
|
||||
{
|
||||
h = size_h;
|
||||
w = (size_h * width) / height;
|
||||
}
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
if (width < 1) width = 1;
|
||||
if (height < 1) height = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
read_svg_data(void)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
shm_alloc(width * height * (sizeof(DATA32)));
|
||||
if (!shm_addr) return 0;
|
||||
|
||||
memset(shm_addr, 0, width * height * sizeof (DATA32));
|
||||
surface = cairo_image_surface_create_for_data((unsigned char *)shm_addr, CAIRO_FORMAT_ARGB32,
|
||||
width, height, width * sizeof(DATA32));;
|
||||
if (!surface) return 0;
|
||||
|
||||
cr = cairo_create(surface);
|
||||
if (!cr) return 0;
|
||||
|
||||
cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex);
|
||||
rsvg_handle_render_cairo(rsvg, cr);
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_destroy(cr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *file;
|
||||
int i;
|
||||
int head_only = 0;
|
||||
int scale_down = 0;
|
||||
double dpi = 0.0;
|
||||
int size_w = 0, size_h = 0;
|
||||
|
||||
if (argc < 2) return -1;
|
||||
file = argv[1];
|
||||
|
||||
for (i = 2; i < argc; ++i)
|
||||
{
|
||||
if (!strcmp(argv[i], "-head"))
|
||||
head_only = 1;
|
||||
else if (!strcmp(argv[i], "-key"))
|
||||
{ // not used by svg loader
|
||||
i++;
|
||||
// const char *key = argv[i];
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-scale-down-by"))
|
||||
{
|
||||
i++;
|
||||
scale_down = atoi(argv[i]);
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-dpi"))
|
||||
{
|
||||
i++;
|
||||
dpi = ((double)atoi(argv[i])) / 1000.0;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-opt-size"))
|
||||
{
|
||||
i++;
|
||||
size_w = atoi(argv[i]);
|
||||
i++;
|
||||
size_h = atoi(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
timeout_init(5);
|
||||
|
||||
if (!_svg_init(file)) return -1;
|
||||
if (!read_svg_header(scale_down, dpi, size_w, size_h)) return -1;
|
||||
|
||||
if (head_only != 0)
|
||||
{
|
||||
printf("size %d %d\n", width, height);
|
||||
printf("alpha 1\n");
|
||||
printf("done\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read_svg_data())
|
||||
{
|
||||
printf("size %d %d\n", width, height);
|
||||
printf("alpha 1\n");
|
||||
if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
|
||||
else
|
||||
{
|
||||
printf("data\n");
|
||||
fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout);
|
||||
}
|
||||
shm_free();
|
||||
}
|
||||
}
|
||||
_svg_shutdown();
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef __COMMON
|
||||
#define __COMMON 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <netinet/in.h>
|
||||
#include <time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#define DATABIG unsigned long long
|
||||
#define DATA64 unsigned long long
|
||||
#define DATA32 unsigned int
|
||||
#define DATA16 unsigned short
|
||||
#define DATA8 unsigned char
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
|
||||
#define A_VAL(p) ((DATA8 *)(p))[3]
|
||||
#define R_VAL(p) ((DATA8 *)(p))[2]
|
||||
#define G_VAL(p) ((DATA8 *)(p))[1]
|
||||
#define B_VAL(p) ((DATA8 *)(p))[0]
|
||||
|
||||
#else
|
||||
|
||||
#define A_VAL(p) ((DATA8 *)(p))[0]
|
||||
#define R_VAL(p) ((DATA8 *)(p))[1]
|
||||
#define G_VAL(p) ((DATA8 *)(p))[2]
|
||||
#define B_VAL(p) ((DATA8 *)(p))[3]
|
||||
|
||||
#endif
|
||||
|
||||
//#define XCF_DBG 1
|
||||
|
||||
#ifdef XCF_DBG
|
||||
#define D(fmt, args...) fprintf(stderr, fmt, ## args)
|
||||
#else
|
||||
#define D(fmt, args...)
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,759 @@
|
|||
/*
|
||||
|
||||
-----------------------------[ XCF Loader ]-----------------------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define RS R_VAL(src + s_idx)
|
||||
#define GS G_VAL(src + s_idx)
|
||||
#define BS B_VAL(src + s_idx)
|
||||
#define AS A_VAL(src + s_idx)
|
||||
#define RD R_VAL(dest + d_idx)
|
||||
#define GD G_VAL(dest + d_idx)
|
||||
#define BD B_VAL(dest + d_idx)
|
||||
#define AD A_VAL(dest + d_idx)
|
||||
|
||||
#define EPS 0.00001
|
||||
#define PI 3.141592654
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
|
||||
#define LINEAR(x,y,w) ((w*y + x)*4)
|
||||
|
||||
static void
|
||||
rgb_to_hls (DATA8 *red, DATA8 *green, DATA8 *blue)
|
||||
{
|
||||
int r, g, b;
|
||||
double h, l, s;
|
||||
int min, max;
|
||||
int delta;
|
||||
|
||||
r = *red;
|
||||
g = *green;
|
||||
b = *blue;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
max = MAX (r, b);
|
||||
min = MIN (g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
max = MAX (g, b);
|
||||
min = MIN (r, b);
|
||||
}
|
||||
|
||||
l = (max + min) / 2.0;
|
||||
|
||||
if (max == min)
|
||||
{
|
||||
s = 0.0;
|
||||
h = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = (max - min);
|
||||
|
||||
if (l < 128)
|
||||
s = 255 * (double) delta / (double) (max + min);
|
||||
else
|
||||
s = 255 * (double) delta / (double) (511 - max - min);
|
||||
|
||||
if (r == max)
|
||||
h = (g - b) / (double) delta;
|
||||
else if (g == max)
|
||||
h = 2 + (b - r) / (double) delta;
|
||||
else
|
||||
h = 4 + (r - g) / (double) delta;
|
||||
|
||||
h = h * 42.5;
|
||||
|
||||
if (h < 0)
|
||||
h += 255;
|
||||
else if (h > 255)
|
||||
h -= 255;
|
||||
}
|
||||
|
||||
*red = h;
|
||||
*green = l;
|
||||
*blue = s;
|
||||
}
|
||||
|
||||
|
||||
static DATA8
|
||||
gimp_hls_value (double n1, double n2, double hue)
|
||||
{
|
||||
double value;
|
||||
|
||||
if (hue > 255)
|
||||
hue -= 255;
|
||||
else if (hue < 0)
|
||||
hue += 255;
|
||||
if (hue < 42.5)
|
||||
value = n1 + (n2 - n1) * (hue / 42.5);
|
||||
else if (hue < 127.5)
|
||||
value = n2;
|
||||
else if (hue < 170)
|
||||
value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
|
||||
else
|
||||
value = n1;
|
||||
|
||||
return (DATA8) (value * 255);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hls_to_rgb (DATA8 *hue, DATA8 *lightness, DATA8 *saturation)
|
||||
{
|
||||
double h, l, s;
|
||||
double m1, m2;
|
||||
|
||||
h = *hue;
|
||||
l = *lightness;
|
||||
s = *saturation;
|
||||
|
||||
if (s == 0)
|
||||
{
|
||||
/* achromatic case */
|
||||
*hue = l;
|
||||
*lightness = l;
|
||||
*saturation = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (l < 128)
|
||||
m2 = (l * (255 + s)) / 65025.0;
|
||||
else
|
||||
m2 = (l + s - (l * s) / 255.0) / 255.0;
|
||||
|
||||
m1 = (l / 127.5) - m2;
|
||||
|
||||
/* chromatic case */
|
||||
*hue = gimp_hls_value (m1, m2, h + 85);
|
||||
*lightness = gimp_hls_value (m1, m2, h);
|
||||
*saturation = gimp_hls_value (m1, m2, h - 85);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rgb_to_hsv (DATA8 *red, DATA8 *green, DATA8 *blue)
|
||||
{
|
||||
int r, g, b;
|
||||
double h, s, v;
|
||||
int min, max;
|
||||
int delta;
|
||||
|
||||
h = 0.0;
|
||||
|
||||
r = *red;
|
||||
g = *green;
|
||||
b = *blue;
|
||||
|
||||
if (r > g)
|
||||
{
|
||||
max = MAX (r, b);
|
||||
min = MIN (g, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
max = MAX (g, b);
|
||||
min = MIN (r, b);
|
||||
}
|
||||
|
||||
v = max;
|
||||
|
||||
if (max != 0)
|
||||
s = ((max - min) * 255) / (double) max;
|
||||
else
|
||||
s = 0;
|
||||
|
||||
if (s == 0)
|
||||
h = 0;
|
||||
else
|
||||
{
|
||||
delta = max - min;
|
||||
if (r == max)
|
||||
h = (g - b) / (double) delta;
|
||||
else if (g == max)
|
||||
h = 2 + (b - r) / (double) delta;
|
||||
else if (b == max)
|
||||
h = 4 + (r - g) / (double) delta;
|
||||
h *= 42.5;
|
||||
|
||||
if (h < 0)
|
||||
h += 255;
|
||||
if (h > 255)
|
||||
h -= 255;
|
||||
}
|
||||
|
||||
*red = h;
|
||||
*green = s;
|
||||
*blue = v;
|
||||
}
|
||||
|
||||
static void
|
||||
hsv_to_rgb (DATA8 *hue, DATA8 *saturation, DATA8 *value)
|
||||
{
|
||||
double h, s, v;
|
||||
double f, p, q, t;
|
||||
|
||||
if (*saturation == 0)
|
||||
{
|
||||
*hue = *value;
|
||||
*saturation = *value;
|
||||
/* *value = *value; */
|
||||
}
|
||||
else
|
||||
{
|
||||
h = *hue * 6.0 / 255.0;
|
||||
s = *saturation / 255.0;
|
||||
v = *value / 255.0;
|
||||
|
||||
f = h - (int) h;
|
||||
p = v * (1.0 - s);
|
||||
q = v * (1.0 - (s * f));
|
||||
t = v * (1.0 - (s * (1.0 - f)));
|
||||
|
||||
switch ((int) h)
|
||||
{
|
||||
case 0:
|
||||
*hue = v * 255;
|
||||
*saturation = t * 255;
|
||||
*value = p * 255;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*hue = q * 255;
|
||||
*saturation = v * 255;
|
||||
*value = p * 255;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*hue = p * 255;
|
||||
*saturation = v * 255;
|
||||
*value = t * 255;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
*hue = p * 255;
|
||||
*saturation = q * 255;
|
||||
*value = v * 255;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*hue = t * 255;
|
||||
*saturation = p * 255;
|
||||
*value = v * 255;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
*hue = v * 255;
|
||||
*saturation = p * 255;
|
||||
*value = q * 255;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* translate negative destinations */
|
||||
static
|
||||
void _clip(int * src_tl_x, int * src_tl_y,
|
||||
int * src_br_x, int * src_br_y,
|
||||
int * dest_x, int * dest_y,
|
||||
int dest_w, int dest_h)
|
||||
{
|
||||
if (*dest_x + *src_br_x >= dest_w)
|
||||
{ *src_br_x -= (*dest_x + *src_br_x) - dest_w; }
|
||||
|
||||
if (*dest_y + *src_br_y >= dest_h)
|
||||
{ *src_br_y -= (*dest_y + *src_br_y) - dest_h; }
|
||||
|
||||
if (*dest_x < 0)
|
||||
{
|
||||
*src_tl_x = -(*dest_x);
|
||||
*dest_x = 0;
|
||||
}
|
||||
if (*dest_y < 0)
|
||||
{
|
||||
*src_tl_y = -(*dest_y);
|
||||
*dest_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: make sure layer alpha is used/applied in all cases
|
||||
void
|
||||
combine_pixels_normal (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
int b;
|
||||
unsigned char src_alpha;
|
||||
unsigned char new_alpha;
|
||||
float ratio, compl_ratio;
|
||||
unsigned long tmp;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
src_alpha = AS;
|
||||
|
||||
if (src_alpha != 0)
|
||||
{
|
||||
if (src_alpha == 255)
|
||||
new_alpha = src_alpha;
|
||||
else
|
||||
new_alpha = AD + INT_MULT((255u - AD), src_alpha, tmp);
|
||||
|
||||
b = 3;
|
||||
if (new_alpha != 0)
|
||||
{
|
||||
ratio = (float) src_alpha / new_alpha;
|
||||
compl_ratio = 1.0 - ratio;
|
||||
|
||||
do
|
||||
{
|
||||
b--;
|
||||
dest[d_idx + b] =
|
||||
(unsigned char) (src[s_idx + b] * ratio + dest[d_idx + b] * compl_ratio + EPS);
|
||||
}
|
||||
while (b);
|
||||
}
|
||||
|
||||
AD = new_alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_add (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
int tmp, tmp2;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp2 = INT_MULT(AS, RS, tmp);
|
||||
tmp = RD + tmp2;
|
||||
RD = (tmp > 255 ? 255 : tmp);
|
||||
|
||||
tmp2 = INT_MULT(AS, GS, tmp);
|
||||
tmp = GD + tmp2;
|
||||
GD = (tmp > 255 ? 255 : tmp);
|
||||
|
||||
tmp2 = INT_MULT(AS, BS, tmp);
|
||||
tmp = BD + tmp2;
|
||||
BD = (tmp > 255 ? 255 : tmp);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_sub (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
int tmp, tmp2;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp2 = INT_MULT(AS, RS, tmp);
|
||||
tmp = RD - tmp2;
|
||||
RD = (tmp < 0 ? 0 : tmp);
|
||||
|
||||
tmp2 = INT_MULT(AS, GS, tmp);
|
||||
tmp = GD - tmp2;
|
||||
GD = (tmp < 0 ? 0 : tmp);
|
||||
|
||||
tmp2 = INT_MULT(AS, BS, tmp);
|
||||
tmp = BD - tmp2;
|
||||
BD = (tmp < 0 ? 0 : tmp);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_diff (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
int tmp, tmp2;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp2 = INT_MULT(AS, RS, tmp);
|
||||
tmp = RD - tmp2;
|
||||
RD = (tmp < 0 ? -tmp : tmp);
|
||||
|
||||
tmp2 = INT_MULT(AS, GS, tmp);
|
||||
tmp = GD - tmp2;
|
||||
GD = (tmp < 0 ? -tmp : tmp);
|
||||
|
||||
tmp2 = INT_MULT(AS, BS, tmp);
|
||||
tmp = BD - tmp2;
|
||||
BD = (tmp < 0 ? -tmp : tmp);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_darken (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
RD = MIN(RD, RS);
|
||||
GD = MIN(GD, GS);
|
||||
BD = MIN(BD, BS);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_lighten (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
RD = MAX(RD, RS);
|
||||
GD = MAX(GD, GS);
|
||||
BD = MAX(BD, BS);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_mult (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
int tmp, tmp2, tmp3;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp2 = INT_MULT(RS, AS, tmp);
|
||||
tmp2 = INT_MULT(RD, tmp2, tmp);
|
||||
tmp3 = INT_MULT(RD, (255 - AS), tmp);
|
||||
RD = (tmp2 + tmp3);
|
||||
|
||||
tmp2 = INT_MULT(GS, AS, tmp);
|
||||
tmp2 = INT_MULT(GD, tmp2, tmp);
|
||||
tmp3 = INT_MULT(GD, (255 - AS), tmp);
|
||||
GD = (tmp2 + tmp3);
|
||||
|
||||
tmp2 = INT_MULT(BS, AS, tmp);
|
||||
tmp2 = INT_MULT(BD, tmp2, tmp);
|
||||
tmp3 = INT_MULT(BD, (255 - AS), tmp);
|
||||
BD = (tmp2 + tmp3);
|
||||
|
||||
// AS = MIN(AS, AD);
|
||||
}
|
||||
|
||||
// combine_pixels_normal(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_div (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
RS = MIN(255, ((float)RD / (RS + 1)) * 256);
|
||||
GS = MIN(255, ((float)GD / (GS + 1)) * 256);
|
||||
BS = MIN(255, ((float)BD / (BS + 1)) * 256);
|
||||
|
||||
// AS = MIN(AD, AS);
|
||||
}
|
||||
|
||||
combine_pixels_normal(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_screen (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
RD = 255 - (((255 - RD) * (255 - RS)) >> 8);
|
||||
GD = 255 - (((255 - GD) * (255 - GS)) >> 8);
|
||||
BD = 255 - (((255 - BD) * (255 - BS)) >> 8);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_overlay (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
int tmp_screen, tmp_mult;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
tmp_screen = 255 - (((255 - RD) * (255 - RS)) >> 8);
|
||||
tmp_mult = (RD * RS) >> 8;
|
||||
RD = (RD * tmp_screen + (255 - RD) * tmp_mult) >> 8;
|
||||
|
||||
tmp_screen = 255 - (((255 - GD) * (255 - GS)) >> 8);
|
||||
tmp_mult = (GD * GS) >> 8;
|
||||
GD = (GD * tmp_screen + (255 - GD) * tmp_mult) >> 8;
|
||||
|
||||
tmp_screen = 255 - (((255 - BD) * (255 - BS)) >> 8);
|
||||
tmp_mult = (BD * BS) >> 8;
|
||||
BD = (BD * tmp_screen + (255 - BD) * tmp_mult) >> 8;
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
combine_pixels_hsv (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y, int mode)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
rgb_to_hsv(&RS, &GS, &BS);
|
||||
rgb_to_hsv(&RD, &GD, &BD);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0: /* hue mode */
|
||||
RD = RS;
|
||||
break;
|
||||
case 1: /* saturation mode */
|
||||
GD = GS;
|
||||
break;
|
||||
case 2: /* value mode */
|
||||
BD = BS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hsv_to_rgb(&RD, &GD, &BD);
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_hue (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_sat (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_val (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
combine_pixels_hsv(src, src_w, src_h, dest, dest_w, dest_h, dest_x, dest_y, 2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_col (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
rgb_to_hls(&RS, &GS, &BS);
|
||||
rgb_to_hls(&RD, &GD, &BD);
|
||||
RD = RS;
|
||||
BD = BS;
|
||||
hls_to_rgb(&RD, &GD, &BD);
|
||||
|
||||
// AD = MIN(AD, AS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
combine_pixels_diss (DATA8* src, int src_w, int src_h, DATA8* dest, int dest_w, int dest_h, int dest_x, int dest_y)
|
||||
{
|
||||
int x, y, s_idx, d_idx;
|
||||
int src_tl_x = 0, src_tl_y = 0;
|
||||
int src_br_x = src_w, src_br_y = src_h;
|
||||
|
||||
srand(12345);
|
||||
|
||||
_clip(&src_tl_x, &src_tl_y, &src_br_x, &src_br_y, &dest_x, &dest_y, dest_w, dest_h);
|
||||
|
||||
for (y = src_tl_y; y < src_br_y; y++)
|
||||
for (x = src_tl_x; x < src_br_x; x++)
|
||||
{
|
||||
d_idx = LINEAR((dest_x + x - src_tl_x), (dest_y + y - src_tl_y), dest_w);
|
||||
s_idx = LINEAR(x, y, src_w);
|
||||
|
||||
if ((rand() % 255) < AS)
|
||||
{
|
||||
int b;
|
||||
unsigned char src_alpha;
|
||||
unsigned char new_alpha;
|
||||
float ratio, compl_ratio;
|
||||
unsigned long tmp;
|
||||
|
||||
src_alpha = AS;
|
||||
|
||||
if (src_alpha != 0)
|
||||
{
|
||||
if (src_alpha == 255)
|
||||
new_alpha = src_alpha;
|
||||
else
|
||||
new_alpha = AD + INT_MULT((255u - AD), src_alpha, tmp);
|
||||
|
||||
b = 3;
|
||||
if (new_alpha != 0)
|
||||
{
|
||||
ratio = (float) src_alpha / new_alpha;
|
||||
compl_ratio = 1.0 - ratio;
|
||||
|
||||
do
|
||||
{
|
||||
b--;
|
||||
dest[d_idx + b] =
|
||||
(unsigned char) (src[s_idx + b] * ratio + dest[d_idx + b] * compl_ratio + EPS);
|
||||
}
|
||||
while (b);
|
||||
}
|
||||
|
||||
AD = new_alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue