heifsave: make it possible to use a specific encoder (#3198)
* heifsave: make it possible to use a specific encoder * argument label: switch to leading capital letter Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl> * add VipsForeignHeifEncoder enum * correct type * implement reviewer feedback Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
This commit is contained in:
parent
20a4d6029d
commit
6bb0b4dd1e
@ -26,6 +26,7 @@ master
|
|||||||
- GIF load supports truncated frames [tlsa]
|
- GIF load supports truncated frames [tlsa]
|
||||||
- EXIF support for PNG load and save
|
- EXIF support for PNG load and save
|
||||||
- deprecate gifsave reoptimise, add reuse
|
- deprecate gifsave reoptimise, add reuse
|
||||||
|
- add "encoder" to heifsave [dloebl]
|
||||||
|
|
||||||
9/11/22 started 8.13.4
|
9/11/22 started 8.13.4
|
||||||
- missing include in mosaic_fuzzer [ServOKio]
|
- missing include in mosaic_fuzzer [ServOKio]
|
||||||
|
@ -2250,6 +2250,7 @@ vips_heifload_source( VipsSource *source, VipsImage **out, ... )
|
|||||||
* * @compression: #VipsForeignHeifCompression, write with this compression
|
* * @compression: #VipsForeignHeifCompression, write with this compression
|
||||||
* * @effort: %gint, encoding effort
|
* * @effort: %gint, encoding effort
|
||||||
* * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
|
* * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
|
||||||
|
* * @encoder: #VipsForeignHeifEncoder, select encoder to use
|
||||||
*
|
*
|
||||||
* Write a VIPS image to a file in HEIF format.
|
* Write a VIPS image to a file in HEIF format.
|
||||||
*
|
*
|
||||||
@ -2258,7 +2259,7 @@ vips_heifload_source( VipsSource *source, VipsImage **out, ... )
|
|||||||
*
|
*
|
||||||
* Set @lossless %TRUE to switch to lossless compression.
|
* Set @lossless %TRUE to switch to lossless compression.
|
||||||
*
|
*
|
||||||
* Use @compression to set the encoder e.g. HEVC, AVC, AV1. It defaults to AV1
|
* Use @compression to set the compression format e.g. HEVC, AVC, AV1 to use. It defaults to AV1
|
||||||
* if the target filename ends with ".avif", otherwise HEVC.
|
* if the target filename ends with ".avif", otherwise HEVC.
|
||||||
*
|
*
|
||||||
* Use @effort to control the CPU effort spent improving compression.
|
* Use @effort to control the CPU effort spent improving compression.
|
||||||
@ -2271,6 +2272,8 @@ vips_heifload_source( VipsSource *source, VipsImage **out, ... )
|
|||||||
* Use @bitdepth to set the bitdepth of the output file. HEIC supports at
|
* Use @bitdepth to set the bitdepth of the output file. HEIC supports at
|
||||||
* least 8, 10 and 12 bits; other codecs may support more or fewer options.
|
* least 8, 10 and 12 bits; other codecs may support more or fewer options.
|
||||||
*
|
*
|
||||||
|
* Use @encoder to set the encode library to use, e.g. aom, SVT-AV1, rav1e etc.
|
||||||
|
*
|
||||||
* See also: vips_image_write_to_file(), vips_heifload().
|
* See also: vips_image_write_to_file(), vips_heifload().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error.
|
* Returns: 0 on success, -1 on error.
|
||||||
@ -2303,6 +2306,7 @@ vips_heifsave( VipsImage *in, const char *filename, ... )
|
|||||||
* * @compression: #VipsForeignHeifCompression, write with this compression
|
* * @compression: #VipsForeignHeifCompression, write with this compression
|
||||||
* * @effort: %gint, encoding effort
|
* * @effort: %gint, encoding effort
|
||||||
* * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
|
* * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
|
||||||
|
* * @encoder: #VipsForeignHeifEncoder, select encoder to use
|
||||||
*
|
*
|
||||||
* As vips_heifsave(), but save to a memory buffer.
|
* As vips_heifsave(), but save to a memory buffer.
|
||||||
*
|
*
|
||||||
@ -2356,6 +2360,7 @@ vips_heifsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
|||||||
* * @compression: #VipsForeignHeifCompression, write with this compression
|
* * @compression: #VipsForeignHeifCompression, write with this compression
|
||||||
* * @effort: %gint, encoding effort
|
* * @effort: %gint, encoding effort
|
||||||
* * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
|
* * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
|
||||||
|
* * @encoder: #VipsForeignHeifEncoder, select encoder to use
|
||||||
*
|
*
|
||||||
* As vips_heifsave(), but save to a target.
|
* As vips_heifsave(), but save to a target.
|
||||||
*
|
*
|
||||||
|
@ -99,6 +99,10 @@ typedef struct _VipsForeignSaveHeif {
|
|||||||
*/
|
*/
|
||||||
VipsForeignSubsample subsample_mode;
|
VipsForeignSubsample subsample_mode;
|
||||||
|
|
||||||
|
/* Encoder to use. For instance: aom, svt etc.
|
||||||
|
*/
|
||||||
|
VipsForeignHeifEncoder selected_encoder;
|
||||||
|
|
||||||
/* The image we save. This is a copy of save->ready since we need to
|
/* The image we save. This is a copy of save->ready since we need to
|
||||||
* be able to update the metadata.
|
* be able to update the metadata.
|
||||||
*/
|
*/
|
||||||
@ -438,6 +442,7 @@ vips_foreign_save_heif_build( VipsObject *object )
|
|||||||
struct heif_error error;
|
struct heif_error error;
|
||||||
struct heif_writer writer;
|
struct heif_writer writer;
|
||||||
char *chroma;
|
char *chroma;
|
||||||
|
const struct heif_encoder_descriptor* out_encoder;
|
||||||
|
|
||||||
if( VIPS_OBJECT_CLASS( vips_foreign_save_heif_parent_class )->
|
if( VIPS_OBJECT_CLASS( vips_foreign_save_heif_parent_class )->
|
||||||
build( object ) )
|
build( object ) )
|
||||||
@ -465,9 +470,36 @@ vips_foreign_save_heif_build( VipsObject *object )
|
|||||||
heif->image->Type == VIPS_INTERPRETATION_GREY16 ?
|
heif->image->Type == VIPS_INTERPRETATION_GREY16 ?
|
||||||
12 : 8;
|
12 : 8;
|
||||||
|
|
||||||
error = heif_context_get_encoder_for_format( heif->ctx,
|
/* Try to find the selected encoder.
|
||||||
(enum heif_compression_format) heif->compression,
|
*/
|
||||||
&heif->encoder );
|
if( heif->selected_encoder != VIPS_FOREIGN_HEIF_ENCODER_AUTO ) {
|
||||||
|
const int count = heif_context_get_encoder_descriptors(
|
||||||
|
heif->ctx,
|
||||||
|
(enum heif_compression_format) heif->compression,
|
||||||
|
vips_enum_nick( VIPS_TYPE_FOREIGN_HEIF_ENCODER,
|
||||||
|
heif->selected_encoder ),
|
||||||
|
&out_encoder, 1 );
|
||||||
|
|
||||||
|
if( count > 0 ) {
|
||||||
|
error = heif_context_get_encoder( heif->ctx,
|
||||||
|
out_encoder, &heif->encoder );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_warning(
|
||||||
|
"heifsave: could not find selected encoder %s",
|
||||||
|
vips_enum_nick( VIPS_TYPE_FOREIGN_HEIF_ENCODER,
|
||||||
|
heif->selected_encoder ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback to default encoder.
|
||||||
|
*/
|
||||||
|
if( !heif->encoder ) {
|
||||||
|
error = heif_context_get_encoder_for_format( heif->ctx,
|
||||||
|
(enum heif_compression_format) heif->compression,
|
||||||
|
&heif->encoder );
|
||||||
|
}
|
||||||
|
|
||||||
if( error.code ) {
|
if( error.code ) {
|
||||||
if( error.code == heif_error_Unsupported_filetype )
|
if( error.code == heif_error_Unsupported_filetype )
|
||||||
vips_error( "heifsave",
|
vips_error( "heifsave",
|
||||||
@ -654,6 +686,13 @@ vips_foreign_save_heif_class_init( VipsForeignSaveHeifClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsForeignSaveHeif, speed ),
|
G_STRUCT_OFFSET( VipsForeignSaveHeif, speed ),
|
||||||
0, 9, 5 );
|
0, 9, 5 );
|
||||||
|
|
||||||
|
VIPS_ARG_ENUM( class, "encoder", 18,
|
||||||
|
_( "Encoder" ),
|
||||||
|
_( "Select encoder to use" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignSaveHeif, selected_encoder ),
|
||||||
|
VIPS_TYPE_FOREIGN_HEIF_ENCODER,
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_AUTO );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -964,6 +964,28 @@ typedef enum {
|
|||||||
VIPS_FOREIGN_HEIF_COMPRESSION_LAST
|
VIPS_FOREIGN_HEIF_COMPRESSION_LAST
|
||||||
} VipsForeignHeifCompression;
|
} VipsForeignHeifCompression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VipsForeignHeifEncoder:
|
||||||
|
* @VIPS_FOREIGN_HEIF_ENCODER_AUTO: auto
|
||||||
|
* @VIPS_FOREIGN_HEIF_ENCODER_AOM: aom
|
||||||
|
* @VIPS_FOREIGN_HEIF_ENCODER_RAV1E: RAV1E
|
||||||
|
* @VIPS_FOREIGN_HEIF_ENCODER_SVT: SVT-AV1
|
||||||
|
* @VIPS_FOREIGN_HEIF_ENCODER_X265: x265
|
||||||
|
*
|
||||||
|
* The selected encoder to use.
|
||||||
|
* If libheif hasn't been compiled with the selected encoder,
|
||||||
|
* we will fallback to the default encoder for the compression format.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_AUTO,
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_AOM,
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_RAV1E,
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_SVT,
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_X265,
|
||||||
|
VIPS_FOREIGN_HEIF_ENCODER_LAST
|
||||||
|
} VipsForeignHeifEncoder;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
Loading…
Reference in New Issue
Block a user