start adding poppler support

This commit is contained in:
John Cupitt 2016-02-07 23:33:43 +00:00
parent 41b41effde
commit 8da4e706dd
7 changed files with 273 additions and 21 deletions

View File

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

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
noinst_LTLIBRARIES = libforeign.la
libforeign_la_SOURCES = \
popplerload.c \
radiance.h \
radiance.c \
radload.c \

View File

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

View 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*/