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])
|
||||
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
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
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
|
||||
#define __COMMON 1
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
Loading…
Reference in New Issue