switch svgload to random access

and fix up pdfload random access
This commit is contained in:
John Cupitt 2022-06-05 15:57:43 +01:00
parent 4fab8beae9
commit 586fb31550
3 changed files with 32 additions and 19 deletions

View File

@ -637,11 +637,13 @@ vips_foreign_load_pdf_load( VipsForeignLoad *load )
return( -1 ); return( -1 );
/* PDFium does not like rendering parts of pages :-( always render /* PDFium does not like rendering parts of pages :-( always render
* complete ones. * complete pages.
*/ */
if( vips_linecache( t[0], &t[1], if( vips_tilecache( t[0], &t[1],
"tile_height", pdf->pages[0].height, "tile_width", pdf->pages[0].width,
NULL ) ) "tile_height", pdf->pages[0].height,
"max_tiles", 1,
NULL ) )
return( -1 ); return( -1 );
if( vips_image_write( t[1], load->real ) ) if( vips_image_write( t[1], load->real ) )
return( -1 ); return( -1 );

View File

@ -76,6 +76,11 @@
#include <cairo.h> #include <cairo.h>
#include <poppler.h> #include <poppler.h>
/* Render PDFs with tiles this size. They need to be pretty big to limit
* overcomputation.
*/
#define TILE_SIZE (2000)
#define VIPS_TYPE_FOREIGN_LOAD_PDF (vips_foreign_load_pdf_get_type()) #define VIPS_TYPE_FOREIGN_LOAD_PDF (vips_foreign_load_pdf_get_type())
#define VIPS_FOREIGN_LOAD_PDF( obj ) \ #define VIPS_FOREIGN_LOAD_PDF( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), \
@ -495,14 +500,14 @@ vips_foreign_load_pdf_load( VipsForeignLoad *load )
g_signal_connect( t[0], "minimise", g_signal_connect( t[0], "minimise",
G_CALLBACK( vips_foreign_load_pdf_minimise ), pdf ); G_CALLBACK( vips_foreign_load_pdf_minimise ), pdf );
/* Very large strips to limit render calls per page.
*/
vips_foreign_load_pdf_set_image( pdf, t[0] ); vips_foreign_load_pdf_set_image( pdf, t[0] );
if( vips_image_generate( t[0], if( vips_image_generate( t[0],
NULL, vips_foreign_load_pdf_generate, NULL, pdf, NULL ) || NULL, vips_foreign_load_pdf_generate, NULL, pdf, NULL ) ||
vips_sequential( t[0], &t[1], vips_tilecache( t[0], &t[1],
"tile_height", VIPS_MIN( 5000, pdf->pages[0].height ), "tile_width", TILE_SIZE,
NULL ) || "tile_height", TILE_SIZE,
"max_tiles", 2 * (1 + t[0]->Xsize / TILE_SIZE),
NULL ) ||
vips_image_write( t[1], load->real ) ) vips_image_write( t[1], load->real ) )
return( -1 ); return( -1 );

View File

@ -26,6 +26,8 @@
* - allow utf-8 headers for svg detection * - allow utf-8 headers for svg detection
* 28/4/22 * 28/4/22
* - support rsvg_handle_get_intrinsic_size_in_pixels() * - support rsvg_handle_get_intrinsic_size_in_pixels()
* 5/6/22
* - allow random access
*/ */
/* /*
@ -79,6 +81,11 @@
#include <cairo.h> #include <cairo.h>
#include <librsvg/rsvg.h> #include <librsvg/rsvg.h>
/* Render SVGs with tiles this size. They need to be pretty big to limit
* overcomputation.
*/
#define TILE_SIZE (2000)
/* The <svg tag must appear within this many bytes of the start of the file. /* The <svg tag must appear within this many bytes of the start of the file.
*/ */
#define SVG_HEADER_SIZE (1000) #define SVG_HEADER_SIZE (1000)
@ -310,13 +317,15 @@ vips_foreign_load_svg_dispose( GObject *gobject )
static VipsForeignFlags static VipsForeignFlags
vips_foreign_load_svg_get_flags_filename( const char *filename ) vips_foreign_load_svg_get_flags_filename( const char *filename )
{ {
return( VIPS_FOREIGN_SEQUENTIAL ); /* We can render any part of the page on demand.
*/
return( VIPS_FOREIGN_PARTIAL );
} }
static VipsForeignFlags static VipsForeignFlags
vips_foreign_load_svg_get_flags( VipsForeignLoad *load ) vips_foreign_load_svg_get_flags( VipsForeignLoad *load )
{ {
return( VIPS_FOREIGN_SEQUENTIAL ); return( VIPS_FOREIGN_PARTIAL );
} }
#if LIBRSVG_CHECK_VERSION( 2, 52, 0 ) #if LIBRSVG_CHECK_VERSION( 2, 52, 0 )
@ -658,21 +667,18 @@ vips_foreign_load_svg_load( VipsForeignLoad *load )
VipsImage **t = (VipsImage **) VipsImage **t = (VipsImage **)
vips_object_local_array( (VipsObject *) load, 3 ); vips_object_local_array( (VipsObject *) load, 3 );
/* Make tiles 2000 pixels high to limit overcomputation. /* Enough tiles for two complete rows.
*/ */
t[0] = vips_image_new(); t[0] = vips_image_new();
if( vips_foreign_load_svg_parse( svg, t[0] ) || if( vips_foreign_load_svg_parse( svg, t[0] ) ||
vips_image_generate( t[0], NULL, vips_image_generate( t[0], NULL,
vips_foreign_load_svg_generate, NULL, svg, NULL ) || vips_foreign_load_svg_generate, NULL, svg, NULL ) ||
vips_tilecache( t[0], &t[1], vips_tilecache( t[0], &t[1],
"tile_width", t[0]->Xsize, "tile_width", TILE_SIZE,
"tile_height", 2000, "tile_height", TILE_SIZE,
"max_tiles", 1, "max_tiles", 2 * (1 + t[0]->Xsize / TILE_SIZE),
NULL ) || NULL ) ||
vips_sequential( t[1], &t[2], vips_image_write( t[1], load->real ) )
"tile_height", 2000,
NULL ) ||
vips_image_write( t[2], load->real ) )
return( -1 ); return( -1 );
return( 0 ); return( 0 );