Merge branch 'master' into libspng-experiment
This commit is contained in:
commit
df4f03863e
@ -19,6 +19,8 @@
|
||||
- flood fill could stop half-way for some very complex shapes
|
||||
- better handling of unaligned reads in multipage tiffs [petoor]
|
||||
- add experimental libspng reader
|
||||
- mark old --delete option to vipsthumbnail as deprecated [UweOhse]
|
||||
- png save with a bad ICC profile just gives a warning
|
||||
|
||||
24/4/20 started 8.9.3
|
||||
- better iiif tile naming [IllyaMoskvin]
|
||||
|
@ -267,10 +267,11 @@ $ ls -l tn_shark.jpg
|
||||
-rw-r–r– 1 john john 7295 Nov 9 14:33 tn_shark.jpg
|
||||
```
|
||||
|
||||
Now encode with sRGB and delete any embedded profile:
|
||||
Now transform to sRGB and don't attach a profile (you can also use `strip`,
|
||||
though that will remove *all* metadata from the image):
|
||||
|
||||
```
|
||||
$ vipsthumbnail shark.jpg --eprofile srgb --delete
|
||||
$ vipsthumbnail shark.jpg --eprofile srgb -o tn_shark.jpg[profile=none]
|
||||
$ ls -l tn_shark.jpg
|
||||
-rw-r–r– 1 john john 4229 Nov 9 14:33 tn_shark.jpg
|
||||
```
|
||||
@ -307,6 +308,7 @@ Putting all this together, I suggest this as a sensible set of options:
|
||||
```
|
||||
$ vipsthumbnail fred.jpg \
|
||||
--size 128 \
|
||||
--eprofile srgb \
|
||||
-o tn_%s.jpg[optimize_coding,strip] \
|
||||
--eprofile srgb
|
||||
```
|
||||
|
@ -126,10 +126,11 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
#define CAST_SHORT( X ) VIPS_CLIP( SHRT_MIN, (X), SHRT_MAX )
|
||||
|
||||
/* We know the source cannot be the same as the dest, so we will only use
|
||||
* CAST_UINT() for an INT source, and vice versa.
|
||||
* CAST_UINT() for an INT source, and vice versa. We don't need to clip to
|
||||
* INT_MAX, since float->int does that for us.
|
||||
*/
|
||||
#define CAST_UINT( X ) VIPS_MAX( 0, (X) )
|
||||
#define CAST_INT( X ) VIPS_MIN( (X), INT_MAX )
|
||||
#define CAST_INT( X ) (X)
|
||||
|
||||
/* Rightshift an integer type, ie. sizeof(ITYPE) > sizeof(OTYPE).
|
||||
*/
|
||||
@ -222,7 +223,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
OTYPE * restrict q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
q[x] = p[x]; \
|
||||
q[x] = CAST( p[x] ); \
|
||||
}
|
||||
|
||||
/* Cast complex types to an int type. Just take the real part.
|
||||
@ -232,7 +233,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
OTYPE * restrict q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
q[x] = p[0]; \
|
||||
q[x] = CAST( p[0] ); \
|
||||
p += 2; \
|
||||
} \
|
||||
}
|
||||
|
@ -418,10 +418,8 @@ vips_image_resolution_from_exif( VipsImage *image, ExifData *ed )
|
||||
|
||||
switch( unit ) {
|
||||
case 1:
|
||||
/* No unit ... just pass the fields straight to vips.
|
||||
/* No units, instead xres / yres gives the pixel aspect ratio.
|
||||
*/
|
||||
vips_image_set_string( image,
|
||||
VIPS_META_RESOLUTION_UNIT, "none" );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -106,6 +106,8 @@
|
||||
* - restart after minimise
|
||||
* 14/10/19
|
||||
* - revise for source IO
|
||||
* 5/5/20 angelmixu
|
||||
* - better handling of JFIF res unit 0
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -504,24 +506,28 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out )
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the jfif resolution. exif may overwrite this later.
|
||||
/* Get the jfif resolution. exif may overwrite this later. Default to
|
||||
* 72dpi (as EXIF does).
|
||||
*/
|
||||
xres = 1.0;
|
||||
yres = 1.0;
|
||||
xres = 72.0 / 25.4;
|
||||
yres = 72.0 / 25.4;
|
||||
if( cinfo->saw_JFIF_marker &&
|
||||
cinfo->X_density != 1U &&
|
||||
cinfo->Y_density != 1U ) {
|
||||
#ifdef DEBUG
|
||||
printf( "read_jpeg_header: seen jfif _density %d, %d\n",
|
||||
cinfo->X_density, cinfo->Y_density );
|
||||
printf( "read_jpeg_header: jfif _density %d, %d, unit %d\n",
|
||||
cinfo->X_density, cinfo->Y_density,
|
||||
cinfo->density_unit );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
switch( cinfo->density_unit ) {
|
||||
case 0:
|
||||
/* None. Just set.
|
||||
/* X_density / Y_density gives the pixel aspect ratio.
|
||||
* Leave xres, but adjust yres.
|
||||
*/
|
||||
xres = cinfo->X_density;
|
||||
yres = cinfo->Y_density;
|
||||
if( cinfo->Y_density > 0 )
|
||||
yres = xres * cinfo->X_density /
|
||||
cinfo->Y_density;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -841,7 +841,7 @@ G_DEFINE_TYPE( VipsForeignLoadMagick7Buffer, vips_foreign_load_magick7_buffer,
|
||||
static gboolean
|
||||
vips_foreign_load_magick7_buffer_is_a_buffer( const void *buf, size_t len )
|
||||
{
|
||||
return( magick_ismagick( (const unsigned char *) buf, len ) );
|
||||
return( len > 10 && magick_ismagick( (const unsigned char *) buf, len ) );
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -77,6 +77,8 @@
|
||||
* - restart after minimise
|
||||
* 14/10/19
|
||||
* - revise for connection IO
|
||||
* 11/5/20
|
||||
* - only warn for saving bad profiles, don't fail
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1047,10 +1049,28 @@ write_vips( Write *write,
|
||||
"of ICC profile\n", length );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
png_set_iCCP( write->pPng, write->pInfo, "icc",
|
||||
PNG_COMPRESSION_TYPE_BASE,
|
||||
(void *) data, length );
|
||||
/* We need to ignore any errors from png_set_iCCP()
|
||||
* since we want to drop incompatible profiles rather
|
||||
* than simply failing.
|
||||
*/
|
||||
if( setjmp( png_jmpbuf( write->pPng ) ) ) {
|
||||
/* Silent ignore of error.
|
||||
*/
|
||||
g_warning( "bad ICC profile not saved" );
|
||||
}
|
||||
else {
|
||||
/* This will jump back to the line above on
|
||||
* error.
|
||||
*/
|
||||
png_set_iCCP( write->pPng, write->pInfo, "icc",
|
||||
PNG_COMPRESSION_TYPE_BASE,
|
||||
(void *) data, length );
|
||||
}
|
||||
|
||||
/* And restore the setjmp.
|
||||
*/
|
||||
if( setjmp( png_jmpbuf( write->pPng ) ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips_image_get_typeof( in, VIPS_META_XMP_NAME ) ) {
|
||||
|
@ -77,7 +77,7 @@ vips_hist_norm_build( VipsObject *object )
|
||||
VipsHistNorm *norm = (VipsHistNorm *) object;
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 3 );
|
||||
|
||||
guint64 px;
|
||||
guint64 new_max;
|
||||
int bands;
|
||||
double *a, *b;
|
||||
int y;
|
||||
@ -95,13 +95,13 @@ vips_hist_norm_build( VipsObject *object )
|
||||
|
||||
/* Scale each channel by px / channel max
|
||||
*/
|
||||
px = VIPS_IMAGE_N_PELS( norm->in );
|
||||
new_max = VIPS_IMAGE_N_PELS( norm->in ) - 1;
|
||||
bands = norm->in->Bands;
|
||||
if( !(a = VIPS_ARRAY( object, bands, double )) ||
|
||||
!(b = VIPS_ARRAY( object, bands, double )) )
|
||||
return( -1 );
|
||||
for( y = 0; y < bands; y++ ) {
|
||||
a[y] = px / *VIPS_MATRIX( t[0], 1, y + 1 );
|
||||
a[y] = new_max / *VIPS_MATRIX( t[0], 1, y + 1 );
|
||||
b[y] = 0;
|
||||
}
|
||||
|
||||
@ -110,9 +110,9 @@ vips_hist_norm_build( VipsObject *object )
|
||||
|
||||
/* Make output format as small as we can.
|
||||
*/
|
||||
if( px <= 256 )
|
||||
if( new_max <= 255 )
|
||||
fmt = VIPS_FORMAT_UCHAR;
|
||||
else if( px <= 65536 )
|
||||
else if( new_max <= 65535 )
|
||||
fmt = VIPS_FORMAT_USHORT;
|
||||
else
|
||||
fmt = VIPS_FORMAT_UINT;
|
||||
@ -161,8 +161,9 @@ vips_hist_norm_init( VipsHistNorm *hist_norm )
|
||||
* @out: (out): output image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Normalise histogram ... normalise range to make it square (ie. max ==
|
||||
* number of elements). Normalise each band separately.
|
||||
* Normalise histogram. The maximum of each band becomes equal to the maximum
|
||||
* index, so for example the max for a uchar image becomes 255.
|
||||
* Normalise each band separately.
|
||||
*
|
||||
* See also: vips_hist_cum().
|
||||
*
|
||||
|
@ -101,19 +101,19 @@ vips_reduce_get_points( VipsKernel kernel, double shrink )
|
||||
return( 1 );
|
||||
|
||||
case VIPS_KERNEL_LINEAR:
|
||||
return( rint( 2 * shrink ) + 1 );
|
||||
return( 2 * rint( shrink ) + 1 );
|
||||
|
||||
case VIPS_KERNEL_CUBIC:
|
||||
case VIPS_KERNEL_MITCHELL:
|
||||
return( rint( 4 * shrink ) + 1 );
|
||||
return( 2 * rint( 2 * shrink ) + 1 );
|
||||
|
||||
case VIPS_KERNEL_LANCZOS2:
|
||||
/* Needs to be in sync with calculate_coefficients_lanczos().
|
||||
*/
|
||||
return( rint( 2 * 2 * shrink ) + 1 );
|
||||
return( 2 * rint( 2 * shrink ) + 1 );
|
||||
|
||||
case VIPS_KERNEL_LANCZOS3:
|
||||
return( rint( 2 * 3 * shrink ) + 1 );
|
||||
return( 2 * rint( 3 * shrink ) + 1 );
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -321,14 +321,15 @@ calculate_coefficients_triangle( double *c,
|
||||
{
|
||||
/* Needs to be in sync with vips_reduce_get_points().
|
||||
*/
|
||||
const int n_points = rint( 2 * shrink ) + 1;
|
||||
const int n_points = 2 * rint( shrink ) + 1;
|
||||
const double half = x + n_points / 2.0 - 1;
|
||||
|
||||
int i;
|
||||
double sum;
|
||||
|
||||
sum = 0;
|
||||
for( i = 0; i < n_points; i++ ) {
|
||||
double xp = (i - (shrink - 0.5) - x) / shrink;
|
||||
const double xp = (i - half) / shrink;
|
||||
|
||||
double l;
|
||||
|
||||
@ -358,14 +359,15 @@ calculate_coefficients_cubic( double *c,
|
||||
{
|
||||
/* Needs to be in sync with vips_reduce_get_points().
|
||||
*/
|
||||
const int n_points = rint( 4 * shrink ) + 1;
|
||||
const int n_points = 2 * rint( 2 * shrink ) + 1;
|
||||
const double half = x + n_points / 2.0 - 1;
|
||||
|
||||
int i;
|
||||
double sum;
|
||||
|
||||
sum = 0;
|
||||
for( i = 0; i < n_points; i++ ) {
|
||||
const double xp = (i - (2 * shrink - 1) - x) / shrink;
|
||||
const double xp = (i - half) / shrink;
|
||||
const double axp = VIPS_FABS( xp );
|
||||
const double axp2 = axp * axp;
|
||||
const double axp3 = axp2 * axp;
|
||||
@ -406,14 +408,15 @@ calculate_coefficients_lanczos( double *c,
|
||||
{
|
||||
/* Needs to be in sync with vips_reduce_get_points().
|
||||
*/
|
||||
const int n_points = rint( 2 * a * shrink ) + 1;
|
||||
const int n_points = 2 * rint( a * shrink ) + 1;
|
||||
const double half = x + n_points / 2.0 - 1;
|
||||
|
||||
int i;
|
||||
double sum;
|
||||
|
||||
sum = 0;
|
||||
for( i = 0; i < n_points; i++ ) {
|
||||
double xp = (i - (n_points - 2) / 2 - x) / shrink;
|
||||
double xp = (i - half) / shrink;
|
||||
|
||||
double l;
|
||||
|
||||
|
@ -1238,8 +1238,11 @@ vips_thumbnail_buffer_init( VipsThumbnailBuffer *buffer )
|
||||
* * @import_profile: %gchararray, fallback import ICC profile
|
||||
* * @export_profile: %gchararray, export ICC profile
|
||||
* * @intent: #VipsIntent, rendering intent
|
||||
* * @option_string: %gchararray, extra loader options
|
||||
*
|
||||
* Exacty as vips_thumbnail(), but read from a memory buffer.
|
||||
* Exacty as vips_thumbnail(), but read from a memory buffer. One extra
|
||||
* optional argument, @option_string, lets you pass options to the underlying
|
||||
* loader.
|
||||
*
|
||||
* See also: vips_thumbnail().
|
||||
*
|
||||
@ -1414,8 +1417,11 @@ vips_thumbnail_source_init( VipsThumbnailSource *source )
|
||||
* * @import_profile: %gchararray, fallback import ICC profile
|
||||
* * @export_profile: %gchararray, export ICC profile
|
||||
* * @intent: #VipsIntent, rendering intent
|
||||
* * @option_string: %gchararray, extra loader options
|
||||
*
|
||||
* Exactly as vips_thumbnail(), but read from a source.
|
||||
* Exacty as vips_thumbnail(), but read from a source. One extra
|
||||
* optional argument, @option_string, lets you pass options to the underlying
|
||||
* loader.
|
||||
*
|
||||
* See also: vips_thumbnail().
|
||||
*
|
||||
@ -1520,7 +1526,12 @@ vips_thumbnail_image_init( VipsThumbnailImage *image )
|
||||
* * @export_profile: %gchararray, export ICC profile
|
||||
* * @intent: #VipsIntent, rendering intent
|
||||
*
|
||||
* Exacty as vips_thumbnail(), but read from an existing image.
|
||||
* Exacty as vips_thumbnail(), but read from an existing image.
|
||||
*
|
||||
* This operation
|
||||
* is not able to exploit shrink-on-load features of image load libraries, so
|
||||
* it can be much slower than `vips_thumbnail()` and produce poorer quality
|
||||
* output. Only use it if you really have to.
|
||||
*
|
||||
* See also: vips_thumbnail().
|
||||
*
|
||||
|
@ -100,6 +100,8 @@
|
||||
* - add --no-rotate
|
||||
* - add --import-profile / --export-profile names
|
||||
* - back to -o for output
|
||||
* 29/2/20
|
||||
* - deprecate --delete
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -128,7 +130,6 @@ static VipsSize size_restriction = VIPS_SIZE_BOTH;
|
||||
static char *output_format = "tn_%s.jpg";
|
||||
static char *export_profile = NULL;
|
||||
static char *import_profile = NULL;
|
||||
static gboolean delete_profile = FALSE;
|
||||
static gboolean linear_processing = FALSE;
|
||||
static gboolean crop_image = FALSE;
|
||||
static gboolean no_rotate_image = FALSE;
|
||||
@ -137,6 +138,7 @@ static char *thumbnail_intent = NULL;
|
||||
|
||||
/* Deprecated and unused.
|
||||
*/
|
||||
static gboolean delete_profile = FALSE;
|
||||
static gboolean nosharpen = FALSE;
|
||||
static gboolean nodelete_profile = FALSE;
|
||||
static gboolean verbose = FALSE;
|
||||
@ -172,9 +174,9 @@ static GOptionEntry options[] = {
|
||||
G_OPTION_ARG_STRING, &thumbnail_intent,
|
||||
N_( "ICC transform with INTENT" ),
|
||||
N_( "INTENT" ) },
|
||||
{ "delete", 'd', 0,
|
||||
{ "delete", 'd', G_OPTION_FLAG_HIDDEN,
|
||||
G_OPTION_ARG_NONE, &delete_profile,
|
||||
N_( "delete profile from exported image" ), NULL },
|
||||
N_( "(deprecated, does nothing)" ), NULL },
|
||||
{ "no-rotate", 0, 0,
|
||||
G_OPTION_ARG_NONE, &no_rotate_image,
|
||||
N_( "don't auto-rotate" ), NULL },
|
||||
|
Loading…
Reference in New Issue
Block a user