From 4a65af9196363fe95f1994fd976df4ced82d0528 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 6 Aug 2013 18:15:18 +0100 Subject: [PATCH] add save functions --- ChangeLog | 3 +- TODO | 4 +-- libvips/foreign/vips2webp.c | 57 +++++++++++++++++++++++++++++++++++-- libvips/foreign/webp2vips.c | 10 +++---- 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3e7d218..0dd82dbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,7 +7,8 @@ - added vips_error_freeze() / vips_error_thaw() - used freeze() / thaw() to stop file format sniffers logging spurious errors - vipsthumbnail uses embedded jpg thumbnails if it can -- added vips_webpload(), vips_webpload_buffer() +- added vips_webpload(), vips_webpload_buffer(), vips_webpsave(), + vips_webpsave_buffer(), vips_webpsave_mime() 3/7/13 started 7.34.2 - lower priority for Matlab load to reduce segvs from Mat_Open(), thanks diff --git a/TODO b/TODO index ab2c95a9..5a017acd 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,4 @@ -- support webp, see: - - https://github.com/jcupitt/libvips/issues/68 +- use mmap to read encoded webp image - rename vips_diag() as vips_info(), make it work like a log thing ... normally no output, can be turned on with a --vips-verbose flag diff --git a/libvips/foreign/vips2webp.c b/libvips/foreign/vips2webp.c index 5cfeec67..3c60f0c6 100644 --- a/libvips/foreign/vips2webp.c +++ b/libvips/foreign/vips2webp.c @@ -51,10 +51,47 @@ #include "webp.h" +typedef size_t (*webp_encoder)( const uint8_t *rgb, + int width, int height, int stride, + float quality_factor, uint8_t **output ); + int vips__webp_write_file( VipsImage *in, const char *filename, int Q ) { - printf( "vips__webp_write_file:\n" ); + webp_encoder encoder; + size_t len; + uint8_t *buffer; + FILE *fp; + + if( vips_image_wio_input( in ) ) + return( -1 ); + + if( in->Bands == 4 ) + encoder = WebPEncodeRGBA; + else + encoder = WebPEncodeRGB; + + if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ), + in->Xsize, in->Ysize, + VIPS_IMAGE_SIZEOF_LINE( in ), + Q, &buffer )) ) { + vips_error( "vips2webp", "%s", _( "unable to encode" ) ); + return( -1 ); + } + + if( !(fp = vips__file_open_write( filename, FALSE )) ) { + free( buffer ); + return( -1 ); + } + + if( vips__file_write( buffer, len, 1, fp ) ) { + fclose( fp ); + free( buffer ); + return( -1 ); + } + + fclose( fp ); + free( buffer ); return( 0 ); } @@ -62,7 +99,23 @@ vips__webp_write_file( VipsImage *in, const char *filename, int Q ) int vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen, int Q ) { - printf( "vips__webp_write_buffer:\n" ); + webp_encoder encoder; + + if( vips_image_wio_input( in ) ) + return( -1 ); + + if( in->Bands == 4 ) + encoder = WebPEncodeRGBA; + else + encoder = WebPEncodeRGB; + + if( !(*olen = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ), + in->Xsize, in->Ysize, + VIPS_IMAGE_SIZEOF_LINE( in ), + Q, (uint8_t **) obuf )) ) { + vips_error( "vips2webp", "%s", _( "unable to encode" ) ); + return( -1 ); + } return( 0 ); } diff --git a/libvips/foreign/webp2vips.c b/libvips/foreign/webp2vips.c index 1b2449ce..838ca88a 100644 --- a/libvips/foreign/webp2vips.c +++ b/libvips/foreign/webp2vips.c @@ -176,7 +176,7 @@ vips__webp_read_file_header( const char *filename, VipsImage *out ) return( 0 ); } -typedef uint8_t *(*webp_reader)( const uint8_t* data, size_t data_size, +typedef uint8_t *(*webp_decoder)( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride ); @@ -187,7 +187,7 @@ read_image( Read *read, VipsImage *out ) vips_object_local_array( VIPS_OBJECT( out ), 3 ); char *data; unsigned int len; - webp_reader reader; + webp_decoder decoder; /* libwebp makes streaming very hard. We have to read to a full memory * buffer, then copy to out. @@ -202,11 +202,11 @@ read_image( Read *read, VipsImage *out ) return( -1 ); if( t[0]->Bands == 3 ) - reader = WebPDecodeRGBInto; + decoder = WebPDecodeRGBInto; else - reader = WebPDecodeRGBAInto; + decoder = WebPDecodeRGBAInto; - if( !reader( (uint8_t *) data, len, + if( !decoder( (uint8_t *) data, len, VIPS_IMAGE_ADDR( t[0], 0, 0 ), VIPS_IMAGE_SIZEOF_IMAGE( t[0] ), VIPS_IMAGE_SIZEOF_LINE( t[0] ) ) ) {