polishing

This commit is contained in:
John Cupitt 2016-11-08 14:42:54 +00:00
parent b56b888bf0
commit d5934d606a
7 changed files with 74 additions and 52 deletions

13
TODO
View File

@ -1,18 +1,5 @@
- test with libwebp 0.3, the earliest that supports libwebpmux
test with ubuntu ... seems to have libwebpmux2
test webp metadata read and write
webpsave should support strip
update docs
need to check for >4gb overflow ... use guint64 for all size calculations
webpsave needs hooking up to exif.c
- not sure about utf8 error messages on win

View File

@ -220,11 +220,13 @@ int vips__webp_read_buffer( const void *buf, size_t len,
int vips__webp_write_file( VipsImage *out, const char *filename,
int Q, gboolean lossless, VipsForeignWebpPreset preset,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q );
int alpha_q,
gboolean strip );
int vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len,
int Q, gboolean lossless, VipsForeignWebpPreset preset,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q );
int alpha_q,
gboolean strip );
int vips__openslide_isslide( const char *filename );
int vips__openslide_read_header( const char *filename, VipsImage *out,

View File

@ -89,8 +89,12 @@ get_preset( VipsForeignWebpPreset preset )
typedef struct {
uint8_t *mem;
size_t size;
size_t max_size;
/* We want to be able to detect >4gb even on machines that have size_t
* as uint32.
*/
guint64 size;
guint64 max_size;
} VipsWebPWriter;
static void
@ -103,21 +107,33 @@ vips_webp_writer_init( VipsWebPWriter *writer )
static int
vips_webp_writer_append( VipsWebPWriter *writer,
const uint8_t *data, size_t data_size )
const uint8_t *data, guint64 data_size )
{
size_t next_size;
guint64 next_size;
next_size = writer->size + data_size;
if( next_size > writer->max_size ) {
uint8_t *new_mem;
const size_t next_max_size =
const guint64 next_max_size =
VIPS_MAX( 8192, VIPS_MAX( next_size,
writer->max_size * 2 ) );
if( !(new_mem = (uint8_t *)
g_try_realloc( writer->mem, next_max_size )) )
/* We should let it creep up to 4gb rather than just
* blocking when max goes over, but no one will make a >2gb
* webp image.
*/
if( next_max_size > UINT_MAX ) {
vips_error( "webp",
"%s", _( "output webp image too large" ) );
return( 0 );
}
if( !(new_mem = (uint8_t *)
g_try_realloc( writer->mem, next_max_size )) ) {
vips_error( "webp", "%s", _( "out of memory" ) );
return( 0 );
}
writer->mem = new_mem;
writer->max_size = next_max_size;
@ -167,7 +183,7 @@ vips_webp_writer_appendcc( VipsWebPWriter *writer, const char buf[4] )
static gboolean
vips_webp_writer_appendc( VipsWebPWriter *writer,
const char fourcc[4], const uint8_t *data, size_t data_size )
const char fourcc[4], const uint8_t *data, guint64 data_size )
{
const int zero = 0;
gboolean need_padding = (data_size & 1) != 0;
@ -284,7 +300,7 @@ static int
vips_webp_add_chunk( VipsWebPWriter *writer, VipsImage *image,
const char *vips, const char webp[4] )
{
if( vips_image_get_typeof( image, vips) ) {
if( vips_image_get_typeof( image, vips ) ) {
void *data;
size_t length;
@ -345,6 +361,11 @@ vips_webp_add_metadata( VipsWebPWriter *writer, VipsImage *image )
guint64 new_size;
VipsWebPWriter new;
/* Rebuild the EXIF block, if any, ready for writing.
*/
if( vips__exif_update( image ) )
return( -1 );
/* We have to find the size of the block we will write before we can
* start to write it.
*/
@ -474,7 +495,7 @@ int
vips__webp_write_file( VipsImage *in, const char *filename,
int Q, gboolean lossless, VipsForeignWebpPreset preset,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q )
int alpha_q, gboolean strip )
{
WebPPicture pic;
VipsWebPWriter writer;
@ -499,7 +520,8 @@ vips__webp_write_file( VipsImage *in, const char *filename,
WebPPictureFree( &pic );
if( vips_webp_add_metadata( &writer, in ) ) {
if( !strip &&
vips_webp_add_metadata( &writer, in ) ) {
vips_webp_writer_unset( &writer );
return( -1 );
}
@ -525,7 +547,7 @@ int
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
int Q, gboolean lossless, VipsForeignWebpPreset preset,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q )
int alpha_q, gboolean strip )
{
WebPPicture pic;
VipsWebPWriter writer;
@ -549,7 +571,8 @@ vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
WebPPictureFree( &pic );
if( vips_webp_add_metadata( &writer, in ) ) {
if( !strip &&
vips_webp_add_metadata( &writer, in ) ) {
vips_webp_writer_unset( &writer );
return( -1 );
}

View File

@ -236,7 +236,7 @@ read_header( Read *read, VipsImage *out )
WebPMux *mux;
int i;
/* We have to parse the whole file again to get the ICC profile out.
/* We have to parse the whole file again to get the metadata out.
*/
bitstream.bytes = read->data;
bitstream.size = read->length;
@ -245,7 +245,7 @@ read_header( Read *read, VipsImage *out )
return( -1 );
}
for( i = 0; i < VIPS_NUMBER( vips__webp_names ); i++ ) {
for( i = 0; i < vips__n_webp_names; i++ ) {
const char *vips = vips__webp_names[i].vips;
const char *webp = vips__webp_names[i].webp;

View File

@ -293,6 +293,9 @@ vips_foreign_load_webp_buffer_init( VipsForeignLoadWebpBuffer *buffer )
*
* Use @shrink to specify a shrink-on-load factor.
*
* If libwebpmux is available, image metadata is also read. The loader supports
* ICC, EXIF and XMP metadata.
*
* See also: vips_image_new_from_file().
*
* Returns: 0 on success, -1 on error.

View File

@ -191,7 +191,7 @@ vips_foreign_save_webp_file_build( VipsObject *object )
if( vips__webp_write_file( save->ready, file->filename,
webp->Q, webp->lossless, webp->preset,
webp->smart_subsample, webp->near_lossless,
webp->alpha_q ) )
webp->alpha_q, save->strip ) )
return( -1 );
return( 0 );
@ -255,7 +255,7 @@ vips_foreign_save_webp_buffer_build( VipsObject *object )
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
webp->Q, webp->lossless, webp->preset,
webp->smart_subsample, webp->near_lossless,
webp->alpha_q ) )
webp->alpha_q, save->strip ) )
return( -1 );
/* obuf is a g_free() buffer, not vips_free().
@ -320,7 +320,7 @@ vips_foreign_save_webp_mime_build( VipsObject *object )
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
webp->Q, webp->lossless, webp->preset,
webp->smart_subsample, webp->near_lossless,
webp->alpha_q ) )
webp->alpha_q, save->strip ) )
return( -1 );
printf( "Content-length: %zu\r\n", olen );
@ -363,12 +363,13 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime )
*
* Optional arguments:
*
* * @Q: %gint quality factor
* * @lossless: %gboolean enables lossless compression
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
* * @smart_subsample: %gboolean enables high quality chroma subsampling
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
* * @alpha_q: %gint set alpha quality in lossless mode
* * @Q: %gint, quality factor
* * @lossless: %gboolean, enables lossless compression
* * @preset: #VipsForeignWebpPreset, choose lossy compression preset
* * @smart_subsample: %gboolean, enables high quality chroma subsampling
* * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q)
* * @alpha_q: %gint, set alpha quality in lossless mode
* * @strip: %gboolean, remove all metadata from image
*
* Write an image to a file in WebP format.
*
@ -386,6 +387,9 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime )
* with @Q 80, 60, 40 or 20 to apply increasing amounts of preprocessing
* which improves the near-lossless compression ratio by up to 50%.
*
* The writer will attach ICC, EXIF and XMP metadata, unless @strip is set to
* %TRUE.
*
* See also: vips_webpload(), vips_image_write_to_file().
*
* Returns: 0 on success, -1 on error.
@ -412,12 +416,13 @@ vips_webpsave( VipsImage *in, const char *filename, ... )
*
* Optional arguments:
*
* * @Q: %gint quality factor
* * @lossless: %gboolean enables lossless compression
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
* * @smart_subsample: %gboolean enables high quality chroma subsampling
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
* * @alpha_q: %gint set alpha quality in lossless mode
* * @Q: %gint, quality factor
* * @lossless: %gboolean, enables lossless compression
* * @preset: #VipsForeignWebpPreset, choose lossy compression preset
* * @smart_subsample: %gboolean, enables high quality chroma subsampling
* * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q)
* * @alpha_q: %gint, set alpha quality in lossless mode
* * @strip: %gboolean, remove all metadata from image
*
* As vips_webpsave(), but save to a memory buffer.
*
@ -464,12 +469,13 @@ vips_webpsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
*
* Optional arguments:
*
* * @Q: %gint quality factor
* * @lossless: %gboolean enables lossless compression
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
* * @smart_subsample: %gboolean enables high quality chroma subsampling
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
* * @alpha_q: %gint set alpha quality in lossless mode
* * @Q: %gint, quality factor
* * @lossless: %gboolean, enables lossless compression
* * @preset: #VipsForeignWebpPreset, choose lossy compression preset
* * @smart_subsample: %gboolean, enables high quality chroma subsampling
* * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q)
* * @alpha_q: %gint, set alpha quality in lossless mode
* * @strip: %gboolean, remove all metadata from image
*
* As vips_webpsave(), but save as a mime webp on stdout.
*

View File

@ -49,7 +49,8 @@ save_load() {
fi
if ! $vips copy $tmp/t1.$format $tmp/back.v ; then
echo "read from $out failed"
echo "read from $tmp/t1.format failed"
echo " (was written by $vips copy $in $tmp/t1.$format$mode)"
exit 1
fi
}