support webp lossless encoding
This commit is contained in:
parent
ea3b2e3ef1
commit
3d14709bdb
@ -55,10 +55,13 @@ typedef size_t (*webp_encoder)( const uint8_t *rgb,
|
|||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
float quality_factor, uint8_t **output );
|
float quality_factor, uint8_t **output );
|
||||||
|
|
||||||
|
typedef size_t (*webp_encoder_lossless)( const uint8_t *rgb,
|
||||||
|
int width, int height, int stride, uint8_t **output );
|
||||||
|
|
||||||
int
|
int
|
||||||
vips__webp_write_file( VipsImage *in, const char *filename, int Q )
|
vips__webp_write_file( VipsImage *in, const char *filename,
|
||||||
|
int Q, gboolean lossless )
|
||||||
{
|
{
|
||||||
webp_encoder encoder;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -66,17 +69,39 @@ vips__webp_write_file( VipsImage *in, const char *filename, int Q )
|
|||||||
if( vips_image_wio_input( in ) )
|
if( vips_image_wio_input( in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( in->Bands == 4 )
|
if( lossless ) {
|
||||||
encoder = WebPEncodeRGBA;
|
webp_encoder_lossless encoder;
|
||||||
else
|
|
||||||
encoder = WebPEncodeRGB;
|
|
||||||
|
|
||||||
if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ),
|
if( in->Bands == 4 )
|
||||||
in->Xsize, in->Ysize,
|
encoder = WebPEncodeLosslessRGBA;
|
||||||
VIPS_IMAGE_SIZEOF_LINE( in ),
|
else
|
||||||
Q, &buffer )) ) {
|
encoder = WebPEncodeLosslessRGB;
|
||||||
vips_error( "vips2webp", "%s", _( "unable to encode" ) );
|
|
||||||
return( -1 );
|
if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ),
|
||||||
|
in->Xsize, in->Ysize,
|
||||||
|
VIPS_IMAGE_SIZEOF_LINE( in ),
|
||||||
|
&buffer )) ) {
|
||||||
|
vips_error( "vips2webp",
|
||||||
|
"%s", _( "unable to encode" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
webp_encoder encoder;
|
||||||
|
|
||||||
|
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 )) ) {
|
if( !(fp = vips__file_open_write( filename, FALSE )) ) {
|
||||||
@ -97,7 +122,8 @@ vips__webp_write_file( VipsImage *in, const char *filename, int Q )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen, int Q )
|
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
|
||||||
|
int Q, gboolean lossless )
|
||||||
{
|
{
|
||||||
webp_encoder encoder;
|
webp_encoder encoder;
|
||||||
|
|
||||||
|
@ -45,8 +45,10 @@ int vips__webp_read_file( const char *name, VipsImage *out );
|
|||||||
int vips__webp_read_buffer_header( void *buf, size_t len, VipsImage *out );
|
int vips__webp_read_buffer_header( void *buf, size_t len, VipsImage *out );
|
||||||
int vips__webp_read_buffer( void *buf, size_t len, VipsImage *out );
|
int vips__webp_read_buffer( void *buf, size_t len, VipsImage *out );
|
||||||
|
|
||||||
int vips__webp_write_file( VipsImage *out, const char *filename, int Q );
|
int vips__webp_write_file( VipsImage *out, const char *filename,
|
||||||
int vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len, int Q );
|
int Q, gboolean lossless );
|
||||||
|
int vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len,
|
||||||
|
int Q, gboolean lossless );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,10 @@ typedef struct _VipsForeignSaveWebp {
|
|||||||
*/
|
*/
|
||||||
int Q;
|
int Q;
|
||||||
|
|
||||||
|
/* Turn on lossless encode.
|
||||||
|
*/
|
||||||
|
gboolean lossless;
|
||||||
|
|
||||||
} VipsForeignSaveWebp;
|
} VipsForeignSaveWebp;
|
||||||
|
|
||||||
typedef VipsForeignSaveClass VipsForeignSaveWebpClass;
|
typedef VipsForeignSaveClass VipsForeignSaveWebpClass;
|
||||||
@ -95,6 +99,13 @@ vips_foreign_save_webp_class_init( VipsForeignSaveWebpClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsForeignSaveWebp, Q ),
|
G_STRUCT_OFFSET( VipsForeignSaveWebp, Q ),
|
||||||
1, 100, 75 );
|
1, 100, 75 );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( class, "lossless", 11,
|
||||||
|
_( "lossless" ),
|
||||||
|
_( "enable lossless compression" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignSaveWebp, lossless ),
|
||||||
|
FALSE );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -128,7 +139,8 @@ vips_foreign_save_webp_file_build( VipsObject *object )
|
|||||||
build( object ) )
|
build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips__webp_write_file( save->ready, file->filename, webp->Q ) )
|
if( vips__webp_write_file( save->ready, file->filename,
|
||||||
|
webp->Q, webp->lossless ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -192,7 +204,8 @@ vips_foreign_save_webp_buffer_build( VipsObject *object )
|
|||||||
build( object ) )
|
build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips__webp_write_buffer( save->ready, &obuf, &olen, webp->Q ) )
|
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
||||||
|
webp->Q, webp->lossless ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
area = vips_area_new_blob( (VipsCallbackFn) vips_free, obuf, olen );
|
area = vips_area_new_blob( (VipsCallbackFn) vips_free, obuf, olen );
|
||||||
@ -252,7 +265,8 @@ vips_foreign_save_webp_mime_build( VipsObject *object )
|
|||||||
build( object ) )
|
build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips__webp_write_buffer( save->ready, &obuf, &olen, webp->Q ) )
|
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
||||||
|
webp->Q, webp->lossless ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
printf( "Content-length: %zd\r\n", olen );
|
printf( "Content-length: %zd\r\n", olen );
|
||||||
|
Loading…
Reference in New Issue
Block a user