Merge branch 'master' of github.com:libvips/libvips
This commit is contained in:
commit
11818e1caf
@ -1013,6 +1013,14 @@ if test x"$with_rsvg" != x"no"; then
|
|||||||
AC_DEFINE(HAVE_RSVG,1,[define if you have librsvg-2.0 >= 2.40.3 and cairo >= 1.2 installed.])
|
AC_DEFINE(HAVE_RSVG,1,[define if you have librsvg-2.0 >= 2.40.3 and cairo >= 1.2 installed.])
|
||||||
with_rsvg=yes
|
with_rsvg=yes
|
||||||
PACKAGES_USED="$PACKAGES_USED librsvg-2.0 cairo"
|
PACKAGES_USED="$PACKAGES_USED librsvg-2.0 cairo"
|
||||||
|
|
||||||
|
# 2.46 for rsvg_handle_render_document
|
||||||
|
PKG_CHECK_MODULES(RSVG_HANDLE_RENDER_DOCUMENT, librsvg-2.0 >= 2.46,
|
||||||
|
[AC_DEFINE(HAVE_RSVG_HANDLE_RENDER_DOCUMENT,1,[define if your librsvg has rsvg_handle_render_document().])
|
||||||
|
],
|
||||||
|
[:
|
||||||
|
]
|
||||||
|
)
|
||||||
], [
|
], [
|
||||||
AC_MSG_WARN([librsvg-2.0 >= 2.40.3 or cairo >= 1.2 not found; disabling SVG load via rsvg])
|
AC_MSG_WARN([librsvg-2.0 >= 2.40.3 or cairo >= 1.2 not found; disabling SVG load via rsvg])
|
||||||
with_rsvg=no
|
with_rsvg=no
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
* - requires us to use the gio API to librsvg
|
* - requires us to use the gio API to librsvg
|
||||||
* 11/9/19
|
* 11/9/19
|
||||||
* - rework as a sequential loader to reduce overcomputation
|
* - rework as a sequential loader to reduce overcomputation
|
||||||
|
* 11/6/21
|
||||||
|
* - switch to rsvg_handle_render_document()
|
||||||
|
* - librsvg can no longer render very large images :(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -76,10 +79,6 @@
|
|||||||
*/
|
*/
|
||||||
#define SVG_HEADER_SIZE (1000)
|
#define SVG_HEADER_SIZE (1000)
|
||||||
|
|
||||||
/* The maximum pixel width librsvg is able to render.
|
|
||||||
*/
|
|
||||||
#define RSVG_MAX_WIDTH (32767)
|
|
||||||
|
|
||||||
/* A handy #define for we-will-handle-svgz.
|
/* A handy #define for we-will-handle-svgz.
|
||||||
*/
|
*/
|
||||||
#if LIBRSVG_CHECK_FEATURE(SVGZ) && defined(HAVE_ZLIB)
|
#if LIBRSVG_CHECK_FEATURE(SVGZ) && defined(HAVE_ZLIB)
|
||||||
@ -323,9 +322,9 @@ static int
|
|||||||
vips_foreign_load_svg_generate( VipsRegion *or,
|
vips_foreign_load_svg_generate( VipsRegion *or,
|
||||||
void *seq, void *a, void *b, gboolean *stop )
|
void *seq, void *a, void *b, gboolean *stop )
|
||||||
{
|
{
|
||||||
VipsForeignLoadSvg *svg = (VipsForeignLoadSvg *) a;
|
const VipsForeignLoadSvg *svg = (VipsForeignLoadSvg *) a;
|
||||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( svg );
|
const VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( svg );
|
||||||
VipsRect *r = &or->valid;
|
const VipsRect *r = &or->valid;
|
||||||
|
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
@ -349,13 +348,36 @@ vips_foreign_load_svg_generate( VipsRegion *or,
|
|||||||
cr = cairo_create( surface );
|
cr = cairo_create( surface );
|
||||||
cairo_surface_destroy( surface );
|
cairo_surface_destroy( surface );
|
||||||
|
|
||||||
|
/* rsvg is single-threaded, but we don't need to lock since we're
|
||||||
|
* running inside a non-threaded tilecache.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_RSVG_HANDLE_RENDER_DOCUMENT
|
||||||
|
{
|
||||||
|
RsvgRectangle viewport;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
cairo_translate( cr, -r->left, -r->top );
|
||||||
|
viewport.x = 0;
|
||||||
|
viewport.y = 0;
|
||||||
|
viewport.width = or->im->Xsize;
|
||||||
|
viewport.height = or->im->Ysize;
|
||||||
|
|
||||||
|
if( !rsvg_handle_render_document( svg->page, cr, &viewport, &error ) ) {
|
||||||
|
cairo_destroy( cr );
|
||||||
|
vips_operation_invalidate( VIPS_OPERATION( svg ) );
|
||||||
|
vips_error( class->nickname,
|
||||||
|
"%s", _( "SVG rendering failed" ) );
|
||||||
|
vips_g_error( &error );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_destroy( cr );
|
||||||
|
}
|
||||||
|
#else /*!HAVE_RSVG_HANDLE_RENDER_DOCUMENT*/
|
||||||
cairo_scale( cr, svg->cairo_scale, svg->cairo_scale );
|
cairo_scale( cr, svg->cairo_scale, svg->cairo_scale );
|
||||||
cairo_translate( cr, -r->left / svg->cairo_scale,
|
cairo_translate( cr, -r->left / svg->cairo_scale,
|
||||||
-r->top / svg->cairo_scale );
|
-r->top / svg->cairo_scale );
|
||||||
|
|
||||||
/* rsvg is single-threaded, but we don't need to lock since we're
|
|
||||||
* running inside a non-threaded tilecache.
|
|
||||||
*/
|
|
||||||
if( !rsvg_handle_render_cairo( svg->page, cr ) ) {
|
if( !rsvg_handle_render_cairo( svg->page, cr ) ) {
|
||||||
cairo_destroy( cr );
|
cairo_destroy( cr );
|
||||||
vips_operation_invalidate( VIPS_OPERATION( svg ) );
|
vips_operation_invalidate( VIPS_OPERATION( svg ) );
|
||||||
@ -365,6 +387,7 @@ vips_foreign_load_svg_generate( VipsRegion *or,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cairo_destroy( cr );
|
cairo_destroy( cr );
|
||||||
|
#endif /*HAVE_RSVG_HANDLE_RENDER_DOCUMENT*/
|
||||||
|
|
||||||
/* Cairo makes pre-multipled BRGA -- we must byteswap and unpremultiply.
|
/* Cairo makes pre-multipled BRGA -- we must byteswap and unpremultiply.
|
||||||
*/
|
*/
|
||||||
@ -383,21 +406,14 @@ 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 );
|
||||||
|
|
||||||
/* librsvg starts to fail if any axis in a single render call is over
|
/* Make tiles 2000 pixels high to limit overcomputation.
|
||||||
* RSVG_MAX_WIDTH pixels. vips_sequential() will use a tilecache where
|
|
||||||
* each tile is a strip the width of the image and (in this case)
|
|
||||||
* 2000 pixels high. To be able to render images wider than
|
|
||||||
* RSVG_MAX_WIDTH pixels, we need to chop these strips up.
|
|
||||||
* We use a small tilecache between the seq and our gen to do this.
|
|
||||||
*
|
|
||||||
* Make tiles 2000 pixels high to limit overcomputation.
|
|
||||||
*/
|
*/
|
||||||
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", VIPS_MIN( t[0]->Xsize, RSVG_MAX_WIDTH ),
|
"tile_width", t[0]->Xsize,
|
||||||
"tile_height", 2000,
|
"tile_height", 2000,
|
||||||
"max_tiles", 1,
|
"max_tiles", 1,
|
||||||
NULL ) ||
|
NULL ) ||
|
||||||
|
@ -699,6 +699,12 @@ int vips_jxlload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
|||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_jxlload( const char *filename, VipsImage **out, ... )
|
int vips_jxlload( const char *filename, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
int vips_jxlsave( VipsImage *in, const char *filename, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
int vips_jxlsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
int vips_jxlsave_target( VipsImage *in, VipsTarget *target, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VipsForeignDzLayout:
|
* VipsForeignDzLayout:
|
||||||
|
Loading…
Reference in New Issue
Block a user