From 0a23bf35780f409c7f7d59bd4ea969345c9327b1 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 18 Feb 2020 17:37:56 +0000 Subject: [PATCH] revise formatting, add docs fix up some formatting from https://github.com/libvips/libvips/pull/1552 plus some other small changes --- ChangeLog | 1 + libvips/foreign/jpegsave.c | 71 ++++++++++++++++++---------------- libvips/foreign/pforeign.h | 2 +- libvips/foreign/vips2jpeg.c | 35 +++++++---------- libvips/include/vips/foreign.h | 9 +++-- libvips/iofuncs/enumtypes.c | 1 + 6 files changed, 61 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index c23df862..7359d1d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ - add vips_pipe_read_limit_set(), --vips-pipe-read-limit, VIPS_PIPE_READ_LIMIT - revise gifload to fix BACKGROUND and PREVIOUS dispose [alon-ne] +- add subsample_mode, deprecate no_subsample in jpegsave [Elad-Laufer] 31/1/19 started 8.9.2 - fix a deadlock with --vips-leak [DarthSim] diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index a138e564..e1cca6c1 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -2,6 +2,8 @@ * * 24/11/11 * - wrap a class around the jpeg writer + * 18/2/20 Elad-Laufer + * - add subsample_mode, deprecate no_subsample */ /* @@ -77,12 +79,12 @@ typedef struct _VipsForeignSaveJpeg { */ gboolean no_subsample; - /* Select chroma subsampling mode: - * auto will disable subsampling for Q >= 90 - * on will always enable subsampling - * off will always disable subsampling - */ - VipsForeignJpegSubsample subsample_mode; + /* Select chroma subsampling mode: + * auto will disable subsampling for Q >= 90 + * on will always enable subsampling + * off will always disable subsampling + */ + VipsForeignJpegSubsample subsample_mode; /* Apply trellis quantisation to each 8x8 block. */ @@ -113,26 +115,28 @@ G_DEFINE_ABSTRACT_TYPE( VipsForeignSaveJpeg, vips_foreign_save_jpeg, /* Type promotion for save ... just always go to uchar. */ static int bandfmt_jpeg[10] = { -/* UC C US S UI I F X D DX */ - UC, UC, UC, UC, UC, UC, UC, UC, UC, UC + /* UC C US S UI I F X D DX */ + UC, UC, UC, UC, UC, UC, UC, UC, UC, UC }; static int vips_foreign_save_jpeg_build( VipsObject *object ) { - VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object; + VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object; - if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_parent_class )-> - build( object ) ) - return( -1 ); + if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_parent_class )-> + build( object ) ) + return( -1 ); - /* no_subsample is deprecated, but we retain backwards compatibility - * new code should use subsample_mode - */ - if( vips_object_argument_isset(object, "no_subsample") ) - jpeg->subsample_mode = jpeg->no_subsample ? VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF : VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO; + /* no_subsample is deprecated, but we retain backwards compatibility + * new code should use subsample_mode + */ + if( vips_object_argument_isset( object, "no_subsample" ) ) + jpeg->subsample_mode = jpeg->no_subsample ? + VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF : + VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO; - return( 0 ); + return( 0 ); } static void @@ -148,7 +152,7 @@ vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class ) object_class->nickname = "jpegsave_base"; object_class->description = _( "save jpeg" ); - object_class->build = vips_foreign_save_jpeg_build; + object_class->build = vips_foreign_save_jpeg_build; foreign_class->suffs = vips__jpeg_suffs; @@ -220,19 +224,20 @@ vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class ) G_STRUCT_OFFSET( VipsForeignSaveJpeg, quant_table ), 0, 8, 0 ); - VIPS_ARG_ENUM( class, "subsample_mode", 19, - _( "Subsample mode" ), - _( "Select chroma subsample operation mode" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsForeignSaveJpeg, subsample_mode ), - VIPS_TYPE_FOREIGN_JPEG_SUBSAMPLE, - VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO ); + VIPS_ARG_ENUM( class, "subsample_mode", 19, + _( "Subsample mode" ), + _( "Select chroma subsample operation mode" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignSaveJpeg, subsample_mode ), + VIPS_TYPE_FOREIGN_JPEG_SUBSAMPLE, + VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO ); } static void vips_foreign_save_jpeg_init( VipsForeignSaveJpeg *jpeg ) { jpeg->Q = 75; + jpeg->subsample_mode = VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO; } typedef struct _VipsForeignSaveJpegTarget { @@ -524,7 +529,7 @@ vips_foreign_save_jpeg_mime_init( VipsForeignSaveJpegMime *mime ) * * @optimize_coding: %gboolean, compute optimal Huffman coding tables * * @interlace: %gboolean, write an interlaced (progressive) jpeg * * @strip: %gboolean, remove all metadata from image - * * @no_subsample: %gboolean, disable chroma subsampling + * * @subsample_mode: #VipsForeignJpegSubsample, chroma subsampling mode * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block * * @overshoot_deringing: %gboolean, overshoot samples with extreme values * * @optimize_scans: %gboolean, split DCT coefficients into separate scans @@ -550,10 +555,10 @@ vips_foreign_save_jpeg_mime_init( VipsForeignSaveJpegMime *mime ) * conection, but need much more memory to encode and decode. * * If @strip is set, no EXIF data, IPTC data, ICC profile or XMP metadata is - * written into the output file. + * written into the output file. * - * If @no_subsample is set, chrominance subsampling is disabled. This will - * improve quality at the cost of larger file size. Useful for high Q factors. + * Chroma subsampling is normally automatically disabled for Q > 90. You can + * force the subsampling mode with @@subsample_mode. * * If @trellis_quant is set and the version of libjpeg supports it * (e.g. mozjpeg >= 3.0), apply trellis quantisation to each 8x8 block. @@ -640,7 +645,7 @@ vips_jpegsave( VipsImage *in, const char *filename, ... ) * * @optimize_coding: %gboolean, compute optimal Huffman coding tables * * @interlace: %gboolean, write an interlaced (progressive) jpeg * * @strip: %gboolean, remove all metadata from image - * * @no_subsample: %gboolean, disable chroma subsampling + * * @subsample_mode: #VipsForeignJpegSubsample, chroma subsampling mode * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block * * @overshoot_deringing: %gboolean, overshoot samples with extreme values * * @optimize_scans: %gboolean, split DCT coefficients into separate scans @@ -679,7 +684,7 @@ vips_jpegsave_target( VipsImage *in, VipsTarget *target, ... ) * * @optimize_coding: %gboolean, compute optimal Huffman coding tables * * @interlace: %gboolean, write an interlaced (progressive) jpeg * * @strip: %gboolean, remove all metadata from image - * * @no_subsample: %gboolean, disable chroma subsampling + * * @subsample_mode: #VipsForeignJpegSubsample, chroma subsampling mode * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block * * @overshoot_deringing: %gboolean, overshoot samples with extreme values * * @optimize_scans: %gboolean, split DCT coefficients into separate scans @@ -735,7 +740,7 @@ vips_jpegsave_buffer( VipsImage *in, void **buf, size_t *len, ... ) * * @optimize_coding: %gboolean, compute optimal Huffman coding tables * * @interlace: %gboolean, write an interlaced (progressive) jpeg * * @strip: %gboolean, remove all metadata from image - * * @no_subsample: %gboolean, disable chroma subsampling + * * @subsample_mode: #VipsForeignJpegSubsample, chroma subsampling mode * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block * * @overshoot_deringing: %gboolean, overshoot samples with extreme values * * @optimize_scans: %gboolean, split DCT coefficients into separate scans diff --git a/libvips/foreign/pforeign.h b/libvips/foreign/pforeign.h index 791d26e3..92b32cc4 100644 --- a/libvips/foreign/pforeign.h +++ b/libvips/foreign/pforeign.h @@ -49,7 +49,7 @@ void vips__tiff_init( void ); int vips__tiff_write( VipsImage *in, const char *filename, VipsForeignTiffCompression compression, int Q, - VipsForeignTiffPredictor predictor, + VipsForeignTiffPredictor predictor, char *profile, gboolean tile, int tile_width, int tile_height, gboolean pyramid, diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index 62c1cbbf..cd11e453 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -92,6 +92,8 @@ * - ignore large XMP * 14/10/19 * - revise for target IO + * 18/2/20 Elad-Laufer + * - add subsample_mode, deprecate no_subsample */ /* @@ -481,7 +483,7 @@ write_vips( Write *write, int qfac, const char *profile, gboolean optimize_coding, gboolean progressive, gboolean strip, gboolean trellis_quant, gboolean overshoot_deringing, gboolean optimize_scans, int quant_table, - VipsForeignJpegSubsample subsample_mode) + VipsForeignJpegSubsample subsample_mode ) { VipsImage *in; J_COLOR_SPACE space; @@ -628,24 +630,15 @@ write_vips( Write *write, int qfac, const char *profile, if( progressive ) jpeg_simple_progression( &write->cinfo ); - switch ( subsample_mode ) { - case VIPS_FOREIGN_JPEG_SUBSAMPLE_ON: - break; - case VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO: - /* Turn off chroma subsampling. Follow IM and do it automatically for - * high Q. - */ - if( qfac < 90 ) - break; - case VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF: - default: - { - int i; - for ( i = 0; i < in->Bands; i++ ) { - write->cinfo.comp_info[i].h_samp_factor = 1; - write->cinfo.comp_info[i].v_samp_factor = 1; - } - } + if( subsample_mode == VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF || + (subsample_mode == VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO && + qfac >= 90) ) { + int i; + + for( i = 0; i < in->Bands; i++ ) { + write->cinfo.comp_info[i].h_samp_factor = 1; + write->cinfo.comp_info[i].v_samp_factor = 1; + } } /* Don't write the APP0 JFIF headers if we are stripping. @@ -783,8 +776,8 @@ vips__jpeg_write_target( VipsImage *in, VipsTarget *target, int Q, const char *profile, gboolean optimize_coding, gboolean progressive, gboolean strip, gboolean trellis_quant, - gboolean overshoot_deringing, gboolean optimize_scans, - int quant_table, VipsForeignJpegSubsample subsample_mode) + gboolean overshoot_deringing, gboolean optimize_scans, + int quant_table, VipsForeignJpegSubsample subsample_mode) { Write *write; diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 0f25c52a..da9a82a2 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -369,11 +369,14 @@ int vips_openslideload( const char *filename, VipsImage **out, ... ) * @VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO: default preset * @VIPS_FOREIGN_JPEG_SUBSAMPLE_ON: always perform subsampling * @VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF: never perform subsampling + * + * Set jpeg subsampling mode. */ typedef enum { - VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO, - VIPS_FOREIGN_JPEG_SUBSAMPLE_ON, - VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF + VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO, + VIPS_FOREIGN_JPEG_SUBSAMPLE_ON, + VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF, + VIPS_FOREIGN_JPEG_SUBSAMPLE_LAST } VipsForeignJpegSubsample; int vips_jpegload( const char *filename, VipsImage **out, ... ) diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index e9069cd2..8a748a7d 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -508,6 +508,7 @@ vips_foreign_jpeg_subsample_get_type( void ) {VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO, "VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO", "auto"}, {VIPS_FOREIGN_JPEG_SUBSAMPLE_ON, "VIPS_FOREIGN_JPEG_SUBSAMPLE_ON", "on"}, {VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF, "VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF", "off"}, + {VIPS_FOREIGN_JPEG_SUBSAMPLE_LAST, "VIPS_FOREIGN_JPEG_SUBSAMPLE_LAST", "last"}, {0, NULL, NULL} };