Merge branch 'master' into revise-thumbnail

This commit is contained in:
John Cupitt 2019-03-02 22:06:23 +00:00
commit 15ee957ea9
30 changed files with 837 additions and 739 deletions

View File

@ -47,6 +47,9 @@ addons:
sources:
# use imagemagick 6.9.7-4 instead than 6.8.9-9
- sourceline: 'ppa:opencpu/imagemagick'
# add support for HEIF files
- sourceline: 'ppa:strukturag/libheif'
- sourceline: 'ppa:strukturag/libde265'
packages:
- automake
- gtk-doc-tools
@ -59,6 +62,7 @@ addons:
# missing on xenial, unfortunately
# - libwebpmux2
- libtiff5-dev
- libheif-dev
- libexpat1-dev
- swig
- libmagick++-dev

View File

@ -25,6 +25,8 @@
- tilecache speedups
- add vips_heifload(), vips_heifsave()
- add heif thumbnail support to vips_thumbnail()
- free threadpool earlier, reducing mem growth for some long-running
processes [jtorresfabra]
4/1/19 started 8.7.4
- magickload with magick6 API did not chain exceptions correctly causing a
@ -87,6 +89,7 @@
- escape ASCII control characters in XML
- magickload now sniffs some file types itself
- update radiance load from upstream
- add region_shrink to tiffsave
- mapim could fail for float index images with coordinates out of int range
- scale openexr alpha to 0 - 255
- close input earlier, when we can [kleisauke]
@ -333,6 +336,7 @@
- dzsave puts vips-properties.xml in the main dir for gm and zoomify layouts
- resize and reduce have @centre option for centre convention downsampling
- vipsthumbnail uses centre convention to better match imagemagick
_ add vips_foreign_get_suffixes()
19/8/16 started 8.3.4
- better transparency handling in gifload, thanks diegocsandrim

View File

@ -143,8 +143,7 @@ Clang static analysis:
Clang dynamic analysis:
$ FLAGS="-O1 -g -fsanitize=address"
$ FLAGS="$FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls"
$ FLAGS="-g -O1 -fno-omit-frame-pointer"
$ CC=clang CXX=clang++ LD=clang \
CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" LDFLAGS=-fsanitize=address \
./configure --prefix=/home/john/vips

View File

@ -927,6 +927,18 @@ if test x"$with_heif" != x"no"; then
)
fi
# color profile support added in 1.3.3
if test x"$with_heif" = x"yes"; then
save_LIBS="$LIBS"
LIBS="$LIBS $HEIF_LIBS"
AC_CHECK_FUNCS(heif_image_handle_get_raw_color_profile,[
AC_DEFINE(HAVE_HEIF_COLOR_PROFILE,1,
[define if you have heif_image_handle_get_raw_color_profile.])
],[]
)
LIBS="$save_LIBS"
fi
# pdfium
AC_ARG_WITH([pdfium],
AS_HELP_STRING([--without-pdfium], [build without pdfium (default: test)]))

View File

@ -27,6 +27,8 @@
* 3/12/13
* - add orc, though the speed improvement vs. gcc's auto-vectorizer
* seems very marginal
* 21/2/19
* - move orc init to first use of abs
*/
/*
@ -78,11 +80,39 @@ typedef VipsUnaryClass VipsAbsClass;
G_DEFINE_TYPE( VipsAbs, vips_abs, VIPS_TYPE_UNARY );
static void *
vips_abs_orc_init_cb( void *a )
{
VipsAbs *abs = (VipsAbs *) a;
VipsArithmeticClass *aclass = VIPS_ARITHMETIC_GET_CLASS( abs );
VipsVector *v;
vips_arithmetic_set_vector( aclass );
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_CHAR );
vips_vector_asm2( v, "absb", "d1", "s1" );
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_SHORT );
vips_vector_asm2( v, "absw", "d1", "s1" );
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_INT );
vips_vector_asm2( v, "absl", "d1", "s1" );
vips_arithmetic_compile( aclass );
return( NULL );
}
static int
vips_abs_build( VipsObject *object )
{
static GOnce once = G_ONCE_INIT;
VipsUnary *unary = (VipsUnary *) object;
VIPS_ONCE( &once, vips_abs_orc_init_cb, object );
if( unary->in &&
vips_band_format_isuint( unary->in->BandFmt ) )
return( vips_unary_copy( unary ) );
@ -224,8 +254,6 @@ vips_abs_class_init( VipsAbsClass *class )
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class );
VipsVector *v;
object_class->nickname = "abs";
object_class->description = _( "absolute value of an image" );
object_class->build = vips_abs_build;
@ -233,18 +261,6 @@ vips_abs_class_init( VipsAbsClass *class )
aclass->process_line = vips_abs_buffer;
vips_arithmetic_set_format_table( aclass, vips_abs_format_table );
vips_arithmetic_set_vector( aclass );
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_CHAR );
vips_vector_asm2( v, "absb", "d1", "s1" );
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_SHORT );
vips_vector_asm2( v, "absw", "d1", "s1" );
v = vips_arithmetic_get_program( aclass, VIPS_FORMAT_INT );
vips_vector_asm2( v, "absl", "d1", "s1" );
vips_arithmetic_compile( aclass );
}
static void

View File

@ -104,7 +104,7 @@ vips_fallback_profile_get( const char *name, size_t *length )
for( p = vips_fallback_profile_list; p; p = p->next ) {
VipsFallbackProfile *fallback = (VipsFallbackProfile *) p->data;
if( strcasecmp( fallback->name, name ) == 0 ) {
if( g_ascii_strcasecmp( fallback->name, name ) == 0 ) {
*length = fallback->data_length;
return( fallback->data );
@ -128,7 +128,7 @@ vips_profile_load_build( VipsObject *object )
build( object ) )
return( -1 );
if( strcasecmp( load->name, "none" ) == 0 ) {
if( g_ascii_strcasecmp( load->name, "none" ) == 0 ) {
profile = NULL;
}
else if( (data = vips_fallback_profile_get( load->name, &length )) ) {

View File

@ -77,8 +77,13 @@ vips_eye_point( VipsPoint *point, int x, int y )
{
VipsEye *eye = (VipsEye *) point;
double c = eye->factor * VIPS_PI / (2 * (point->width - 1));
double h = ((point->height - 1) * (point->height - 1));
/* VIPS_MAX to prevent /0.
*/
int max_x = VIPS_MAX( point->width - 1, 1 );
int max_y = VIPS_MAX( point->height - 1, 1 );
double c = eye->factor * VIPS_PI / (2 * max_x);
double h = max_y * max_y;
return( y * y * cos( c * x * x ) / h );
}

