summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2011-05-12 05:44:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2011-05-12 05:44:42 +0000
commitdb19186bc1057b47bf686407ce730f8f8b395e4d (patch)
tree1e6baf1ece2ea8f1ad86102a95e022f50b805826
parentda9dafeb035df578e5b5e34782edfe22b546df67 (diff)
downloadevas_generic_loaders-db19186bc1057b47bf686407ce730f8f8b395e4d.tar.gz
Add PDF loader (with some help from raster)
SVN revision: 59338
-rw-r--r--TODO9
-rw-r--r--configure.ac48
-rw-r--r--src/bin/Makefile.am4
-rw-r--r--src/bin/pdf/Makefile.am19
-rw-r--r--src/bin/pdf/main.cpp304
-rw-r--r--src/bin/xcf/common.h4
6 files changed, 377 insertions, 11 deletions
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..f35cb33
--- /dev/null
+++ b/TODO
@@ -0,0 +1,9 @@
+
+Modules to add:
+---------------
+
+ [x] XCF
+ [x] PDF
+ [ ] PS
+ [ ] DVI
+ [ ] Djvu
diff --git a/configure.ac b/configure.ac
index a056f64..b7db8ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,11 +28,6 @@ AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([1.6 dist-bzip2])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-AC_LIBTOOL_WIN32_DLL
-define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
-define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
-AC_PROG_LIBTOOL
-
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_ifdef([v_rev], , [m4_define([v_rev], [0])])
@@ -54,8 +49,10 @@ AC_SUBST(VMAJ)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
-AC_C_BIGENDIAN
+
+### Checks for libraries
AC_PROG_CC
+AC_PROG_CXX
PKG_PROG_PKG_CONFIG
### Checks for libraries
@@ -63,14 +60,16 @@ PKG_PROG_PKG_CONFIG
# Eina library
PKG_CHECK_MODULES(EINA, [eina >= 1.0.0])
+PKG_CHECK_MODULES([POPPLER], [poppler >= 0.14], [have_poppler="yes"], [have_poppler="no"])
+
+AM_CONDITIONAL([HAVE_PDF], [test "x${have_poppler}" = "xyes"])
+
### Checks for header files
AC_CHECK_HEADER([zlib.h],
[dummy="yes"],
[AC_MSG_ERROR("Cannot find zlib.h. Make sure your CFLAGS environment variable contains include lines for the location of this file")])
-AC_CHECK_HEADERS(netinet/in.h)
-
SHM_OPEN_LIBS=""
AC_MSG_CHECKING([whether shm_open() is present])
LIBS_save=${LIBS}
@@ -102,15 +101,44 @@ AM_PROG_CC_C_O
AC_C_CONST
AC_C_INLINE
AC_PROG_CC_STDC
+AC_C_BIGENDIAN
AC_C___ATTRIBUTE__
### Checks for library functions
AC_ISC_POSIX
-AC_FUNC_ALLOCA
-AC_OUTPUT([
+AC_CONFIG_FILES([
Makefile
src/Makefile
src/bin/Makefile
src/bin/xcf/Makefile
+src/bin/pdf/Makefile
])
+
+AC_OUTPUT
+
+#####################################################################
+## Info
+
+echo
+echo
+echo
+echo "------------------------------------------------------------------------"
+echo "$PACKAGE $VERSION"
+echo "------------------------------------------------------------------------"
+echo
+echo
+echo "Configuration Options Summary:"
+echo
+echo "Loaders:"
+echo " XCF..................: yes"
+echo " PDF..................: ${have_poppler}"
+echo
+echo "Compilation............: make (or gmake)"
+echo " CPPFLAGS.............: $CPPFLAGS"
+echo " CFLAGS...............: $CFLAGS"
+echo " LDFLAGS..............: $LDFLAGS"
+echo
+echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')"
+echo " prefix...............: $prefix"
+echo
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index f64bd1c..eae5af3 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -1,3 +1,7 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = xcf
+
+if HAVE_PDF
+SUBDIRS += pdf
+endif
diff --git a/src/bin/pdf/Makefile.am b/src/bin/pdf/Makefile.am
new file mode 100644
index 0000000..3700ceb
--- /dev/null
+++ b/src/bin/pdf/Makefile.am
@@ -0,0 +1,19 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src \
+-I$(top_srcdir)/src/bin \
+-I$(top_srcdir)/src/bin/pdf \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@EINA_CFLAGS@ \
+@POPPLER_CFLAGS@
+
+bin_PROGRAMS = evas_image_loader.pdf
+
+evas_image_loader_pdf_SOURCES = main.cpp
+evas_image_loader_pdf_CFLAGS =
+evas_image_loader_pdf_LDADD = @POPPLER_LIBS@ @EINA_LIBS@ @SHM_OPEN_LIBS@
+evas_image_loader_pdf_LDFLAGS =
diff --git a/src/bin/pdf/main.cpp b/src/bin/pdf/main.cpp
new file mode 100644
index 0000000..24017bb
--- /dev/null
+++ b/src/bin/pdf/main.cpp
@@ -0,0 +1,304 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include <GlobalParams.h>
+#include <PDFDoc.h>
+#include <ErrorCodes.h>
+#include <Page.h>
+#include <SplashOutputDev.h>
+#include <splash/SplashBitmap.h>
+
+#include <Eina.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;
+SplashOutputDev *output_dev;
+
+::Page *page;
+int width = 0;
+int height = 0;
+void *data;
+
+static int shm_fd = -1;
+static int shm_size = 0;
+static void *shm_addr = NULL;
+static char shmfile[1024] = "";
+
+static void
+shm_alloc(int dsize)
+{
+#ifdef HAVE_SHM_OPEN
+ srand(time(NULL));
+ do
+ {
+ snprintf(shmfile, sizeof(shmfile), "/evas-loader-xcf.%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);
+}
+
+static 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;
+ return;
+ }
+#endif
+ free(shm_addr);
+ shm_addr = NULL;
+ shm_fd = -1;
+}
+
+Eina_Bool poppler_init(const char *file, int page_nbr, double dpi, int size_w, int size_h)
+{
+ Object obj;
+ SplashColor white;
+
+ 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;
+
+ if (globalParams->getAntialias())
+ globalParams->setAntialias((char *)"yes");
+ if (globalParams->getVectorAntialias())
+ globalParams->setVectorAntialias((char *)"yes");
+
+ 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;
+
+ width = page->getMediaWidth();
+ height = page->getMediaHeight();
+
+ if ((size_w > 0) || (size_h > 0))
+ {
+ /* FIXME: tell poller to render at the new width and height
+ unsigned int w2 = width, h2 = height;
+ if (size_w > 0)
+ {
+ w2 = size_w;
+ h2 = (size_w * h) / w;
+ if ((size_h > 0) && (h2 > size_h))
+ {
+ unsigned int w3;
+ h2 = size_h;
+ w3 = (size_h * w) / h;
+ if (w3 > w2)
+ w2 = w3;
+ }
+ }
+ else if (size_h > 0)
+ {
+ h2 = size_h;
+ w2 = (size_h * w) / h;
+ }
+ width = w2;
+ height = h2;
+ */
+ }
+ else if (dpi > 0.0)
+ {
+ /* FIXME: tell poppler to render at this size
+ width = (width * dpi) / 72.0;
+ height = (height * dpi) / 72.0;
+ */
+ }
+
+ 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(double dpi, int size_w, int size_h)
+{
+ SplashOutputDev *output_dev;
+ SplashColor white;
+ SplashColorPtr color_ptr;
+
+ white[0] = 255;
+ white[1] = 255;
+ white[2] = 255;
+ white[3] = 255;
+
+ output_dev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, white);
+ if (!output_dev)
+ return;
+
+ output_dev->startDoc(pdfdoc->getXRef());
+
+ if (dpi <= 0.0) dpi = 72.0;
+
+ page->display(output_dev,
+ dpi, dpi, 0,
+ false, false, false,
+ pdfdoc->getCatalog());
+ color_ptr = output_dev->getBitmap()->getDataPtr();
+
+ shm_alloc(width * height * sizeof(DATA32));
+ if (!shm_addr)
+ goto del_outpput_dev;
+ data = shm_addr;
+ memcpy(data, color_ptr, width * height * sizeof(DATA32));
+
+ del_outpput_dev:
+ delete output_dev;
+}
+
+int
+main(int argc, char **argv)
+{
+ char *file;
+ int i;
+ int size_w = 0, size_h = 0;
+ int head_only = 0;
+ int page = 0;
+ double dpi = -1.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 = 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("poppler_file_init\n");
+ D("dpi....: %f\n", dpi);
+ D("page...: %d\n", page);
+
+ if (!poppler_init(file, page, dpi, size_w, size_h))
+ return -1;
+ D("poppler_file_init done\n");
+
+ if (!head_only)
+ {
+ poppler_load_image(dpi, size_w, size_h);
+ }
+
+ D("size...: %ix%i\n", width, height);
+ D("alpha..: 1\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");
+
+ poppler_shutdown();
+
+ return 0;
+}
diff --git a/src/bin/xcf/common.h b/src/bin/xcf/common.h
index a6de744..209c3c1 100644
--- a/src/bin/xcf/common.h
+++ b/src/bin/xcf/common.h
@@ -1,7 +1,9 @@
#ifndef __COMMON
#define __COMMON 1
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
#include <stdio.h>
#include <stdlib.h>