add jxl encoder options

though they don't seem to affect file size, curiously
This commit is contained in:
John Cupitt 2021-04-03 18:11:38 +01:00
parent 55e634a0d2
commit 70078e3774
2 changed files with 92 additions and 5 deletions

View File

@ -32,9 +32,9 @@
*/ */
/* /*
*/
#define DEBUG_VERBOSE #define DEBUG_VERBOSE
#define DEBUG #define DEBUG
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
@ -56,6 +56,18 @@
#include "pforeign.h" #include "pforeign.h"
/* TODO:
*
* - libjxl seems to only work in one shot mode, so there's no way to read in
* chunks
*
* - preview image? EXIF? XMP?
*
* - check scRGB encoding
*
* - add "shrink" option to read out 8x shrunk image?
*/
#define INPUT_BUFFER_SIZE (4096) #define INPUT_BUFFER_SIZE (4096)
typedef struct _VipsForeignLoadJxl { typedef struct _VipsForeignLoadJxl {

View File

@ -62,6 +62,9 @@
* - libjxl seems to only work in one shot mode, so there's no way to write in * - libjxl seems to only work in one shot mode, so there's no way to write in
* chunks * chunks
* *
* - embed a preview image? EXIF? XMP?
*
* - check scRGB encoding
*/ */
#define OUTPUT_BUFFER_SIZE (4096) #define OUTPUT_BUFFER_SIZE (4096)
@ -73,6 +76,13 @@ typedef struct _VipsForeignSaveJxl {
*/ */
VipsTarget *target; VipsTarget *target;
/* Encoder options.
*/
int tier;
double distance;
int effort;
gboolean lossless;
/* Base image properties. /* Base image properties.
*/ */
JxlBasicInfo info; JxlBasicInfo info;
@ -123,7 +133,7 @@ vips_foreign_save_jxl_build( VipsObject *object )
VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSave *save = (VipsForeignSave *) object;
VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) object; VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) object;
JxlEncoderOptions *encoder_options; JxlEncoderOptions *options;
JxlEncoderStatus status; JxlEncoderStatus status;
if( VIPS_OBJECT_CLASS( vips_foreign_save_jxl_parent_class )-> if( VIPS_OBJECT_CLASS( vips_foreign_save_jxl_parent_class )->
@ -253,8 +263,13 @@ vips_foreign_save_jxl_build( VipsObject *object )
if( vips_image_wio_input( save->ready ) ) if( vips_image_wio_input( save->ready ) )
return( -1 ); return( -1 );
encoder_options = JxlEncoderOptionsCreate( jxl->encoder, NULL ); options = JxlEncoderOptionsCreate( jxl->encoder, NULL );
if( JxlEncoderAddImageFrame( encoder_options, &jxl->format, JxlEncoderOptionsSetDecodingSpeed( options, jxl->tier );
JxlEncoderOptionsSetDistance( options, jxl->distance );
JxlEncoderOptionsSetEffort( options, jxl->effort );
JxlEncoderOptionsSetLossless( options, jxl->lossless );
if( JxlEncoderAddImageFrame( options, &jxl->format,
VIPS_IMAGE_ADDR( save->ready, 0, 0 ), VIPS_IMAGE_ADDR( save->ready, 0, 0 ),
VIPS_IMAGE_SIZEOF_IMAGE( save->ready ) ) ) { VIPS_IMAGE_SIZEOF_IMAGE( save->ready ) ) ) {
vips_foreign_save_jxl_error( jxl, "JxlEncoderAddImageFrame" ); vips_foreign_save_jxl_error( jxl, "JxlEncoderAddImageFrame" );
@ -325,11 +340,43 @@ vips_foreign_save_jxl_class_init( VipsForeignSaveJxlClass *class )
save_class->saveable = VIPS_SAVEABLE_ANY; save_class->saveable = VIPS_SAVEABLE_ANY;
save_class->format_table = bandfmt_jpeg; save_class->format_table = bandfmt_jpeg;
VIPS_ARG_INT( class, "tier", 10,
_( "Tier" ),
_( "Decode speed tier" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveJxl, tier ),
0, 4, 0 );
VIPS_ARG_DOUBLE( class, "distance", 11,
_( "Distance" ),
_( "Target butteraugli distance" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveJxl, distance ),
0, 15, 1.0 );
VIPS_ARG_INT( class, "effort", 12,
_( "effort" ),
_( "Encoding effort" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveJxl, effort ),
3, 9, 7 );
VIPS_ARG_BOOL( class, "lossless", 13,
_( "Lossless" ),
_( "Enable lossless compression" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveJxl, lossless ),
FALSE );
} }
static void static void
vips_foreign_save_jxl_init( VipsForeignSaveJxl *jxl ) vips_foreign_save_jxl_init( VipsForeignSaveJxl *jxl )
{ {
jxl->tier = 0;
jxl->distance = 1.0;
jxl->effort = 7;
jxl->lossless = FALSE;
} }
typedef struct _VipsForeignSaveJxlFile { typedef struct _VipsForeignSaveJxlFile {
@ -517,9 +564,23 @@ vips_foreign_save_jxl_target_init( VipsForeignSaveJxlTarget *target )
* @filename: file to write to * @filename: file to write to
* @...: %NULL-terminated list of optional named arguments * @...: %NULL-terminated list of optional named arguments
* *
* Optional arguments:
*
* * @tier: %gint, decode speed tier
* * @distance: %gdouble, maximum encoding error
* * @effort: %gint, encoding effort
* * @lossless: %gboolean, enables lossless compression
*
* Write a VIPS image to a file in JPEG-XL format. * Write a VIPS image to a file in JPEG-XL format.
* *
* See also: vips_image_write_to_file(), vips_jxlload(). * @tier sets the overall decode speed the encoder will target. Minimum is 0
* (highest quality), and maximum is 4 (lowest quality). Default is 0.
*
* @distance sets the target maximum encoding error. Minimum is 0
* (highest quality), and maximum is 15 (lowest quality). Default is 1.0
* (visually lossless).
*
* Set @lossless to enable lossless compresion.
* *
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.
*/ */
@ -543,6 +604,13 @@ vips_jxlsave( VipsImage *in, const char *filename, ... )
* @len: (type gsize): return output length here * @len: (type gsize): return output length here
* @...: %NULL-terminated list of optional named arguments * @...: %NULL-terminated list of optional named arguments
* *
* Optional arguments:
*
* * @tier: %gint, decode speed tier
* * @distance: %gdouble, maximum encoding error
* * @effort: %gint, encoding effort
* * @lossless: %gboolean, enables lossless compression
*
* As vips_jxlsave(), but save to a memory buffer. * As vips_jxlsave(), but save to a memory buffer.
* *
* See also: vips_jxlsave(), vips_image_write_to_target(). * See also: vips_jxlsave(), vips_image_write_to_target().
@ -583,6 +651,13 @@ vips_jxlsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
* @target: save image to this target * @target: save image to this target
* @...: %NULL-terminated list of optional named arguments * @...: %NULL-terminated list of optional named arguments
* *
* Optional arguments:
*
* * @tier: %gint, decode speed tier
* * @distance: %gdouble, maximum encoding error
* * @effort: %gint, encoding effort
* * @lossless: %gboolean, enables lossless compression
*
* As vips_jxlsave(), but save to a target. * As vips_jxlsave(), but save to a target.
* *
* See also: vips_jxlsave(), vips_image_write_to_target(). * See also: vips_jxlsave(), vips_image_write_to_target().