From dcd2dbb756e1a1c9d1877efb779640e23a8a2cfc Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 17 Jun 2013 09:41:22 +0100 Subject: [PATCH] vips_pngload_buffer() works fix a bug in vips_jpegload_buffer() too --- ChangeLog | 1 + TODO | 8 +++++++- libvips/foreign/foreign.c | 38 ++++++++++++++++++++++++-------------- libvips/foreign/pngload.c | 8 ++++---- libvips/foreign/vipspng.c | 14 +++++++++----- libvips/foreign/vipspng.h | 4 ++-- 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 853f6266..83a55e11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - add im_vips2dz(): run the deepzoom writer from vips7 - vips_magickload() has an option to read all images in a sequence - redo im_make_xy(), im_*eye(), im_zone*(), im_sines() as classes +- added vips_pngload_buffer() 12/3/13 started 7.33.0 - vipsthumbnail lets you specify the sharpening mask diff --git a/TODO b/TODO index 774afe5d..ddb7142c 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,3 @@ -- need png load from buffer? - could we support streaming read? how would it work? @@ -18,6 +17,13 @@ reader.kick end + looks ugly and stupid :( + + could maybe read from a socket? would we need to be able to pass file ids + in? can named sockets work like this? + + + diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 8ef04e46..6298d2d7 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1999,18 +1999,23 @@ vips_jpegsave_buffer( VipsImage *in, void **buf, size_t *len, ... ) VipsArea *area; int result; + area = NULL; + va_start( ap, len ); result = vips_call_split( "jpegsave_buffer", ap, in, &area ); va_end( ap ); - if( buf ) { - *buf = area->data; - area->free_fn = NULL; - } - if( buf ) - *len = area->length; + if( !result && + area ) { + if( buf ) { + *buf = area->data; + area->free_fn = NULL; + } + if( buf ) + *len = area->length; - vips_area_unref( area ); + vips_area_unref( area ); + } return( result ); } @@ -2341,18 +2346,23 @@ vips_pngsave_buffer( VipsImage *in, void **buf, size_t *len, ... ) VipsArea *area; int result; + area = NULL; + va_start( ap, len ); result = vips_call_split( "pngsave_buffer", ap, in, &area ); va_end( ap ); - if( buf ) { - *buf = area->data; - area->free_fn = NULL; - } - if( buf ) - *len = area->length; + if( !result && + area ) { + if( buf ) { + *buf = area->data; + area->free_fn = NULL; + } + if( buf ) + *len = area->length; - vips_area_unref( area ); + vips_area_unref( area ); + } return( result ); } diff --git a/libvips/foreign/pngload.c b/libvips/foreign/pngload.c index 97763eef..cf49b6dd 100644 --- a/libvips/foreign/pngload.c +++ b/libvips/foreign/pngload.c @@ -165,8 +165,8 @@ vips_foreign_load_png_buffer_header( VipsForeignLoad *load ) { VipsForeignLoadPngBuffer *png = (VipsForeignLoadPngBuffer *) load; - if( vips__png_header_buffer( load->out, - png->buf->data, png->buf->length ) ) + if( vips__png_header_buffer( png->buf->data, png->buf->length, + load->out ) ) return( -1 ); return( 0 ); @@ -177,8 +177,8 @@ vips_foreign_load_png_buffer_load( VipsForeignLoad *load ) { VipsForeignLoadPngBuffer *png = (VipsForeignLoadPngBuffer *) load; - if( vips__png_read_buffer( load->out, - png->buf->data, png->buf->length ) ) + if( vips__png_read_buffer( png->buf->data, png->buf->length, + load->real ) ) return( -1 ); return( 0 ); diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index ac39a7c4..54631e3d 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -501,7 +501,7 @@ vips__png_isinterlaced( const char *filename ) } static int -read_all( Read *read, VipsImage *out ) +png2vips_image( Read *read, VipsImage *out ) { int interlace_type = png_get_interlace_type( read->pPng, read->pInfo ); VipsImage **t = (VipsImage **) @@ -543,7 +543,7 @@ vips__png_read( const char *filename, VipsImage *out ) #endif /*DEBUG*/ if( !(read = read_new_filename( out, filename )) || - read_all( read, out ) ) + png2vips_image( read, out ) ) return( -1 ); #ifdef DEBUG @@ -567,6 +567,10 @@ vips_png_read_buffer( png_structp pPng, png_bytep data, png_size_t length ) { Read *read = png_get_io_ptr( pPng ); +#ifdef DEBUG + printf( "vips_png_read_buffer: read %zd bytes\n", length ); +#endif /*DEBUG*/ + if( read->read_pos + length > read->length ) png_error( pPng, "not enough data in buffer" ); @@ -596,7 +600,7 @@ read_new_buffer( VipsImage *out, char *buffer, size_t length ) } int -vips__png_header_buffer( VipsImage *out, char *buffer, size_t length ) +vips__png_header_buffer( char *buffer, size_t length, VipsImage *out ) { Read *read; @@ -608,12 +612,12 @@ vips__png_header_buffer( VipsImage *out, char *buffer, size_t length ) } int -vips__png_read_buffer( VipsImage *out, char *buffer, size_t length ) +vips__png_read_buffer( char *buffer, size_t length, VipsImage *out ) { Read *read; if( !(read = read_new_buffer( out, buffer, length )) || - read_all( read, out ) ) + png2vips_image( read, out ) ) return( -1 ); return( 0 ); diff --git a/libvips/foreign/vipspng.h b/libvips/foreign/vipspng.h index c28951c1..9922eecd 100644 --- a/libvips/foreign/vipspng.h +++ b/libvips/foreign/vipspng.h @@ -40,8 +40,8 @@ int vips__png_read( const char *name, VipsImage *out ); int vips__png_ispng( const char *filename ); gboolean vips__png_isinterlaced( const char *filename ); extern const char *vips__png_suffs[]; -int vips__png_read_buffer( VipsImage *out, char *buffer, size_t length ); -int vips__png_header_buffer( VipsImage *out, char *buffer, size_t length ); +int vips__png_read_buffer( char *buffer, size_t length, VipsImage *out ); +int vips__png_header_buffer( char *buffer, size_t length, VipsImage *out ); int vips__png_write( VipsImage *in, const char *filename, int compress, int interlace );