View File

@ -58,8 +58,11 @@ vips_mask_point( VipsPoint *point, int x, int y )
{
VipsMask *mask = VIPS_MASK( point );
VipsMaskClass *class = VIPS_MASK_GET_CLASS( point );
int half_width = point->width / 2;
int half_height = point->height / 2;
/* VIPS_MAX to prevent /0.
*/
int half_width = VIPS_MAX( point->width / 2, 1 );
int half_height = VIPS_MAX( point->height / 2, 1 );
double result;

View File

@ -606,7 +606,7 @@ lookup_enum( GType type, const char *names[], const char *name )
return( value->value );
for( i = 0; names[i]; i++ )
if( strcasecmp( names[i], name ) == 0 )
if( g_ascii_strcasecmp( names[i], name ) == 0 )
return( i );
return( -1 );

View File

@ -127,10 +127,6 @@ vips_foreign_load_csv_class_init( VipsForeignLoadCsvClass *class )
foreign_class->suffs = vips__foreign_csv_suffs;
/* is_a() is not that quick ... lower the priority.
*/
foreign_class->priority = -50;
load_class->get_flags_filename =
vips_foreign_load_csv_get_flags_filename;
load_class->get_flags = vips_foreign_load_csv_get_flags;

View File

@ -1158,9 +1158,7 @@ strip_work( VipsThreadState *state, void *a )
}
}
#ifdef DEBUG
vips_object_sanity( VIPS_OBJECT( strip->image ) );
#endif /*DEBUG*/
g_assert( vips_object_sanity( VIPS_OBJECT( strip->image ) ) );
/* Extract relative to the strip top-left corner.
*/
@ -2198,16 +2196,16 @@ vips_foreign_save_dz_file_build( VipsObject *object )
*/
if( (p = strrchr( dz->basename, '.' )) ) {
if( !vips_object_argument_isset( object, "container" ) )
if( strcasecmp( p + 1, "zip" ) == 0 ||
strcasecmp( p + 1, "szi" ) == 0 )
if( g_ascii_strcasecmp( p + 1, "zip" ) == 0 ||
g_ascii_strcasecmp( p + 1, "szi" ) == 0 )
dz->container = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
/* Remove any legal suffix. We don't remove all suffixes
* since we might be writing to a dirname with a dot in.
*/
if( strcasecmp( p + 1, "zip" ) == 0 ||
strcasecmp( p + 1, "szi" ) == 0 ||
strcasecmp( p + 1, "dz" ) == 0 )
if( g_ascii_strcasecmp( p + 1, "zip" ) == 0 ||
g_ascii_strcasecmp( p + 1, "szi" ) == 0 ||
g_ascii_strcasecmp( p + 1, "dz" ) == 0 )
*p = '\0';
}

View File

