add @profile to webpsave

small tiffsave fixes too
This commit is contained in:
John Cupitt 2020-07-18 14:49:37 +01:00
parent a69c998ff0
commit fcaba0e6ba
6 changed files with 72 additions and 30 deletions

View File

@ -41,6 +41,7 @@
- vipsheader allows "stdin" as a filename
- gifload allows gifs with images outside the canvas
- wasm compatibility patches [kleisauke]
- webpsave has a @profile param
24/4/20 started 8.9.3
- better iiif tile naming [IllyaMoskvin]

View File

@ -525,7 +525,7 @@ vips_foreign_save_jpeg_mime_init( VipsForeignSaveJpegMime *mime )
* Optional arguments:
*
* * @Q: %gint, quality factor
* * @profile: filename of ICC profile to attach
* * @profile: %gchararray, filename of ICC profile to attach
* * @optimize_coding: %gboolean, compute optimal Huffman coding tables
* * @interlace: %gboolean, write an interlaced (progressive) jpeg
* * @strip: %gboolean, remove all metadata from image
@ -641,7 +641,7 @@ vips_jpegsave( VipsImage *in, const char *filename, ... )
* Optional arguments:
*
* * @Q: %gint, quality factor
* * @profile: filename of ICC profile to attach
* * @profile: %gchararray, filename of ICC profile to attach
* * @optimize_coding: %gboolean, compute optimal Huffman coding tables
* * @interlace: %gboolean, write an interlaced (progressive) jpeg
* * @strip: %gboolean, remove all metadata from image
@ -680,7 +680,7 @@ vips_jpegsave_target( VipsImage *in, VipsTarget *target, ... )
* Optional arguments:
*
* * @Q: %gint, quality factor
* * @profile: filename of ICC profile to attach
* * @profile: %gchararray, filename of ICC profile to attach
* * @optimize_coding: %gboolean, compute optimal Huffman coding tables
* * @interlace: %gboolean, write an interlaced (progressive) jpeg
* * @strip: %gboolean, remove all metadata from image
@ -736,7 +736,7 @@ vips_jpegsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
* Optional arguments:
*
* * @Q: %gint, quality factor
* * @profile: filename of ICC profile to attach
* * @profile: %gchararray, filename of ICC profile to attach
* * @optimize_coding: %gboolean, compute optimal Huffman coding tables
* * @interlace: %gboolean, write an interlaced (progressive) jpeg
* * @strip: %gboolean, remove all metadata from image

View File

