forked from enlightenment/efl
Add PDF loader (with some help from raster)
SVN revision: 59338
This commit is contained in:
parent
476c349d86
commit
110a75531d
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
Modules to add:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
[x] XCF
|
||||||
|
[x] PDF
|
||||||
|
[ ] PS
|
||||||
|
[ ] DVI
|
||||||
|
[ ] Djvu
|
|
@ -28,11 +28,6 @@ AC_CONFIG_HEADERS([config.h])
|
||||||
AM_INIT_AUTOMAKE([1.6 dist-bzip2])
|
AM_INIT_AUTOMAKE([1.6 dist-bzip2])
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
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])])
|
m4_ifdef([v_rev], , [m4_define([v_rev], [0])])
|
||||||
|
@ -54,8 +49,10 @@ AC_SUBST(VMAJ)
|
||||||
|
|
||||||
AC_CANONICAL_BUILD
|
AC_CANONICAL_BUILD
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_C_BIGENDIAN
|
|
||||||
|
### Checks for libraries
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
AC_PROG_CXX
|
||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
|
|
||||||
### Checks for libraries
|
### Checks for libraries
|
||||||
|
@ -63,14 +60,16 @@ PKG_PROG_PKG_CONFIG
|
||||||
# Eina library
|
# Eina library
|
||||||
PKG_CHECK_MODULES(EINA, [eina >= 1.0.0])
|
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
|
### Checks for header files
|
||||||
|
|
||||||
AC_CHECK_HEADER([zlib.h],
|
AC_CHECK_HEADER([zlib.h],
|
||||||
[dummy="yes"],
|
[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_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=""
|
SHM_OPEN_LIBS=""
|
||||||
AC_MSG_CHECKING([whether shm_open() is present])
|
AC_MSG_CHECKING([whether shm_open() is present])
|
||||||
LIBS_save=${LIBS}
|
LIBS_save=${LIBS}
|
||||||
|
@ -102,15 +101,44 @@ AM_PROG_CC_C_O
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
AC_PROG_CC_STDC
|
AC_PROG_CC_STDC
|
||||||
|
AC_C_BIGENDIAN
|
||||||
AC_C___ATTRIBUTE__
|
AC_C___ATTRIBUTE__
|
||||||
|
|
||||||
### Checks for library functions
|
### Checks for library functions
|
||||||
AC_ISC_POSIX
|
AC_ISC_POSIX
|
||||||
AC_FUNC_ALLOCA
|
|
||||||
|
|
||||||
AC_OUTPUT([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/bin/Makefile
|
src/bin/Makefile
|
||||||
src/bin/xcf/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
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
MAINTAINERCLEANFILES = Makefile.in
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
SUBDIRS = xcf
|
SUBDIRS = xcf
|
||||||
|
|
||||||
|
if HAVE_PDF
|
||||||
|
SUBDIRS += pdf
|
||||||
|
endif
|
||||||
|
|
|
@ -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 =
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
#ifndef __COMMON
|
#ifndef __COMMON
|
||||||
#define __COMMON 1
|
#define __COMMON 1
|
||||||
|
|
||||||
#include "config.h"
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
Loading…
Reference in New Issue