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:
Tom Hacohen 2016-06-02 11:36:13 +01:00
commit 92cfd074aa
20 changed files with 4945 additions and 1 deletions

40
AUTHORS
View File

@ -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>

View File

@ -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.

View File

@ -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])

View File

@ -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
])

View File

@ -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

View File

@ -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;

5
src/generic/.gitignore vendored Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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"

View File

@ -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;
}

289
src/generic/evas/ps/main.c Normal file
View File

@ -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;
}

242
src/generic/evas/raw/main.c Normal file
View File

@ -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;
}

230
src/generic/evas/svg/main.c Normal file
View File

@ -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;
}

View File

@ -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

1731
src/generic/evas/xcf/main.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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;
}
}
}
}