polishing
This commit is contained in:
parent
b56b888bf0
commit
d5934d606a
13
TODO
13
TODO
@ -1,18 +1,5 @@
|
|||||||
- test with libwebp 0.3, the earliest that supports libwebpmux
|
- 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
|
- not sure about utf8 error messages on win
|
||||||
|
|
||||||
|
@ -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 vips__webp_write_file( VipsImage *out, const char *filename,
|
||||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||||
gboolean smart_subsample, gboolean near_lossless,
|
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 vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len,
|
||||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||||
gboolean smart_subsample, gboolean near_lossless,
|
gboolean smart_subsample, gboolean near_lossless,
|
||||||
int alpha_q );
|
int alpha_q,
|
||||||
|
gboolean strip );
|
||||||
|
|
||||||
int vips__openslide_isslide( const char *filename );
|
int vips__openslide_isslide( const char *filename );
|
||||||
int vips__openslide_read_header( const char *filename, VipsImage *out,
|
int vips__openslide_read_header( const char *filename, VipsImage *out,
|
||||||
|
@ -89,8 +89,12 @@ get_preset( VipsForeignWebpPreset preset )
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *mem;
|
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;
|
} VipsWebPWriter;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -103,21 +107,33 @@ vips_webp_writer_init( VipsWebPWriter *writer )
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
vips_webp_writer_append( VipsWebPWriter *writer,
|
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;
|
next_size = writer->size + data_size;
|
||||||
|
|
||||||
if( next_size > writer->max_size ) {
|
if( next_size > writer->max_size ) {
|
||||||
uint8_t *new_mem;
|
uint8_t *new_mem;
|
||||||
const size_t next_max_size =
|
const guint64 next_max_size =
|
||||||
VIPS_MAX( 8192, VIPS_MAX( next_size,
|
VIPS_MAX( 8192, VIPS_MAX( next_size,
|
||||||
writer->max_size * 2 ) );
|
writer->max_size * 2 ) );
|
||||||
|
|
||||||
if( !(new_mem = (uint8_t *)
|
/* We should let it creep up to 4gb rather than just
|
||||||
g_try_realloc( writer->mem, next_max_size )) )
|
* 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 );
|
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->mem = new_mem;
|
||||||
writer->max_size = next_max_size;
|
writer->max_size = next_max_size;
|
||||||
@ -167,7 +183,7 @@ vips_webp_writer_appendcc( VipsWebPWriter *writer, const char buf[4] )
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
vips_webp_writer_appendc( VipsWebPWriter *writer,
|
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;
|
const int zero = 0;
|
||||||
gboolean need_padding = (data_size & 1) != 0;
|
gboolean need_padding = (data_size & 1) != 0;
|
||||||
@ -284,7 +300,7 @@ static int
|
|||||||
vips_webp_add_chunk( VipsWebPWriter *writer, VipsImage *image,
|
vips_webp_add_chunk( VipsWebPWriter *writer, VipsImage *image,
|
||||||
const char *vips, const char webp[4] )
|
const char *vips, const char webp[4] )
|
||||||
{
|
{
|
||||||
if( vips_image_get_typeof( image, vips) ) {
|
if( vips_image_get_typeof( image, vips ) ) {
|
||||||
void *data;
|
void *data;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
@ -345,6 +361,11 @@ vips_webp_add_metadata( VipsWebPWriter *writer, VipsImage *image )
|
|||||||
guint64 new_size;
|
guint64 new_size;
|
||||||
VipsWebPWriter new;
|
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
|
/* We have to find the size of the block we will write before we can
|
||||||
* start to write it.
|
* start to write it.
|
||||||
*/
|
*/
|
||||||
@ -474,7 +495,7 @@ int
|
|||||||
vips__webp_write_file( VipsImage *in, const char *filename,
|
vips__webp_write_file( VipsImage *in, const char *filename,
|
||||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||||
gboolean smart_subsample, gboolean near_lossless,
|
gboolean smart_subsample, gboolean near_lossless,
|
||||||
int alpha_q )
|
int alpha_q, gboolean strip )
|
||||||
{
|
{
|
||||||
WebPPicture pic;
|
WebPPicture pic;
|
||||||
VipsWebPWriter writer;
|
VipsWebPWriter writer;
|
||||||
@ -499,7 +520,8 @@ vips__webp_write_file( VipsImage *in, const char *filename,
|
|||||||
|
|
||||||
WebPPictureFree( &pic );
|
WebPPictureFree( &pic );
|
||||||
|
|
||||||
if( vips_webp_add_metadata( &writer, in ) ) {
|
if( !strip &&
|
||||||
|
vips_webp_add_metadata( &writer, in ) ) {
|
||||||
vips_webp_writer_unset( &writer );
|
vips_webp_writer_unset( &writer );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@ -525,7 +547,7 @@ int
|
|||||||
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
|
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
|
||||||
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
int Q, gboolean lossless, VipsForeignWebpPreset preset,
|
||||||
gboolean smart_subsample, gboolean near_lossless,
|
gboolean smart_subsample, gboolean near_lossless,
|
||||||
int alpha_q )
|
int alpha_q, gboolean strip )
|
||||||
{
|
{
|
||||||
WebPPicture pic;
|
WebPPicture pic;
|
||||||
VipsWebPWriter writer;
|
VipsWebPWriter writer;
|
||||||
@ -549,7 +571,8 @@ vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
|
|||||||
|
|
||||||
WebPPictureFree( &pic );
|
WebPPictureFree( &pic );
|
||||||
|
|
||||||
if( vips_webp_add_metadata( &writer, in ) ) {
|
if( !strip &&
|
||||||
|
vips_webp_add_metadata( &writer, in ) ) {
|
||||||
vips_webp_writer_unset( &writer );
|
vips_webp_writer_unset( &writer );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ read_header( Read *read, VipsImage *out )
|
|||||||
WebPMux *mux;
|
WebPMux *mux;
|
||||||
int i;
|
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.bytes = read->data;
|
||||||
bitstream.size = read->length;
|
bitstream.size = read->length;
|
||||||
@ -245,7 +245,7 @@ read_header( Read *read, VipsImage *out )
|
|||||||
return( -1 );
|
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 *vips = vips__webp_names[i].vips;
|
||||||
const char *webp = vips__webp_names[i].webp;
|
const char *webp = vips__webp_names[i].webp;
|
||||||
|
|
||||||
|
@ -293,6 +293,9 @@ vips_foreign_load_webp_buffer_init( VipsForeignLoadWebpBuffer *buffer )
|
|||||||
*
|
*
|
||||||
* Use @shrink to specify a shrink-on-load factor.
|
* 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().
|
* See also: vips_image_new_from_file().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error.
|
* Returns: 0 on success, -1 on error.
|
||||||
|
@ -191,7 +191,7 @@ vips_foreign_save_webp_file_build( VipsObject *object )
|
|||||||
if( vips__webp_write_file( save->ready, file->filename,
|
if( vips__webp_write_file( save->ready, file->filename,
|
||||||
webp->Q, webp->lossless, webp->preset,
|
webp->Q, webp->lossless, webp->preset,
|
||||||
webp->smart_subsample, webp->near_lossless,
|
webp->smart_subsample, webp->near_lossless,
|
||||||
webp->alpha_q ) )
|
webp->alpha_q, save->strip ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -255,7 +255,7 @@ vips_foreign_save_webp_buffer_build( VipsObject *object )
|
|||||||
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
||||||
webp->Q, webp->lossless, webp->preset,
|
webp->Q, webp->lossless, webp->preset,
|
||||||
webp->smart_subsample, webp->near_lossless,
|
webp->smart_subsample, webp->near_lossless,
|
||||||
webp->alpha_q ) )
|
webp->alpha_q, save->strip ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* obuf is a g_free() buffer, not vips_free().
|
/* 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,
|
if( vips__webp_write_buffer( save->ready, &obuf, &olen,
|
||||||
webp->Q, webp->lossless, webp->preset,
|
webp->Q, webp->lossless, webp->preset,
|
||||||
webp->smart_subsample, webp->near_lossless,
|
webp->smart_subsample, webp->near_lossless,
|
||||||
webp->alpha_q ) )
|
webp->alpha_q, save->strip ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
printf( "Content-length: %zu\r\n", olen );
|
printf( "Content-length: %zu\r\n", olen );
|
||||||
@ -363,12 +363,13 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime )
|
|||||||
*
|
*
|
||||||
* Optional arguments:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* * @Q: %gint quality factor
|
* * @Q: %gint, quality factor
|
||||||
* * @lossless: %gboolean enables lossless compression
|
* * @lossless: %gboolean, enables lossless compression
|
||||||
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
|
* * @preset: #VipsForeignWebpPreset, choose lossy compression preset
|
||||||
* * @smart_subsample: %gboolean enables high quality chroma subsampling
|
* * @smart_subsample: %gboolean, enables high quality chroma subsampling
|
||||||
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
|
* * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q)
|
||||||
* * @alpha_q: %gint set alpha quality in lossless mode
|
* * @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.
|
* 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
|
* with @Q 80, 60, 40 or 20 to apply increasing amounts of preprocessing
|
||||||
* which improves the near-lossless compression ratio by up to 50%.
|
* 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().
|
* See also: vips_webpload(), vips_image_write_to_file().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error.
|
* Returns: 0 on success, -1 on error.
|
||||||
@ -412,12 +416,13 @@ vips_webpsave( VipsImage *in, const char *filename, ... )
|
|||||||
*
|
*
|
||||||
* Optional arguments:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* * @Q: %gint quality factor
|
* * @Q: %gint, quality factor
|
||||||
* * @lossless: %gboolean enables lossless compression
|
* * @lossless: %gboolean, enables lossless compression
|
||||||
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
|
* * @preset: #VipsForeignWebpPreset, choose lossy compression preset
|
||||||
* * @smart_subsample: %gboolean enables high quality chroma subsampling
|
* * @smart_subsample: %gboolean, enables high quality chroma subsampling
|
||||||
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
|
* * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q)
|
||||||
* * @alpha_q: %gint set alpha quality in lossless mode
|
* * @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.
|
* 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:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* * @Q: %gint quality factor
|
* * @Q: %gint, quality factor
|
||||||
* * @lossless: %gboolean enables lossless compression
|
* * @lossless: %gboolean, enables lossless compression
|
||||||
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
|
* * @preset: #VipsForeignWebpPreset, choose lossy compression preset
|
||||||
* * @smart_subsample: %gboolean enables high quality chroma subsampling
|
* * @smart_subsample: %gboolean, enables high quality chroma subsampling
|
||||||
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
|
* * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q)
|
||||||
* * @alpha_q: %gint set alpha quality in lossless mode
|
* * @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.
|
* As vips_webpsave(), but save as a mime webp on stdout.
|
||||||
*
|
*
|
||||||
|
@ -49,7 +49,8 @@ save_load() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if ! $vips copy $tmp/t1.$format $tmp/back.v ; then
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user