@ -1694,6 +1694,78 @@ vips_foreign_find_save( const char *name )
return( G_OBJECT_CLASS_NAME( save_class ) );
}
static void *
vips_foreign_get_suffixes_count_cb( VipsForeignSaveClass *save_class,
void *a, void *b )
{
VipsForeignClass *foreign_class = VIPS_FOREIGN_CLASS( save_class );
int *n_fields = (int *) a;
int i;
if( foreign_class->suffs )
for( i = 0; foreign_class->suffs[i]; i++ )
*n_fields += 1;
return( NULL );
}
static void *
vips_foreign_get_suffixes_add_cb( VipsForeignSaveClass *save_class,
void *a, void *b )
{
VipsForeignClass *foreign_class = VIPS_FOREIGN_CLASS( save_class );
gchar ***p = (gchar ***) a;
int i;
if( foreign_class->suffs )
for( i = 0; foreign_class->suffs[i]; i++ ) {
**p = g_strdup( foreign_class->suffs[i] );
*p += 1;
}
return( NULL );
}
/**
* vips_foreign_get_suffixes: (method)
*
* Get a %NULL-terminated array listing all the supported suffixes.
*
* This is not the same as all the supported file types, since libvips
* detects image format for load by testing the first few bytes.
*
* Use vips_foreign_find_load() to detect type for a specific file.
*
* Free the return result with g_strfreev().
*
* Returns: (transfer full): all supported file extensions, as a
* %NULL-terminated array.
*/
gchar **
vips_foreign_get_suffixes( void )
{
int n_suffs;
gchar **suffs;
gchar **p;
n_suffs = 0;
(void) vips_foreign_map(
"VipsForeignSave",
(VipsSListMap2Fn) vips_foreign_get_suffixes_count_cb,
&n_suffs, NULL );
suffs = g_new0( gchar *, n_suffs + 1 );
p = suffs;
(void) vips_foreign_map(
"VipsForeignSave",
(VipsSListMap2Fn) vips_foreign_get_suffixes_add_cb,
&p, NULL );
return( suffs );
}
/* Kept for early vips8 API compat.
*/

View File

@ -302,7 +302,7 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
/* We need to skip the first four bytes of EXIF, they just
* contain the offset.
*/
if( strcasecmp( type, "exif" ) == 0 ) {
if( g_ascii_strcasecmp( type, "exif" ) == 0 ) {
data += 4;
length -= 4;
}
@ -312,9 +312,9 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
* XMP metadata is just attached with the "mime" type, and
* usually start with "<x:xmpmeta".
*/
if( strcasecmp( type, "exif" ) == 0 )
if( g_ascii_strcasecmp( type, "exif" ) == 0 )
vips_snprintf( name, 256, VIPS_META_EXIF_NAME );
else if( strcasecmp( type, "mime" ) == 0 &&
else if( g_ascii_strcasecmp( type, "mime" ) == 0 &&
vips_isprefix( "<x:xmpmeta", (const char *) data ) )
snprintf( name, 256, VIPS_META_XMP_NAME );
else
@ -323,7 +323,7 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
vips_image_set_blob( out, name,
(VipsCallbackFn) NULL, data, length );
if( strcasecmp( type, "exif" ) == 0 )
if( g_ascii_strcasecmp( type, "exif" ) == 0 )
(void) vips__exif_parse( out );
}
@ -356,6 +356,7 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
}
#endif /*DEBUG*/
#ifdef HAVE_HEIF_COLOR_PROFILE
/* FIXME should probably check the profile type ... lcms seems to be
* able to load at least rICC and prof.
*/
@ -381,6 +382,7 @@ vips_foreign_load_heif_set_header( VipsForeignLoadHeif *heif, VipsImage *out )
vips_image_set_blob( out, VIPS_META_ICC_NAME,
(VipsCallbackFn) NULL, data, length );
}
#endif /*HAVE_HEIF_COLOR_PROFILE*/
return( 0 );
}

View File

@ -162,6 +162,7 @@ vips_foreign_save_heif_write_page( VipsForeignSaveHeif *heif, int page )
struct heif_error error;
struct heif_encoding_options *options;
#ifdef HAVE_HEIF_COLOR_PROFILE
if( !save->strip &&
vips_image_get_typeof( save->ready, VIPS_META_ICC_NAME ) ) {
const void *data;
@ -184,6 +185,7 @@ vips_foreign_save_heif_write_page( VipsForeignSaveHeif *heif, int page )
return( -1 );
}
}
#endif /*HAVE_HEIF_COLOR_PROFILE*/
options = heif_encoding_options_alloc();
/* FIXME .. should be an option, though I don't know of any way to

View File

@ -266,7 +266,8 @@ vips_foreign_load_svg_parse( VipsForeignLoadSvg *svg, VipsImage *out )
rsvg_handle_set_dpi( svg->page, svg->dpi * svg->scale );
rsvg_handle_get_dimensions( svg->page, &dimensions );
if( width == dimensions.width && height == dimensions.height ) {
if( width == dimensions.width &&
height == dimensions.height ) {
/* SVG without width and height always reports the same
* dimensions regardless of dpi. Apply dpi/scale using
* cairo instead.
@ -348,11 +349,11 @@ vips_foreign_load_svg_generate( VipsRegion *or,
cairo_destroy( cr );
/* Cairo makes pre-multipled BRGA, we must byteswap and unpremultiply.
/* Cairo makes pre-multipled BRGA -- we must byteswap and unpremultiply.
*/
for( y = 0; y < r->height; y++ )
vips__cairo2rgba(
(guint32 *) VIPS_REGION_ADDR( or, r->left, r->top + y ),
(guint32 *) VIPS_REGION_ADDR( or, r->left, r->top + y ),
r->width );
return( 0 );

View File