@ -50,7 +50,7 @@ void vips__tiff_init( void );
int vips__tiff_write( VipsImage *in, const char *filename,
VipsForeignTiffCompression compression, int Q,
VipsForeignTiffPredictor predictor,
char *profile,
const char *profile,
gboolean tile, int tile_width, int tile_height,
gboolean pyramid,
int bitdepth,
@ -70,7 +70,7 @@ int vips__tiff_write_buf( VipsImage *in,
void **obuf, size_t *olen,
VipsForeignTiffCompression compression, int Q,
VipsForeignTiffPredictor predictor,
char *profile,
const char *profile,
gboolean tile, int tile_width, int tile_height,
gboolean pyramid,
int bitdepth,
@ -211,7 +211,7 @@ int vips__webp_write_target( VipsImage *image, VipsTarget *target,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q, int reduction_effort,
gboolean min_size, int kmin, int kmax,
gboolean strip );
gboolean strip, const char *profile );
int vips__openslide_isslide( const char *filename );
int vips__openslide_read_header( const char *filename, VipsImage *out,

View File

@ -344,7 +344,7 @@ struct _Wtiff {
int resunit; /* Resolution unit (inches or cm) */
double xres; /* Resolution in X */
double yres; /* Resolution in Y */
char *icc_profile; /* Profile to embed */
const char *profile; /* Profile to embed */
int bigtiff; /* True for bigtiff write */
int rgbjpeg; /* True for RGB not YCbCr */
int properties; /* Set to save XML props */
@ -512,11 +512,11 @@ wtiff_layer_init( Wtiff *wtiff, Layer **layer, Layer *above,
static int
wtiff_embed_profile( Wtiff *wtiff, TIFF *tif )
{
if( wtiff->icc_profile &&
embed_profile_file( tif, wtiff->icc_profile ) )
if( wtiff->profile &&
embed_profile_file( tif, wtiff->profile ) )
return( -1 );
if( !wtiff->icc_profile &&
if( !wtiff->profile &&
vips_image_get_typeof( wtiff->ready, VIPS_META_ICC_NAME ) &&
embed_profile_meta( tif, wtiff->ready ) )
return( -1 );
@ -981,7 +981,6 @@ wtiff_free( Wtiff *wtiff )
VIPS_UNREF( wtiff->ready );
VIPS_FREE( wtiff->tbuf );
VIPS_FREEF( layer_free_all, wtiff->layer );
VIPS_FREE( wtiff->icc_profile );
VIPS_FREE( wtiff->filename );
VIPS_FREE( wtiff );
}
@ -1062,7 +1061,7 @@ static Wtiff *
wtiff_new( VipsImage *input, const char *filename,
VipsForeignTiffCompression compression, int Q,
VipsForeignTiffPredictor predictor,
char *profile,
const char *profile,
gboolean tile, int tile_width, int tile_height,
gboolean pyramid,
int bitdepth,
@ -1099,7 +1098,7 @@ wtiff_new( VipsImage *input, const char *filename,
wtiff->resunit = get_resunit( resunit );
wtiff->xres = xres;
wtiff->yres = yres;
wtiff->icc_profile = vips_strdup( NULL, profile );
wtiff->profile = profile;
wtiff->bigtiff = bigtiff;
wtiff->rgbjpeg = rgbjpeg;
wtiff->properties = properties;
@ -1866,7 +1865,7 @@ wtiff_copy_tiff( Wtiff *wtiff, TIFF *out, TIFF *in )
TIFFSetField( out, TIFFTAG_ZSTD_LEVEL, wtiff->level );
#endif /*HAVE_TIFF_COMPRESSION_WEBP*/
/* We can't copy profiles or xmp :( Set again from Wtiff.
/* We can't copy profiles or xmp :( Set again from wtiff.
*/
if( !wtiff->strip )
if( wtiff_embed_profile( wtiff, out ) ||
@ -2059,7 +2058,7 @@ int
vips__tiff_write( VipsImage *input, const char *filename,
VipsForeignTiffCompression compression, int Q,
VipsForeignTiffPredictor predictor,
char *profile,
const char *profile,
gboolean tile, int tile_width, int tile_height,
gboolean pyramid,
int bitdepth,
@ -2105,7 +2104,7 @@ vips__tiff_write_buf( VipsImage *input,
void **obuf, size_t *olen,
VipsForeignTiffCompression compression, int Q,
VipsForeignTiffPredictor predictor,
char *profile,
const char *profile,
gboolean tile, int tile_width, int tile_height,
gboolean pyramid,
int bitdepth,

View File

@ -18,6 +18,8 @@
* - set loop even if we strip
* 14/10/19
* - revise for target IO
* 18/7/20
* - add @profile param to match tiff, jpg, etc.
*/
/*
@ -88,6 +90,7 @@ typedef struct {
int kmin;
int kmax;
gboolean strip;
const char *profile;
WebPConfig config;
@ -146,7 +149,7 @@ vips_webp_write_init( VipsWebPWrite *write, VipsImage *image,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q, int reduction_effort,
gboolean min_size, int kmin, int kmax,
gboolean strip )
gboolean strip, const char *profile )
{
write->image = NULL;
write->Q = Q;
@ -160,14 +163,15 @@ vips_webp_write_init( VipsWebPWrite *write, VipsImage *image,
write->kmin = kmin;
write->kmax = kmax;
write->strip = strip;
write->profile = profile;
WebPMemoryWriterInit( &write->memory_writer );
write->enc = NULL;
write->mux = NULL;
/* Rebuild exif on image. We must do this on a copy.
/* We need a copy of the input image in case we change the metadata
* eg. in vips__exif_update().
*/
if( vips_copy( image, &write->image, NULL ) ||
vips__exif_update( write->image ) ) {
if( vips_copy( image, &write->image, NULL ) ) {
vips_webp_write_unset( write );
return( -1 );
}
@ -456,6 +460,9 @@ vips_webp_add_chunks( VipsWebPWrite *write )
const char *vips_name = vips__webp_names[i].vips;
const char *webp_name = vips__webp_names[i].webp;
if( strcmp( vips_name, VIPS_META_ICC_NAME ) == 0 &&
write->profile )
if( vips_image_get_typeof( write->image, vips_name ) ) {
const void *data;
size_t length;
@ -507,9 +514,22 @@ vips_webp_add_metadata( VipsWebPWrite *write )
/* Add extra metadata.
*/
if( !write->strip &&
vips_webp_add_chunks( write ) )
return( -1 );
if( !write->strip ) {
/* We need to rebuild exif from the other image tags before
* writing the metadata.
*/
if( vips__exif_update( write->image ) )
return( -1 );
/* Override profile.
*/
if( write->profile &&
vips__profile_set( write->image, write->profile ) )
return( -1 );
if( vips_webp_add_chunks( write ) )
return( -1 );
}
if( WebPMuxAssemble( write->mux, &data ) != WEBP_MUX_OK ) {
vips_error( "vips2webp", "%s", _( "mux error" ) );
@ -531,13 +551,14 @@ vips__webp_write_target( VipsImage *image, VipsTarget *target,
gboolean smart_subsample, gboolean near_lossless,
int alpha_q, int reduction_effort,
gboolean min_size, int kmin, int kmax,
gboolean strip )
gboolean strip, const char *profile )
{
VipsWebPWrite write;
if( vips_webp_write_init( &write, image,
Q, lossless, preset, smart_subsample, near_lossless,
alpha_q, reduction_effort, min_size, kmin, kmax, strip ) )
alpha_q, reduction_effort, min_size, kmin, kmax, strip,
profile ) )
return( -1 );
if( write_webp( &write ) ) {

View File

@ -6,6 +6,8 @@
* - add animated webp support
* 15/1/19 lovell
* - add @reduction_effort
* 18/7/20
* - add @profile param to match tiff, jpg, etc.
*/
/*
@ -99,6 +101,10 @@ typedef struct _VipsForeignSaveWebp {
*/
int kmax;
/* Profile to embed.
*/
char *profile;
} VipsForeignSaveWebp;
typedef VipsForeignSaveClass VipsForeignSaveWebpClass;
@ -204,6 +210,13 @@ vips_foreign_save_webp_class_init( VipsForeignSaveWebpClass *class )
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveWebp, reduction_effort ),
0, 6, 4 );
VIPS_ARG_STRING( class, "profile", 20,
_( "Profile" ),
_( "ICC profile to embed" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveWebp, profile ),
NULL );
}
static void
@ -248,7 +261,7 @@ vips_foreign_save_webp_target_build( VipsObject *object )
webp->smart_subsample, webp->near_lossless,
webp->alpha_q, webp->reduction_effort,
webp->min_size, webp->kmin, webp->kmax,
save->strip ) )
save->strip, webp->profile ) )
return( -1 );
return( 0 );
@ -316,7 +329,7 @@ vips_foreign_save_webp_file_build( VipsObject *object )
webp->smart_subsample, webp->near_lossless,
webp->alpha_q, webp->reduction_effort,
webp->min_size, webp->kmin, webp->kmax,
save->strip ) ) {
save->strip, webp->profile ) ) {
VIPS_UNREF( target );
return( -1 );
}
@ -388,7 +401,7 @@ vips_foreign_save_webp_buffer_build( VipsObject *object )
webp->smart_subsample, webp->near_lossless,
webp->alpha_q, webp->reduction_effort,
webp->min_size, webp->kmin, webp->kmax,
save->strip ) ) {
save->strip, webp->profile ) ) {
VIPS_UNREF( target );
return( -1 );
}
@ -462,7 +475,7 @@ vips_foreign_save_webp_mime_build( VipsObject *object )
webp->smart_subsample, webp->near_lossless,
webp->alpha_q, webp->reduction_effort,
webp->min_size, webp->kmin, webp->kmax,
save->strip ) ) {
save->strip, webp->profile ) ) {
VIPS_UNREF( target );
return( -1 );
}
@ -520,6 +533,7 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime )
* * @kmin: %gint, minimum number of frames between keyframes
* * @kmax: %gint, maximum number of frames between keyframes
* * @strip: %gboolean, remove all metadata from image
* * @profile: %gchararray, filename of ICC profile to attach
*
* Write an image to a file in WebP format.
*
@ -550,6 +564,10 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime )
* frames between frames. Setting 0 means no keyframes. By default, keyframes
* are disabled.
*
* Use @profile to give the name of a profile to be embedded in the file.
* This does not affect the pixels which are written, just the way
* they are tagged. See vips_profile_load() for details on profile naming.
*
* Use the metadata items `loop` and `delay` to set the number of
* loops for the animation and the frame delays.
*
@ -593,6 +611,7 @@ vips_webpsave( VipsImage *in, const char *filename, ... )
* * @kmin: %gint, minimum number of frames between keyframes
* * @kmax: %gint, maximum number of frames between keyframes
* * @strip: %gboolean, remove all metadata from image
* * @profile: %gchararray, filename of ICC profile to attach
*
* As vips_webpsave(), but save to a memory buffer.
*
@ -650,6 +669,7 @@ vips_webpsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
* * @kmin: %gint, minimum number of frames between keyframes
* * @kmax: %gint, maximum number of frames between keyframes
* * @strip: %gboolean, remove all metadata from image
* * @profile: %gchararray, filename of ICC profile to attach
*
* As vips_webpsave(), but save as a mime webp on stdout.
*
@ -689,6 +709,7 @@ vips_webpsave_mime( VipsImage *in, ... )
* * @kmin: %gint, minimum number of frames between keyframes
* * @kmax: %gint, maximum number of frames between keyframes
* * @strip: %gboolean, remove all metadata from image
* * @profile: %gchararray, filename of ICC profile to attach
*
* As vips_webpsave(), but save to a target.
*