start adding poppler support
This commit is contained in:
parent
41b41effde
commit
8da4e706dd
@ -2,6 +2,7 @@
|
||||
- add vips_reduce*() ... a fast path for bicubic downsize
|
||||
- vips_resize() and vips_similarity use it when they can
|
||||
- bicubic is better on 32-bit int images
|
||||
- add popplerload
|
||||
|
||||
27/1/16 started 8.2.3
|
||||
- fix a crash with SPARC byte-order labq vips images
|
||||
|
3
TODO
3
TODO
@ -1,3 +1,6 @@
|
||||
- vips_foreign_load_poppler_load needs to use generate to link
|
||||
poppler_page_render() to vips_region_prepare()
|
||||
|
||||
- new vips_reduce:
|
||||
|
||||
affine
|
||||
|
52
configure.ac
52
configure.ac
@ -537,31 +537,55 @@ if test x"$with_OpenEXR" != "xno"; then
|
||||
PKG_CHECK_MODULES(OPENEXR, OpenEXR >= 1.2.2,
|
||||
[AC_DEFINE(HAVE_OPENEXR,1,[define if you have OpenEXR >=1.2.2 installed.])
|
||||
with_OpenEXR=yes
|
||||
PACKAGES_USED="$PACKAGES_USED OpenEXR"],
|
||||
PACKAGES_USED="$PACKAGES_USED OpenEXR"
|
||||
],
|
||||
[AC_MSG_WARN([OpenEXR not found; disabling OpenEXR support])
|
||||
with_OpenEXR=no
|
||||
])
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
# poppler
|
||||
AC_ARG_WITH([poppler],
|
||||
AS_HELP_STRING([--without-poppler], [build without poppler (default: test)]))
|
||||
|
||||
if test x"$with_poppler" != x"no"; then
|
||||
PKG_CHECK_MODULES(POPPLER, [poppler-glib >= 0.30.0 cairo >= 1.2],
|
||||
[AC_DEFINE(HAVE_POPPLER,1,[define if you have poppler-glib >= 0.30.0 and cairo >= 1.2 installed.])
|
||||
with_poppler=yes
|
||||
PACKAGES_USED="$PACKAGES_USED poppler-glib cairo"
|
||||
],
|
||||
[AC_MSG_WARN([poppler-glib >= 0.40.0 or cairo >= 1.2 not found; disabling PDF load via poppler])
|
||||
with_poppler=no
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
# OpenSlide
|
||||
AC_ARG_WITH([openslide],
|
||||
AS_HELP_STRING([--without-openslide], [build without OpenSlide (default: test)]))
|
||||
AS_HELP_STRING([--without-openslide],
|
||||
[build without OpenSlide (default: test)])
|
||||
)
|
||||
|
||||
if test x"$with_openslide" != x"no"; then
|
||||
PKG_CHECK_MODULES(OPENSLIDE, [openslide >= 3.4.0],
|
||||
[AC_DEFINE(HAVE_OPENSLIDE_3_4,1,[define if you have OpenSlide >= 3.4.0 installed.])
|
||||
AC_DEFINE(HAVE_OPENSLIDE,1,[define if you have OpenSlide >= 3.3.0 installed.])
|
||||
with_openslide=yes
|
||||
PACKAGES_USED="$PACKAGES_USED openslide"],
|
||||
PACKAGES_USED="$PACKAGES_USED openslide"
|
||||
],
|
||||
[AC_MSG_NOTICE([OpenSlide >= 3.4.0 not found; checking for >= 3.3.0])
|
||||
PKG_CHECK_MODULES(OPENSLIDE, [openslide >= 3.3.0],
|
||||
[AC_DEFINE(HAVE_OPENSLIDE,1,[define if you have OpenSlide >= 3.3.0 installed.])
|
||||
with_openslide=yes
|
||||
PACKAGES_USED="$PACKAGES_USED openslide"],
|
||||
[AC_MSG_WARN([OpenSlide >= 3.3.0 not found; disabling virtual slide support])
|
||||
with_openslide=no
|
||||
])
|
||||
])
|
||||
[AC_DEFINE(HAVE_OPENSLIDE,1,[define if you have OpenSlide >= 3.3.0 installed.])
|
||||
with_openslide=yes
|
||||
PACKAGES_USED="$PACKAGES_USED openslide"
|
||||
],
|
||||
[AC_MSG_WARN([OpenSlide >= 3.3.0 not found; disabling virtual slide support])
|
||||
with_openslide=no
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
# matio
|
||||
@ -782,14 +806,14 @@ fi
|
||||
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS
|
||||
# sort includes to get longer, more specific dirs first
|
||||
# helps, for example, selecting graphicsmagick over imagemagick
|
||||
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $GSF_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $LIBWEBP_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS $LCMS_CFLAGS
|
||||
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $GSF_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $LIBWEBP_CFLAGS $POPPLER_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS $LCMS_CFLAGS
|
||||
do
|
||||
echo $i
|
||||
done | sort -ru`
|
||||
VIPS_CFLAGS=`echo $VIPS_CFLAGS`
|
||||
VIPS_CFLAGS="$VIPS_DEBUG_FLAGS $VIPS_CFLAGS"
|
||||
VIPS_INCLUDES="$PNG_INCLUDES $TIFF_INCLUDES $ZIP_INCLUDES $JPEG_INCLUDES"
|
||||
VIPS_LIBS="$MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $ZIP_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_LIBS $MATIO_LIBS $EXIF_LIBS -lm"
|
||||
VIPS_LIBS="$MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $ZIP_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $POPPLER_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_LIBS $MATIO_LIBS $EXIF_LIBS -lm"
|
||||
|
||||
AC_SUBST(VIPS_LIBDIR)
|
||||
|
||||
@ -875,6 +899,8 @@ file import with OpenEXR: $with_OpenEXR
|
||||
file import with OpenSlide: $with_openslide
|
||||
(requires openslide-3.3.0 or later)
|
||||
file import with matio: $with_matio
|
||||
PDF import with poppler-glib: $with_poppler
|
||||
(requires poppler-glib 0.30.0 or later)
|
||||
file import with cfitsio: $with_cfitsio
|
||||
file import/export with libwebp: $with_libwebp
|
||||
text rendering with pangoft2: $with_pangoft2
|
||||
|
@ -25,6 +25,7 @@ TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
|
||||
|
||||
SETUP_FILES = \
|
||||
$(content_files) \
|
||||
$(expand_content_files) \
|
||||
$(DOC_MAIN_SGML_FILE) \
|
||||
$(DOC_MODULE)-sections.txt \
|
||||
$(DOC_MODULE)-overrides.txt
|
||||
@ -86,7 +87,7 @@ GTK_DOC_V_SETUP_0=@echo " DOC Preparing build";
|
||||
|
||||
setup-build.stamp:
|
||||
-$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
|
||||
files=`echo $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types`; \
|
||||
files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \
|
||||
if test "x$$files" != "x" ; then \
|
||||
for file in $$files ; do \
|
||||
destdir=`dirname $(abs_builddir)/$$file`; \
|
||||
@ -118,7 +119,7 @@ scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB)
|
||||
$(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \
|
||||
scanobj_options=""; \
|
||||
gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \
|
||||
if test "$(?)" = "0"; then \
|
||||
if test "$$?" = "0"; then \
|
||||
if test "x$(V)" = "x1"; then \
|
||||
scanobj_options="--verbose"; \
|
||||
fi; \
|
||||
@ -162,17 +163,17 @@ GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V))
|
||||
GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY))
|
||||
GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references";
|
||||
|
||||
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
|
||||
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files)
|
||||
$(GTK_DOC_V_HTML)rm -rf html && mkdir html && \
|
||||
mkhtml_options=""; \
|
||||
gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \
|
||||
if test "$(?)" = "0"; then \
|
||||
if test "$$?" = "0"; then \
|
||||
if test "x$(V)" = "x1"; then \
|
||||
mkhtml_options="$$mkhtml_options --verbose"; \
|
||||
fi; \
|
||||
fi; \
|
||||
gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \
|
||||
if test "$(?)" = "0"; then \
|
||||
if test "$$?" = "0"; then \
|
||||
mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \
|
||||
fi; \
|
||||
cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
|
||||
@ -194,11 +195,11 @@ GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V))
|
||||
GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY))
|
||||
GTK_DOC_V_PDF_0=@echo " DOC Building PDF";
|
||||
|
||||
pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
|
||||
pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files)
|
||||
$(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \
|
||||
mkpdf_options=""; \
|
||||
gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \
|
||||
if test "$(?)" = "0"; then \
|
||||
if test "$$?" = "0"; then \
|
||||
if test "x$(V)" = "x1"; then \
|
||||
mkpdf_options="$$mkpdf_options --verbose"; \
|
||||
fi; \
|
||||
@ -223,12 +224,15 @@ clean-local:
|
||||
@if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \
|
||||
rm -f $(DOC_MODULE).types; \
|
||||
fi
|
||||
@if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \
|
||||
rm -f $(DOC_MODULE)-sections.txt; \
|
||||
fi
|
||||
|
||||
distclean-local:
|
||||
@rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \
|
||||
$(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
|
||||
@if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
|
||||
rm -f $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types; \
|
||||
rm -f $(SETUP_FILES) $(DOC_MODULE).types; \
|
||||
fi
|
||||
|
||||
maintainer-clean-local:
|
||||
|
@ -1,6 +1,7 @@
|
||||
noinst_LTLIBRARIES = libforeign.la
|
||||
|
||||
libforeign_la_SOURCES = \
|
||||
popplerload.c \
|
||||
radiance.h \
|
||||
radiance.c \
|
||||
radload.c \
|
||||
|
@ -1654,6 +1654,7 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_load_webp_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_webp_file_get_type( void );
|
||||
extern GType vips_foreign_save_webp_buffer_get_type( void );
|
||||
extern GType vips_foreign_load_poppler_get_type( void );
|
||||
|
||||
vips_foreign_load_rad_get_type();
|
||||
vips_foreign_save_rad_get_type();
|
||||
@ -1671,6 +1672,10 @@ vips_foreign_operation_init( void )
|
||||
vips_foreign_load_vips_get_type();
|
||||
vips_foreign_save_vips_get_type();
|
||||
|
||||
#ifdef HAVE_POPPLER
|
||||
vips_foreign_load_poppler_get_type();
|
||||
#endif /*HAVE_POPPLER*/
|
||||
|
||||
#ifdef HAVE_GSF
|
||||
vips_foreign_save_dz_get_type();
|
||||
#endif /*HAVE_GSF*/
|
||||
|
212
libvips/foreign/popplerload.c
Normal file
212
libvips/foreign/popplerload.c
Normal file
@ -0,0 +1,212 @@
|
||||
/* load PDF with libpoppler
|
||||
*
|
||||
* 7/2/16
|
||||
* - from openslideload.c
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_POPPLER
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <poppler.h>
|
||||
|
||||
typedef struct _VipsForeignLoadPoppler {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
/* Filename for load.
|
||||
*/
|
||||
char *filename;
|
||||
|
||||
/* Load this page.
|
||||
*/
|
||||
int page_no;
|
||||
|
||||
/* Render at this DPI.
|
||||
*/
|
||||
int dpi;
|
||||
|
||||
char *uri;
|
||||
PopplerDocument *doc;
|
||||
PopplerPage *page;
|
||||
|
||||
} VipsForeignLoadPoppler;
|
||||
|
||||
typedef VipsForeignLoadClass VipsForeignLoadPopplerClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadPoppler, vips_foreign_load_poppler,
|
||||
VIPS_TYPE_FOREIGN_LOAD );
|
||||
|
||||
static void
|
||||
vips_foreign_load_poppler_dispose( GObject *gobject )
|
||||
{
|
||||
VipsForeignLoadPoppler *poppler = (VipsForeignLoadPoppler *) gobject;
|
||||
|
||||
VIPS_FREE( poppler->uri );
|
||||
VIPS_UNREF( poppler->page );
|
||||
VIPS_UNREF( poppler->doc );
|
||||
|
||||
G_OBJECT_CLASS( vips_foreign_load_poppler_parent_class )->
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_poppler_get_flags_filename( const char *filename )
|
||||
{
|
||||
/* We can render any part of the page on demand.
|
||||
*/
|
||||
return( VIPS_FOREIGN_PARTIAL );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_poppler_get_flags( VipsForeignLoad *load )
|
||||
{
|
||||
return( VIPS_FOREIGN_PARTIAL );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_poppler_header( VipsForeignLoad *load )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( load );
|
||||
VipsForeignLoadPoppler *poppler = (VipsForeignLoadPoppler *) load;
|
||||
|
||||
GError *error = NULL;
|
||||
double width;
|
||||
double height;
|
||||
|
||||
poppler->uri = g_strdup_printf( "file://%s", poppler->filename );
|
||||
|
||||
if( !(poppler->doc = poppler_document_new_from_file(
|
||||
poppler->uri, NULL, &error )) ) {
|
||||
vips_g_error( &error );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( !(poppler->page = poppler_document_get_page( poppler->doc,
|
||||
poppler->page_no )) ) {
|
||||
vips_error( class->nickname,
|
||||
_( "unable to load page %d" ), poppler->page_no );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
poppler_page_get_size( poppler->page, &width, &height );
|
||||
|
||||
vips_image_init_fields( load->out, width, height, 3, VIPS_FORMAT_UCHAR,
|
||||
VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, 1.0, 1.0 );
|
||||
|
||||
VIPS_SETSTR( load->out->filename, poppler->filename );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_poppler_load( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadPoppler *poppler = (VipsForeignLoadPoppler *) load;
|
||||
|
||||
cairo_t *cr;
|
||||
|
||||
poppler_page_render( poppler->page, cr );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static const char *vips_foreign_poppler_suffs[] = {
|
||||
".pdf",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
vips_foreign_load_poppler_class_init( VipsForeignLoadPopplerClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_foreign_load_poppler_dispose;
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "popplerload";
|
||||
object_class->description = _( "load PDF with poppler" );
|
||||
|
||||
foreign_class->suffs = vips_foreign_poppler_suffs;
|
||||
|
||||
load_class->get_flags_filename =
|
||||
vips_foreign_load_poppler_get_flags_filename;
|
||||
load_class->get_flags = vips_foreign_load_poppler_get_flags;
|
||||
load_class->header = vips_foreign_load_poppler_header;
|
||||
load_class->load = vips_foreign_load_poppler_load;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadPoppler, filename ),
|
||||
NULL );
|
||||
|
||||
VIPS_ARG_INT( class, "page", 10,
|
||||
_( "Page" ),
|
||||
_( "Load this page from the file" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadPoppler, page_no ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "dpi", 10,
|
||||
_( "DPI" ),
|
||||
_( "Render at this DPI" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadPoppler, dpi ),
|
||||
1, 100000, 72 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_poppler_init( VipsForeignLoadPoppler *poppler )
|
||||
{
|
||||
}
|
||||
|
||||
#endif /*HAVE_POPPLER*/
|
Loading…
Reference in New Issue
Block a user