@ -12,6 +12,8 @@
* - convert for jpg if jpg compression is on
* 19/10/17
* - predictor defaults to horizontal, reducing file size, usually
* 13/6/18
* - add region_shrink
*/
/*

View File

@ -176,6 +176,8 @@
* 24/10/17
* - no error on page-height not a factor of image height, just don't
* write multipage
* 13/6/18
* - add region_shrink
* 2/7/18
* - copy EXTRASAMPLES to pyramid layers
* 21/12/18

View File

@ -1077,7 +1077,8 @@ write_vips( Write *write,
return( -1 );
if( blob ) {
size_t length;
const void *data = vips_blob_get( blob, &length );
const void *data
= vips_blob_get( blob, &length );
#ifdef DEBUG
printf( "write_vips: attaching %zd bytes "
@ -1086,7 +1087,7 @@ write_vips( Write *write,
png_set_iCCP( write->pPng, write->pInfo,
"icc", PNG_COMPRESSION_TYPE_BASE,
data, length );
(void *) data, length );
vips_area_unref( (VipsArea *) blob );
}
@ -1105,7 +1106,8 @@ write_vips( Write *write,
#endif /*DEBUG*/
png_set_iCCP( write->pPng, write->pInfo, "icc",
PNG_COMPRESSION_TYPE_BASE, data, length );
PNG_COMPRESSION_TYPE_BASE,
(void *) data, length );
}

View File

@ -1,58 +1,16 @@
/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */
/* Generated data (by glib-mkenums) */
#ifndef VIPS_ENUM_TYPES_H
#define VIPS_ENUM_TYPES_H
G_BEGIN_DECLS
/* enumerations from "../../../libvips/include/vips/arithmetic.h" */
GType vips_operation_math_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MATH (vips_operation_math_get_type())
GType vips_operation_math2_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MATH2 (vips_operation_math2_get_type())
GType vips_operation_round_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_ROUND (vips_operation_round_get_type())
GType vips_operation_relational_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_RELATIONAL (vips_operation_relational_get_type())
GType vips_operation_boolean_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_BOOLEAN (vips_operation_boolean_get_type())
GType vips_operation_complex_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_COMPLEX (vips_operation_complex_get_type())
GType vips_operation_complex2_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_COMPLEX2 (vips_operation_complex2_get_type())
GType vips_operation_complexget_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_COMPLEXGET (vips_operation_complexget_get_type())
/* enumerations from "../../../libvips/include/vips/basic.h" */
GType vips_precision_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_PRECISION (vips_precision_get_type())
/* enumerations from "../../../libvips/include/vips/colour.h" */
GType vips_intent_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_INTENT (vips_intent_get_type())
GType vips_pcs_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_PCS (vips_pcs_get_type())
/* enumerations from "../../../libvips/include/vips/conversion.h" */
GType vips_extend_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_EXTEND (vips_extend_get_type())
GType vips_compass_direction_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_COMPASS_DIRECTION (vips_compass_direction_get_type())
GType vips_direction_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_DIRECTION (vips_direction_get_type())
GType vips_align_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ALIGN (vips_align_get_type())
GType vips_angle_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ANGLE (vips_angle_get_type())
GType vips_angle45_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ANGLE45 (vips_angle45_get_type())
GType vips_interesting_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_INTERESTING (vips_interesting_get_type())
GType vips_blend_mode_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_BLEND_MODE (vips_blend_mode_get_type())
/* enumerations from "../../../libvips/include/vips/convolution.h" */
GType vips_combine_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_COMBINE (vips_combine_get_type())
/* enumerations from "../../../libvips/include/vips/draw.h" */
GType vips_combine_mode_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_COMBINE_MODE (vips_combine_mode_get_type())
/* enumerations from "../../../libvips/include/vips/resample.h" */
GType vips_kernel_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_KERNEL (vips_kernel_get_type())
GType vips_size_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_SIZE (vips_size_get_type())
/* enumerations from "../../../libvips/include/vips/foreign.h" */
GType vips_foreign_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_FLAGS (vips_foreign_flags_get_type())
@ -74,6 +32,43 @@ GType vips_foreign_dz_depth_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_DZ_DEPTH (vips_foreign_dz_depth_get_type())
GType vips_foreign_dz_container_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_DZ_CONTAINER (vips_foreign_dz_container_get_type())
/* enumerations from "../../../libvips/include/vips/arithmetic.h" */
GType vips_operation_math_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MATH (vips_operation_math_get_type())
GType vips_operation_math2_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MATH2 (vips_operation_math2_get_type())
GType vips_operation_round_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_ROUND (vips_operation_round_get_type())
GType vips_operation_relational_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_RELATIONAL (vips_operation_relational_get_type())
GType vips_operation_boolean_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_BOOLEAN (vips_operation_boolean_get_type())
GType vips_operation_complex_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_COMPLEX (vips_operation_complex_get_type())
GType vips_operation_complex2_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_COMPLEX2 (vips_operation_complex2_get_type())
GType vips_operation_complexget_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_COMPLEXGET (vips_operation_complexget_get_type())
/* enumerations from "../../../libvips/include/vips/conversion.h" */
GType vips_extend_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_EXTEND (vips_extend_get_type())
GType vips_compass_direction_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_COMPASS_DIRECTION (vips_compass_direction_get_type())
GType vips_direction_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_DIRECTION (vips_direction_get_type())
GType vips_align_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ALIGN (vips_align_get_type())
GType vips_angle_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ANGLE (vips_angle_get_type())
GType vips_angle45_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ANGLE45 (vips_angle45_get_type())
GType vips_interesting_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_INTERESTING (vips_interesting_get_type())
GType vips_blend_mode_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_BLEND_MODE (vips_blend_mode_get_type())
/* enumerations from "../../../libvips/include/vips/util.h" */
GType vips_token_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_TOKEN (vips_token_get_type())
/* enumerations from "../../../libvips/include/vips/image.h" */
GType vips_demand_style_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_DEMAND_STYLE (vips_demand_style_get_type())
@ -87,26 +82,32 @@ GType vips_coding_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_CODING (vips_coding_get_type())
GType vips_access_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ACCESS (vips_access_get_type())
/* enumerations from "../../../libvips/include/vips/morphology.h" */
GType vips_operation_morphology_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MORPHOLOGY (vips_operation_morphology_get_type())
/* enumerations from "../../../libvips/include/vips/object.h" */
GType vips_argument_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ARGUMENT_FLAGS (vips_argument_flags_get_type())
/* enumerations from "../../../libvips/include/vips/colour.h" */
GType vips_intent_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_INTENT (vips_intent_get_type())
GType vips_pcs_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_PCS (vips_pcs_get_type())
/* enumerations from "../../../libvips/include/vips/operation.h" */
GType vips_operation_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_FLAGS (vips_operation_flags_get_type())
/* enumerations from "../../../libvips/include/vips/convolution.h" */
GType vips_combine_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_COMBINE (vips_combine_get_type())
/* enumerations from "../../../libvips/include/vips/morphology.h" */
GType vips_operation_morphology_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MORPHOLOGY (vips_operation_morphology_get_type())
/* enumerations from "../../../libvips/include/vips/draw.h" */
GType vips_combine_mode_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_COMBINE_MODE (vips_combine_mode_get_type())
/* enumerations from "../../../libvips/include/vips/basic.h" */
GType vips_precision_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_PRECISION (vips_precision_get_type())
/* enumerations from "../../../libvips/include/vips/object.h" */
GType vips_argument_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ARGUMENT_FLAGS (vips_argument_flags_get_type())
/* enumerations from "../../../libvips/include/vips/region.h" */
GType vips_region_shrink_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_REGION_SHRINK (vips_region_shrink_get_type())
/* enumerations from "../../../libvips/include/vips/resample.h" */
GType vips_kernel_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_KERNEL (vips_kernel_get_type())
GType vips_size_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_SIZE (vips_size_get_type())
/* enumerations from "../../../libvips/include/vips/util.h" */
GType vips_token_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_TOKEN (vips_token_get_type())
G_END_DECLS
#endif /*VIPS_ENUM_TYPES_H*/

