Merge branch 'master' of github.com:jcupitt/libvips
This commit is contained in:
commit
88a9ebd74a
16
configure.ac
16
configure.ac
@ -696,6 +696,22 @@ FIND_JPEG(
|
||||
with_jpeg=no
|
||||
])
|
||||
|
||||
# JPEG extension parameters available in libjpeg-turbo >=1.5.0, mozjpeg >=3.0
|
||||
if test x"$with_jpeg" = "xyes"; then
|
||||
AC_MSG_CHECKING([for JPEG extension parameters])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdio.h>
|
||||
#include <jpeglib.h>
|
||||
]], [[
|
||||
J_BOOLEAN_PARAM test;
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_JPEG_EXT_PARAMS],1,[libjpeg has extension parameters])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
fi
|
||||
|
||||
# libexif
|
||||
AC_ARG_WITH([libexif],
|
||||
AS_HELP_STRING([--without-libexif], [build without libexif (default: test)]))
|
||||
|
@ -2080,6 +2080,9 @@ vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
* @interlace: %gboolean, write an interlaced (progressive) jpeg
|
||||
* @strip: %gboolean, remove all metadata from image
|
||||
* @no-subsample: %gboolean, disable chroma subsampling
|
||||
* @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
|
||||
*
|
||||
* Write a VIPS image to a file as JPEG.
|
||||
*
|
||||
@ -2117,6 +2120,20 @@ vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
* 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.
|
||||
*
|
||||
* If @trellis_quant is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0), apply trellis quantisation to each 8x8 block.
|
||||
* Reduces file size but increases compression time.
|
||||
*
|
||||
* If @overshoot_deringing is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0), apply overshooting to samples with extreme values
|
||||
* for example 0 and 255 for 8-bit. Overshooting may reduce ringing artifacts
|
||||
* from compression, in particular in areas where black text appears on a
|
||||
* white background.
|
||||
*
|
||||
* If @optimize_scans is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0), split the spectrum of DCT coefficients into
|
||||
* separate scans. Reduces file size but increases compression time.
|
||||
*
|
||||
* See also: vips_jpegsave_buffer(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
@ -2149,6 +2166,9 @@ vips_jpegsave( VipsImage *in, const char *filename, ... )
|
||||
* @interlace: write an interlaced (progressive) jpeg
|
||||
* @strip: remove all metadata from image
|
||||
* @no-subsample: disable chroma subsampling
|
||||
* @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
|
||||
*
|
||||
* As vips_jpegsave(), but save to a memory buffer.
|
||||
*
|
||||
@ -2200,6 +2220,9 @@ vips_jpegsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||
* @optimize_coding: compute optimal Huffman coding tables
|
||||
* @strip: remove all metadata from image
|
||||
* @no-subsample: disable chroma subsampling
|
||||
* @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
|
||||
*
|
||||
* As vips_jpegsave(), but save as a mime jpeg on stdout.
|
||||
*
|
||||
|
@ -91,6 +91,18 @@ typedef struct _VipsForeignSaveJpeg {
|
||||
*/
|
||||
gboolean no_subsample;
|
||||
|
||||
/* Apply trellis quantisation to each 8x8 block.
|
||||
*/
|
||||
gboolean trellis_quant;
|
||||
|
||||
/* Apply overshooting to samples with extreme values e.g. 0 & 255 for 8-bit.
|
||||
*/
|
||||
gboolean overshoot_deringing;
|
||||
|
||||
/* Split the spectrum of DCT coefficients into separate scans.
|
||||
*/
|
||||
gboolean optimize_scans;
|
||||
|
||||
} VipsForeignSaveJpeg;
|
||||
|
||||
typedef VipsForeignSaveClass VipsForeignSaveJpegClass;
|
||||
@ -161,6 +173,27 @@ vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignSaveJpeg, no_subsample ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "trellis_quant", 15,
|
||||
_( "Trellis quantisation" ),
|
||||
_( "Apply trellis quantisation to each 8x8 block" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveJpeg, trellis_quant ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "overshoot_deringing", 16,
|
||||
_( "Overshoot de-ringing" ),
|
||||
_( "Apply overshooting to samples with extreme values" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveJpeg, overshoot_deringing ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "optimize_scans", 17,
|
||||
_( "Optimize scans" ),
|
||||
_( "Split the spectrum of DCT coefficients into separate scans" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSaveJpeg, optimize_scans ),
|
||||
FALSE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -196,7 +229,8 @@ vips_foreign_save_jpeg_file_build( VipsObject *object )
|
||||
|
||||
if( vips__jpeg_write_file( save->ready, file->filename,
|
||||
jpeg->Q, jpeg->profile, jpeg->optimize_coding,
|
||||
jpeg->interlace, save->strip, jpeg->no_subsample ) )
|
||||
jpeg->interlace, save->strip, jpeg->no_subsample,
|
||||
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->optimize_scans) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -259,7 +293,8 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object )
|
||||
|
||||
if( vips__jpeg_write_buffer( save->ready,
|
||||
&obuf, &olen, jpeg->Q, jpeg->profile, jpeg->optimize_coding,
|
||||
jpeg->interlace, save->strip, jpeg->no_subsample ) )
|
||||
jpeg->interlace, save->strip, jpeg->no_subsample,
|
||||
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->optimize_scans) )
|
||||
return( -1 );
|
||||
|
||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||
@ -321,7 +356,8 @@ vips_foreign_save_jpeg_mime_build( VipsObject *object )
|
||||
|
||||
if( vips__jpeg_write_buffer( save->ready,
|
||||
&obuf, &olen, jpeg->Q, jpeg->profile, jpeg->optimize_coding,
|
||||
jpeg->interlace, save->strip, jpeg->no_subsample ) )
|
||||
jpeg->interlace, save->strip, jpeg->no_subsample,
|
||||
jpeg->trellis_quant, jpeg->overshoot_deringing, jpeg->optimize_scans) )
|
||||
return( -1 );
|
||||
|
||||
printf( "Content-length: %zd\r\n", olen );
|
||||
|
@ -143,7 +143,9 @@ read_free( Read *read )
|
||||
VIPS_FREEF( DestroyImage, read->image );
|
||||
VIPS_FREEF( DestroyImageInfo, read->image_info );
|
||||
VIPS_FREE( read->frames );
|
||||
DestroyExceptionInfo( &read->exception );
|
||||
if ( (&read->exception)->signature == MagickSignature ) {
|
||||
DestroyExceptionInfo( &read->exception );
|
||||
}
|
||||
VIPS_FREEF( vips_g_mutex_free, read->lock );
|
||||
}
|
||||
|
||||
|
@ -861,7 +861,8 @@ write_jpeg_block( VipsRegion *region, VipsRect *area, void *a )
|
||||
static int
|
||||
write_vips( Write *write, int qfac, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive, gboolean strip,
|
||||
gboolean no_subsample )
|
||||
gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans )
|
||||
{
|
||||
VipsImage *in;
|
||||
J_COLOR_SPACE space;
|
||||
@ -909,6 +910,14 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
if( !(write->row_pointer = VIPS_ARRAY( NULL, in->Ysize, JSAMPROW )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef HAVE_JPEG_EXT_PARAMS
|
||||
/* Reset compression profile to libjpeg defaults
|
||||
*/
|
||||
if( jpeg_c_int_param_supported( &write->cinfo, JINT_COMPRESS_PROFILE ) ) {
|
||||
jpeg_c_set_int_param( &write->cinfo, JINT_COMPRESS_PROFILE, JCP_FASTEST );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Rest to default.
|
||||
*/
|
||||
jpeg_set_defaults( &write->cinfo );
|
||||
@ -918,6 +927,64 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
*/
|
||||
write->cinfo.optimize_coding = optimize_coding;
|
||||
|
||||
#ifdef HAVE_JPEG_EXT_PARAMS
|
||||
/* Apply trellis quantisation to each 8x8 block. Infers "optimize_coding".
|
||||
*/
|
||||
if( trellis_quant ) {
|
||||
if ( jpeg_c_bool_param_supported(
|
||||
&write->cinfo, JBOOLEAN_TRELLIS_QUANT ) ) {
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_TRELLIS_QUANT, TRUE );
|
||||
write->cinfo.optimize_coding = TRUE;
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s", _( "trellis_quant unsupported" ) );
|
||||
}
|
||||
}
|
||||
/* Apply overshooting to samples with extreme values e.g. 0 & 255 for 8-bit.
|
||||
*/
|
||||
if( overshoot_deringing ) {
|
||||
if ( jpeg_c_bool_param_supported(
|
||||
&write->cinfo, JBOOLEAN_OVERSHOOT_DERINGING ) ) {
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_OVERSHOOT_DERINGING, TRUE );
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s", _( "overshoot_deringing unsupported" ) );
|
||||
}
|
||||
}
|
||||
/* Split the spectrum of DCT coefficients into separate scans.
|
||||
* Requires progressive output. Must be set before jpeg_simple_progression.
|
||||
*/
|
||||
if( optimize_scans ) {
|
||||
if( progressive ) {
|
||||
if( jpeg_c_bool_param_supported(
|
||||
&write->cinfo, JBOOLEAN_OPTIMIZE_SCANS ) ) {
|
||||
jpeg_c_set_bool_param( &write->cinfo, JBOOLEAN_OPTIMIZE_SCANS, TRUE );
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring optimize_scans" ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s",
|
||||
_( "Ignoring optimize_scans for baseline" ) );
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Using jpeglib.h without extension parameters, warn of ignored options.
|
||||
*/
|
||||
if ( trellis_quant ) {
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring trellis_quant" ) );
|
||||
}
|
||||
if ( overshoot_deringing ) {
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring overshoot_deringing" ) );
|
||||
}
|
||||
if ( optimize_scans ) {
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring optimize_scans" ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable progressive write.
|
||||
*/
|
||||
if( progressive )
|
||||
@ -982,7 +1049,8 @@ int
|
||||
vips__jpeg_write_file( VipsImage *in,
|
||||
const char *filename, int Q, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive, gboolean strip,
|
||||
gboolean no_subsample )
|
||||
gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
@ -1013,8 +1081,8 @@ vips__jpeg_write_file( VipsImage *in,
|
||||
/* Convert!
|
||||
*/
|
||||
if( write_vips( write,
|
||||
Q, profile, optimize_coding, progressive, strip,
|
||||
no_subsample ) ) {
|
||||
Q, profile, optimize_coding, progressive, strip, no_subsample,
|
||||
trellis_quant, overshoot_deringing, optimize_scans ) ) {
|
||||
write_destroy( write );
|
||||
return( -1 );
|
||||
}
|
||||
@ -1262,7 +1330,8 @@ int
|
||||
vips__jpeg_write_buffer( VipsImage *in,
|
||||
void **obuf, size_t *olen, int Q, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive,
|
||||
gboolean strip, gboolean no_subsample )
|
||||
gboolean strip, gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
@ -1292,8 +1361,8 @@ vips__jpeg_write_buffer( VipsImage *in,
|
||||
/* Convert!
|
||||
*/
|
||||
if( write_vips( write,
|
||||
Q, profile, optimize_coding, progressive, strip,
|
||||
no_subsample ) ) {
|
||||
Q, profile, optimize_coding, progressive, strip, no_subsample,
|
||||
trellis_quant, overshoot_deringing, optimize_scans ) ) {
|
||||
write_destroy( write );
|
||||
|
||||
return( -1 );
|
||||
|
@ -40,11 +40,13 @@ extern const char *vips__jpeg_suffs[];
|
||||
int vips__jpeg_write_file( VipsImage *in,
|
||||
const char *filename, int Q, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive, gboolean strip,
|
||||
gboolean no_subsample );
|
||||
gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans );
|
||||
int vips__jpeg_write_buffer( VipsImage *in,
|
||||
void **obuf, size_t *olen, int Q, const char *profile,
|
||||
gboolean optimize_coding, gboolean progressive, gboolean strip,
|
||||
gboolean no_subsample );
|
||||
gboolean no_subsample, gboolean trellis_quant,
|
||||
gboolean overshoot_deringing, gboolean optimize_scans );
|
||||
|
||||
int vips__isjpeg_buffer( void *buf, size_t len );
|
||||
int vips__isjpeg( const char *filename );
|
||||
|
Loading…
Reference in New Issue
Block a user