View File

@ -342,6 +342,7 @@ typedef struct _VipsForeignSaveClass {
GType vips_foreign_save_get_type(void);
const char *vips_foreign_find_save( const char *filename );
gchar **vips_foreign_get_suffixes( void );
const char *vips_foreign_find_save_buffer( const char *suffix );
int vips_vipsload( const char *filename, VipsImage **out, ... )

File diff suppressed because it is too large Load Diff

View File

@ -2918,9 +2918,8 @@ vips_image_hasalpha( VipsImage *image )
*/
int
vips_image_write_prepare( VipsImage *image )
{
if( !vips_object_sanity( VIPS_OBJECT( image ) ) )
return( -1 );
{
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
if( image->Xsize <= 0 ||
image->Ysize <= 0 ||
@ -3181,8 +3180,7 @@ vips_image_wio_input( VipsImage *image )
{
VipsImage *t1;
if( !vips_object_sanity( VIPS_OBJECT( image ) ) )
return( -1 );
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
#ifdef DEBUG_IO
printf( "vips_image_wio_input: wio input for %s\n",
@ -3406,8 +3404,7 @@ vips_image_inplace( VipsImage *image )
int
vips_image_pio_input( VipsImage *image )
{
if( !vips_object_sanity( VIPS_OBJECT( image ) ) )
return( -1 );
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
#ifdef DEBUG_IO
printf( "vips_image_pio_input: enabling partial input for %s\n",

View File

@ -1988,8 +1988,8 @@ vips_object_set_argument_from_string( VipsObject *object,
b = TRUE;
if( value &&
(strcasecmp( value, "false" ) == 0 ||
strcasecmp( value, "no" ) == 0 ||
(g_ascii_strcasecmp( value, "false" ) == 0 ||
g_ascii_strcasecmp( value, "no" ) == 0 ||
strcmp( value, "0" ) == 0) )
b = FALSE;
@ -2804,12 +2804,12 @@ vips_type_depth( GType type )
static void *
test_name( VipsObjectClass *class, const char *nickname )
{
if( strcasecmp( class->nickname, nickname ) == 0 )
if( g_ascii_strcasecmp( class->nickname, nickname ) == 0 )
return( class );
/* Check the class name too, why not.
*/
if( strcasecmp( G_OBJECT_CLASS_NAME( class ), nickname ) == 0 )
if( g_ascii_strcasecmp( G_OBJECT_CLASS_NAME( class ), nickname ) == 0 )
return( class );
return( NULL );
@ -2877,8 +2877,8 @@ vips_class_add_hash( VipsObjectClass *class, GHashTable *table )
return( NULL );
}
static void
vips_class_build_hash( void )
static void *
vips_class_build_hash_cb( void *dummy )
{
GType base;
@ -2891,6 +2891,8 @@ vips_class_build_hash( void )
vips_class_map_all( base,
(VipsClassMapFn) vips_class_add_hash,
(void *) vips__object_nickname_table );
return( NULL );
}
/**
@ -2919,7 +2921,7 @@ vips_type_find( const char *basename, const char *nickname )
GType base;
GType type;
VIPS_ONCE( &once, (GThreadFunc) vips_class_build_hash, NULL );
VIPS_ONCE( &once, vips_class_build_hash_cb, NULL );
hit = (NicknameGType *)
g_hash_table_lookup( vips__object_nickname_table,

View File

@ -527,12 +527,8 @@ vips_region_new( VipsImage *image )
* We can't use the property system, we need to be very threaded.
*/
g_object_ref( image );
g_assert( G_OBJECT( image )->ref_count > 1 );
#ifdef DEBUG
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
#endif /*DEBUG*/
region = VIPS_REGION( g_object_new( VIPS_TYPE_REGION, NULL ) );
region->im = image;
@ -542,9 +538,7 @@ vips_region_new( VipsImage *image )
return( NULL );
}
#ifdef DEBUG
g_assert( vips_object_sanity( VIPS_OBJECT( region ) ) );
#endif /*DEBUG*/
return( region );
}

View File

@ -338,7 +338,8 @@ vips_reorder_prepare_many( VipsImage *image, VipsRegion **regions, VipsRect *r )
for( i = 0; i < reorder->n_inputs; i++ ) {
g_assert( regions[i] );
if( vips_region_prepare( regions[reorder->recomp_order[i]], r ) )
if( vips_region_prepare(
regions[reorder->recomp_order[i]], r ) )
return( -1 );
}
@ -374,7 +375,8 @@ vips_reorder_margin_hint( VipsImage *image, int margin )
void
vips__reorder_clear( VipsImage *image )
{
g_object_set_qdata( G_OBJECT( image ), vips__image_reorder_quark, NULL );
g_object_set_qdata( G_OBJECT( image ),
vips__image_reorder_quark, NULL );
}
void

View File

@ -21,6 +21,8 @@
* 23/4/17
* - add ->stall
* - don't depend on image width when setting n_lines
* 27/2/19 jtorresfabra
* - free threadpool earlier
*/
/*
@ -579,6 +581,8 @@ vips_thread_free( VipsThread *thr )
VIPS_FREEF( g_object_unref, thr->state );
thr->pool = NULL;
VIPS_FREE( thr );
}
static int
@ -588,10 +592,9 @@ vips_thread_allocate( VipsThread *thr )
g_assert( !pool->stop );
if( !thr->state ) {
if( !(thr->state = pool->start( pool->im, pool->a )) )
return( -1 );
}
if( !thr->state &&
!(thr->state = pool->start( pool->im, pool->a )) )
return( -1 );
if( pool->allocate( thr->state, pool->a, &pool->stop ) )
return( -1 );
@ -703,7 +706,7 @@ vips_thread_new( VipsThreadpool *pool )
{
VipsThread *thr;
if( !(thr = VIPS_NEW( pool->im, VipsThread )) )
if( !(thr = VIPS_NEW( NULL, VipsThread )) )
return( NULL );
thr->pool = pool;
thr->state = NULL;
@ -725,7 +728,8 @@ vips_thread_new( VipsThreadpool *pool )
return( thr );
}
/* Kill all threads in a threadpool, if there are any.
/* Kill all threads in a threadpool, if there are any. Can be called multiple
* times.
*/
static void
vips_threadpool_kill_threads( VipsThreadpool *pool )
@ -734,21 +738,14 @@ vips_threadpool_kill_threads( VipsThreadpool *pool )
int i;
for( i = 0; i < pool->nthr; i++ )
if( pool->thr[i] ) {
vips_thread_free( pool->thr[i] );
pool->thr[i] = NULL;
}
pool->thr = NULL;
VIPS_FREEF( vips_thread_free, pool->thr[i] );
VIPS_DEBUG_MSG( "vips_threadpool_kill_threads: "
"killed %d threads\n", pool->nthr );
}
}
/* This can be called multiple times, careful.
*/
static int
static void
vips_threadpool_free( VipsThreadpool *pool )
{
VIPS_DEBUG_MSG( "vips_threadpool_free: \"%s\" (%p)\n",
@ -758,14 +755,8 @@ vips_threadpool_free( VipsThreadpool *pool )
VIPS_FREEF( vips_g_mutex_free, pool->allocate_lock );
vips_semaphore_destroy( &pool->finish );
vips_semaphore_destroy( &pool->tick );
return( 0 );
}
static void
vips_threadpool_new_cb( VipsImage *im, VipsThreadpool *pool )
{
vips_threadpool_free( pool );
VIPS_FREE( pool->thr );
VIPS_FREE( pool );
}
static VipsThreadpool *
@ -779,7 +770,7 @@ vips_threadpool_new( VipsImage *im )
/* Allocate and init new thread block.
*/
if( !(pool = VIPS_NEW( im, VipsThreadpool )) )
if( !(pool = VIPS_NEW( NULL, VipsThreadpool )) )
return( NULL );
pool->im = im;
pool->allocate = NULL;
@ -802,11 +793,6 @@ vips_threadpool_new( VipsImage *im )
n_tiles = VIPS_CLIP( 0, n_tiles, MAX_THREADS );
pool->nthr = VIPS_MIN( pool->nthr, n_tiles );
/* Attach tidy-up callback.
*/
g_signal_connect( im, "close",
G_CALLBACK( vips_threadpool_new_cb ), pool );
VIPS_DEBUG_MSG( "vips_threadpool_new: \"%s\" (%p), with %d threads\n",
im->filename, pool, pool->nthr );
@ -824,7 +810,7 @@ vips_threadpool_create_threads( VipsThreadpool *pool )
/* Make thread array.
*/
if( !(pool->thr = VIPS_ARRAY( pool->im, pool->nthr, VipsThread * )) )
if( !(pool->thr = VIPS_ARRAY( NULL, pool->nthr, VipsThread * )) )
return( -1 );
for( i = 0; i < pool->nthr; i++ )
pool->thr[i] = NULL;

View File

@ -333,7 +333,7 @@ vips_iscasepostfix( const char *a, const char *b )
if( n > m )
return( FALSE );
return( strcasecmp( a + m - n, b ) == 0 );
return( g_ascii_strcasecmp( a + m - n, b ) == 0 );
}
/* Test for string a starts string b. a is a known-good string, b may be

View File

@ -16,6 +16,8 @@
* - gtk-doc
* 16/12/15
* - faster bilinear
* 27/2/19 s-sajid-ali
* - more accurate bilinear
*/
/*
@ -471,20 +473,21 @@ G_DEFINE_TYPE( VipsInterpolateBilinear, vips_interpolate_bilinear,
}
/* Interpolate a pel ... int32 and float types, no tables, float
* arithmetic.
* arithmetic. Use float, not double, for coefficient calculation, or we can
* get small over/undershoots.
*/
#define BILINEAR_FLOAT( TYPE ) { \
TYPE * restrict tq = (TYPE *) out; \
\
float Y = y - iy; \
float X = x - ix; \
double Y = y - iy; \
double X = x - ix; \
\
float Yd = 1.0f - Y; \
double Yd = 1.0f - Y; \
\
float c4 = Y * X; \
float c2 = Yd * X; \
float c3 = Y - c4; \
float c1 = Yd - c2; \
double c4 = Y * X; \
double c2 = Yd * X; \
double c3 = Y - c4; \
double c1 = Yd - c2; \
\
const TYPE * restrict tp1 = (TYPE *) p1; \
const TYPE * restrict tp2 = (TYPE *) p2; \

View File

@ -75,52 +75,10 @@ typedef VipsResampleClass VipsMapimClass;
G_DEFINE_TYPE( VipsMapim, vips_mapim, VIPS_TYPE_RESAMPLE );
/* Minmax for integer types.
*/
#define MINMAXI( TYPE ) { \
TYPE * restrict p1 = (TYPE *) p; \
TYPE t_max_x = max_x; \
TYPE t_min_x = min_x; \
TYPE t_max_y = max_y; \
TYPE t_min_y = min_y; \
\
for( x = 0; x < r->width; x++ ) { \
TYPE px = p1[0]; \
TYPE py = p1[1]; \
\
if( first ) { \
t_min_x = px; \
t_max_x = px; \
t_min_y = py; \
t_max_y = py; \
\
first = FALSE; \
} \
else { \
if( px > t_max_x ) \
t_max_x = px; \
else if( px < t_min_x ) \
t_min_x = px; \
\
if( py > t_max_y ) \
t_max_y = py; \
else if( py < t_min_y ) \
t_min_y = py; \
} \
\
p1 += 2; \
} \
\
max_x = VIPS_CLIP( 0, t_max_x, VIPS_MAX_COORD ); \
min_x = VIPS_CLIP( 0, t_min_x, VIPS_MAX_COORD ); \
max_y = VIPS_CLIP( 0, t_max_y, VIPS_MAX_COORD ); \
min_y = VIPS_CLIP( 0, t_min_y, VIPS_MAX_COORD ); \
}
/* Minmax for float types. Look out for overflow when we go back to integer
/* Minmax of a line of pixels. Pass in a thing to convert back to int
* coordinates.
*/
#define MINMAXF( TYPE ) { \
#define MINMAX( TYPE, CLIP_LOW, CLIP_HIGH ) { \
TYPE * restrict p1 = (TYPE *) p; \
TYPE t_max_x = max_x; \
TYPE t_min_x = min_x; \
@ -154,12 +112,36 @@ G_DEFINE_TYPE( VipsMapim, vips_mapim, VIPS_TYPE_RESAMPLE );
p1 += 2; \
} \
\
max_x = VIPS_CLIP( 0, ceil( t_max_x ), VIPS_MAX_COORD ); \
min_x = VIPS_CLIP( 0, floor( t_min_x ), VIPS_MAX_COORD ); \
max_y = VIPS_CLIP( 0, ceil( t_max_y ), VIPS_MAX_COORD ); \
min_y = VIPS_CLIP( 0, floor( t_min_y ), VIPS_MAX_COORD ); \
min_x = CLIP_LOW( t_min_x ); \
max_x = CLIP_HIGH( t_max_x ); \
min_y = CLIP_LOW( t_min_y ); \
max_y = CLIP_HIGH( t_max_y ); \
}
/* All the clippers. These vary with TYPE.
*/
/* Clip a small (max val < VIPS_MAX_COORD) unsigned int type.
*/
#define CLIP_UINT_SMALL( X ) (X)
/* Clip a small (max val < VIPS_MAX_COORD) signed int type.
*/
#define CLIP_SINT_SMALL( X ) VIPS_MAX( X, 0 );
/* An unsigned int type larger than VIPS_MAX_COORD. Trim upper range.
*/
#define CLIP_UINT_LARGE( X ) VIPS_MIN( X, VIPS_MAX_COORD );
/* A large signed int.
*/
#define CLIP_SINT_LARGE( X ) VIPS_CLIP( 0, X, VIPS_MAX_COORD );
/* Float types must clip the range, and also round up or down at the extremes.
*/
#define CLIP_FLOAT_LOW( X ) VIPS_CLIP( 0, floor( X ), VIPS_MAX_COORD );
#define CLIP_FLOAT_HIGH( X ) VIPS_CLIP( 0, ceil( X ), VIPS_MAX_COORD );
/* Scan a region and find min/max in the two axes.
*/
static void
@ -183,37 +165,45 @@ vips_mapim_region_minmax( VipsRegion *region, VipsRect *r, VipsRect *bounds )
switch( region->im->BandFmt ) {
case VIPS_FORMAT_UCHAR:
MINMAXI( unsigned char );
MINMAX( unsigned char,
CLIP_UINT_SMALL, CLIP_UINT_SMALL );
break;
case VIPS_FORMAT_CHAR:
MINMAXI( signed char );
MINMAX( signed char,
CLIP_SINT_SMALL, CLIP_SINT_SMALL );
break;
case VIPS_FORMAT_USHORT:
MINMAXI( unsigned short );
MINMAX( unsigned short,
CLIP_UINT_SMALL, CLIP_UINT_SMALL );
break;
case VIPS_FORMAT_SHORT:
MINMAXI( signed short );
MINMAX( signed short,
CLIP_SINT_SMALL, CLIP_SINT_SMALL );
break;
case VIPS_FORMAT_UINT:
MINMAXI( unsigned int );
MINMAX( unsigned int,
CLIP_UINT_LARGE, CLIP_UINT_LARGE );
break;
case VIPS_FORMAT_INT:
MINMAXI( signed int );
MINMAX( signed int,
CLIP_SINT_LARGE, CLIP_SINT_LARGE );
break;
case VIPS_FORMAT_FLOAT:
case VIPS_FORMAT_COMPLEX:
MINMAXF( float );
MINMAX( float,
CLIP_FLOAT_LOW, CLIP_FLOAT_HIGH );
break;
case VIPS_FORMAT_DOUBLE:
case VIPS_FORMAT_DPCOMPLEX:
MINMAXF( double );
MINMAX( double,
CLIP_FLOAT_LOW, CLIP_FLOAT_HIGH );
break;
default:

View File

@ -843,7 +843,7 @@ class TestForeign:
self.file_loader("heifload", HEIC_FILE, heif_valid)
self.buffer_loader("heifload_buffer", HEIC_FILE, heif_valid)
self.save_load_buffer("heifsave_buffer", "heifload_buffer",
self.colour, 70)
self.colour, 80)
self.save_load("%s.heic", self.colour)
# test lossless mode
@ -859,11 +859,13 @@ class TestForeign:
assert len(b2) > len(b1)
# try saving an image with an ICC profile and reading it back
# not all libheif have profile support, so put it in an if
buf = self.colour.heifsave_buffer()
im = pyvips.Image.new_from_buffer(buf, "")
p1 = self.colour.get("icc-profile-data")
p2 = im.get("icc-profile-data")
assert p1 == p2
if im.get_typeof("icc-profile-data") != 0:
p2 = im.get("icc-profile-data")
assert p1 == p2
# add tests for exif, xmp, ipct
# the exif test will need us to be able to walk the header,