diff --git a/.travis.yml b/.travis.yml index 7163846a..09c4ae23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/ChangeLog b/ChangeLog index 7b2c741d..20819463 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/README.md b/README.md index 0485d24f..1d83be7f 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/configure.ac b/configure.ac index 47846761..6285d5e3 100644 --- a/configure.ac +++ b/configure.ac @@ -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)])) diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index 829f653f..c206e39a 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -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 diff --git a/libvips/colour/profile_load.c b/libvips/colour/profile_load.c index a4964c7a..9f9016c7 100644 --- a/libvips/colour/profile_load.c +++ b/libvips/colour/profile_load.c @@ -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 )) ) { diff --git a/libvips/create/eye.c b/libvips/create/eye.c index c348f180..1544fbe9 100644 --- a/libvips/create/eye.c +++ b/libvips/create/eye.c @@ -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 ); } diff --git a/libvips/create/mask.c b/libvips/create/mask.c index 5d3739b6..66f8a197 100644 --- a/libvips/create/mask.c +++ b/libvips/create/mask.c @@ -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; diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 8a925ad1..308220b7 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -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 ); diff --git a/libvips/foreign/csvload.c b/libvips/foreign/csvload.c index e7f47343..41825706 100644 --- a/libvips/foreign/csvload.c +++ b/libvips/foreign/csvload.c @@ -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; diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 65ea028b..943840ac 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -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'; } diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index bb13c4bb..af284bde 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -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. */ diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index ee64f583..bad62e98 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -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 "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 diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index 1afd435c..a61ce8e5 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -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 ); diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index 576ac179..d9d76124 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -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 */ /* diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 68a1f460..a9e65e21 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -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 diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index a890b0be..2d1cddfd 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -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 ); } diff --git a/libvips/include/vips/enumtypes.h b/libvips/include/vips/enumtypes.h index 87cea5fd..d66af57e 100644 --- a/libvips/include/vips/enumtypes.h +++ b/libvips/include/vips/enumtypes.h @@ -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*/ diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 05a3b608..d9c4c39e 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -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, ... ) diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index 0db48abc..564c679c 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -1,456 +1,48 @@ -/* 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) */ /* auto-generated enums for vips introspection */ #include -/* enumerations from "../../libvips/include/vips/arithmetic.h" */ +/* enumerations from "../../libvips/include/vips/resample.h" */ GType -vips_operation_math_get_type( void ) +vips_kernel_get_type( void ) { static GType etype = 0; if( etype == 0 ) { static const GEnumValue values[] = { - {VIPS_OPERATION_MATH_SIN, "VIPS_OPERATION_MATH_SIN", "sin"}, - {VIPS_OPERATION_MATH_COS, "VIPS_OPERATION_MATH_COS", "cos"}, - {VIPS_OPERATION_MATH_TAN, "VIPS_OPERATION_MATH_TAN", "tan"}, - {VIPS_OPERATION_MATH_ASIN, "VIPS_OPERATION_MATH_ASIN", "asin"}, - {VIPS_OPERATION_MATH_ACOS, "VIPS_OPERATION_MATH_ACOS", "acos"}, - {VIPS_OPERATION_MATH_ATAN, "VIPS_OPERATION_MATH_ATAN", "atan"}, - {VIPS_OPERATION_MATH_LOG, "VIPS_OPERATION_MATH_LOG", "log"}, - {VIPS_OPERATION_MATH_LOG10, "VIPS_OPERATION_MATH_LOG10", "log10"}, - {VIPS_OPERATION_MATH_EXP, "VIPS_OPERATION_MATH_EXP", "exp"}, - {VIPS_OPERATION_MATH_EXP10, "VIPS_OPERATION_MATH_EXP10", "exp10"}, - {VIPS_OPERATION_MATH_LAST, "VIPS_OPERATION_MATH_LAST", "last"}, + {VIPS_KERNEL_NEAREST, "VIPS_KERNEL_NEAREST", "nearest"}, + {VIPS_KERNEL_LINEAR, "VIPS_KERNEL_LINEAR", "linear"}, + {VIPS_KERNEL_CUBIC, "VIPS_KERNEL_CUBIC", "cubic"}, + {VIPS_KERNEL_MITCHELL, "VIPS_KERNEL_MITCHELL", "mitchell"}, + {VIPS_KERNEL_LANCZOS2, "VIPS_KERNEL_LANCZOS2", "lanczos2"}, + {VIPS_KERNEL_LANCZOS3, "VIPS_KERNEL_LANCZOS3", "lanczos3"}, + {VIPS_KERNEL_LAST, "VIPS_KERNEL_LAST", "last"}, {0, NULL, NULL} }; - etype = g_enum_register_static( "VipsOperationMath", values ); + etype = g_enum_register_static( "VipsKernel", values ); } return( etype ); } GType -vips_operation_math2_get_type( void ) +vips_size_get_type( void ) { static GType etype = 0; if( etype == 0 ) { static const GEnumValue values[] = { - {VIPS_OPERATION_MATH2_POW, "VIPS_OPERATION_MATH2_POW", "pow"}, - {VIPS_OPERATION_MATH2_WOP, "VIPS_OPERATION_MATH2_WOP", "wop"}, - {VIPS_OPERATION_MATH2_LAST, "VIPS_OPERATION_MATH2_LAST", "last"}, + {VIPS_SIZE_BOTH, "VIPS_SIZE_BOTH", "both"}, + {VIPS_SIZE_UP, "VIPS_SIZE_UP", "up"}, + {VIPS_SIZE_DOWN, "VIPS_SIZE_DOWN", "down"}, + {VIPS_SIZE_FORCE, "VIPS_SIZE_FORCE", "force"}, + {VIPS_SIZE_LAST, "VIPS_SIZE_LAST", "last"}, {0, NULL, NULL} }; - etype = g_enum_register_static( "VipsOperationMath2", values ); - } - - return( etype ); -} -GType -vips_operation_round_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_OPERATION_ROUND_RINT, "VIPS_OPERATION_ROUND_RINT", "rint"}, - {VIPS_OPERATION_ROUND_CEIL, "VIPS_OPERATION_ROUND_CEIL", "ceil"}, - {VIPS_OPERATION_ROUND_FLOOR, "VIPS_OPERATION_ROUND_FLOOR", "floor"}, - {VIPS_OPERATION_ROUND_LAST, "VIPS_OPERATION_ROUND_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsOperationRound", values ); - } - - return( etype ); -} -GType -vips_operation_relational_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_OPERATION_RELATIONAL_EQUAL, "VIPS_OPERATION_RELATIONAL_EQUAL", "equal"}, - {VIPS_OPERATION_RELATIONAL_NOTEQ, "VIPS_OPERATION_RELATIONAL_NOTEQ", "noteq"}, - {VIPS_OPERATION_RELATIONAL_LESS, "VIPS_OPERATION_RELATIONAL_LESS", "less"}, - {VIPS_OPERATION_RELATIONAL_LESSEQ, "VIPS_OPERATION_RELATIONAL_LESSEQ", "lesseq"}, - {VIPS_OPERATION_RELATIONAL_MORE, "VIPS_OPERATION_RELATIONAL_MORE", "more"}, - {VIPS_OPERATION_RELATIONAL_MOREEQ, "VIPS_OPERATION_RELATIONAL_MOREEQ", "moreeq"}, - {VIPS_OPERATION_RELATIONAL_LAST, "VIPS_OPERATION_RELATIONAL_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsOperationRelational", values ); - } - - return( etype ); -} -GType -vips_operation_boolean_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_OPERATION_BOOLEAN_AND, "VIPS_OPERATION_BOOLEAN_AND", "and"}, - {VIPS_OPERATION_BOOLEAN_OR, "VIPS_OPERATION_BOOLEAN_OR", "or"}, - {VIPS_OPERATION_BOOLEAN_EOR, "VIPS_OPERATION_BOOLEAN_EOR", "eor"}, - {VIPS_OPERATION_BOOLEAN_LSHIFT, "VIPS_OPERATION_BOOLEAN_LSHIFT", "lshift"}, - {VIPS_OPERATION_BOOLEAN_RSHIFT, "VIPS_OPERATION_BOOLEAN_RSHIFT", "rshift"}, - {VIPS_OPERATION_BOOLEAN_LAST, "VIPS_OPERATION_BOOLEAN_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsOperationBoolean", values ); - } - - return( etype ); -} -GType -vips_operation_complex_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_OPERATION_COMPLEX_POLAR, "VIPS_OPERATION_COMPLEX_POLAR", "polar"}, - {VIPS_OPERATION_COMPLEX_RECT, "VIPS_OPERATION_COMPLEX_RECT", "rect"}, - {VIPS_OPERATION_COMPLEX_CONJ, "VIPS_OPERATION_COMPLEX_CONJ", "conj"}, - {VIPS_OPERATION_COMPLEX_LAST, "VIPS_OPERATION_COMPLEX_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsOperationComplex", values ); - } - - return( etype ); -} -GType -vips_operation_complex2_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_OPERATION_COMPLEX2_CROSS_PHASE, "VIPS_OPERATION_COMPLEX2_CROSS_PHASE", "cross-phase"}, - {VIPS_OPERATION_COMPLEX2_LAST, "VIPS_OPERATION_COMPLEX2_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsOperationComplex2", values ); - } - - return( etype ); -} -GType -vips_operation_complexget_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_OPERATION_COMPLEXGET_REAL, "VIPS_OPERATION_COMPLEXGET_REAL", "real"}, - {VIPS_OPERATION_COMPLEXGET_IMAG, "VIPS_OPERATION_COMPLEXGET_IMAG", "imag"}, - {VIPS_OPERATION_COMPLEXGET_LAST, "VIPS_OPERATION_COMPLEXGET_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsOperationComplexget", values ); - } - - return( etype ); -} -/* enumerations from "../../libvips/include/vips/basic.h" */ -GType -vips_precision_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_PRECISION_INTEGER, "VIPS_PRECISION_INTEGER", "integer"}, - {VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"}, - {VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"}, - {VIPS_PRECISION_LAST, "VIPS_PRECISION_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsPrecision", values ); - } - - return( etype ); -} -/* enumerations from "../../libvips/include/vips/colour.h" */ -GType -vips_intent_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_INTENT_PERCEPTUAL, "VIPS_INTENT_PERCEPTUAL", "perceptual"}, - {VIPS_INTENT_RELATIVE, "VIPS_INTENT_RELATIVE", "relative"}, - {VIPS_INTENT_SATURATION, "VIPS_INTENT_SATURATION", "saturation"}, - {VIPS_INTENT_ABSOLUTE, "VIPS_INTENT_ABSOLUTE", "absolute"}, - {VIPS_INTENT_LAST, "VIPS_INTENT_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsIntent", values ); - } - - return( etype ); -} -GType -vips_pcs_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_PCS_LAB, "VIPS_PCS_LAB", "lab"}, - {VIPS_PCS_XYZ, "VIPS_PCS_XYZ", "xyz"}, - {VIPS_PCS_LAST, "VIPS_PCS_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsPCS", values ); - } - - return( etype ); -} -/* enumerations from "../../libvips/include/vips/conversion.h" */ -GType -vips_extend_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_EXTEND_BLACK, "VIPS_EXTEND_BLACK", "black"}, - {VIPS_EXTEND_COPY, "VIPS_EXTEND_COPY", "copy"}, - {VIPS_EXTEND_REPEAT, "VIPS_EXTEND_REPEAT", "repeat"}, - {VIPS_EXTEND_MIRROR, "VIPS_EXTEND_MIRROR", "mirror"}, - {VIPS_EXTEND_WHITE, "VIPS_EXTEND_WHITE", "white"}, - {VIPS_EXTEND_BACKGROUND, "VIPS_EXTEND_BACKGROUND", "background"}, - {VIPS_EXTEND_LAST, "VIPS_EXTEND_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsExtend", values ); - } - - return( etype ); -} -GType -vips_compass_direction_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_COMPASS_DIRECTION_CENTRE, "VIPS_COMPASS_DIRECTION_CENTRE", "centre"}, - {VIPS_COMPASS_DIRECTION_NORTH, "VIPS_COMPASS_DIRECTION_NORTH", "north"}, - {VIPS_COMPASS_DIRECTION_EAST, "VIPS_COMPASS_DIRECTION_EAST", "east"}, - {VIPS_COMPASS_DIRECTION_SOUTH, "VIPS_COMPASS_DIRECTION_SOUTH", "south"}, - {VIPS_COMPASS_DIRECTION_WEST, "VIPS_COMPASS_DIRECTION_WEST", "west"}, - {VIPS_COMPASS_DIRECTION_NORTH_EAST, "VIPS_COMPASS_DIRECTION_NORTH_EAST", "north-east"}, - {VIPS_COMPASS_DIRECTION_SOUTH_EAST, "VIPS_COMPASS_DIRECTION_SOUTH_EAST", "south-east"}, - {VIPS_COMPASS_DIRECTION_SOUTH_WEST, "VIPS_COMPASS_DIRECTION_SOUTH_WEST", "south-west"}, - {VIPS_COMPASS_DIRECTION_NORTH_WEST, "VIPS_COMPASS_DIRECTION_NORTH_WEST", "north-west"}, - {VIPS_COMPASS_DIRECTION_LAST, "VIPS_COMPASS_DIRECTION_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsCompassDirection", values ); - } - - return( etype ); -} -GType -vips_direction_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_DIRECTION_HORIZONTAL, "VIPS_DIRECTION_HORIZONTAL", "horizontal"}, - {VIPS_DIRECTION_VERTICAL, "VIPS_DIRECTION_VERTICAL", "vertical"}, - {VIPS_DIRECTION_LAST, "VIPS_DIRECTION_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsDirection", values ); - } - - return( etype ); -} -GType -vips_align_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_ALIGN_LOW, "VIPS_ALIGN_LOW", "low"}, - {VIPS_ALIGN_CENTRE, "VIPS_ALIGN_CENTRE", "centre"}, - {VIPS_ALIGN_HIGH, "VIPS_ALIGN_HIGH", "high"}, - {VIPS_ALIGN_LAST, "VIPS_ALIGN_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsAlign", values ); - } - - return( etype ); -} -GType -vips_angle_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_ANGLE_D0, "VIPS_ANGLE_D0", "d0"}, - {VIPS_ANGLE_D90, "VIPS_ANGLE_D90", "d90"}, - {VIPS_ANGLE_D180, "VIPS_ANGLE_D180", "d180"}, - {VIPS_ANGLE_D270, "VIPS_ANGLE_D270", "d270"}, - {VIPS_ANGLE_LAST, "VIPS_ANGLE_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsAngle", values ); - } - - return( etype ); -} -GType -vips_angle45_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_ANGLE45_D0, "VIPS_ANGLE45_D0", "d0"}, - {VIPS_ANGLE45_D45, "VIPS_ANGLE45_D45", "d45"}, - {VIPS_ANGLE45_D90, "VIPS_ANGLE45_D90", "d90"}, - {VIPS_ANGLE45_D135, "VIPS_ANGLE45_D135", "d135"}, - {VIPS_ANGLE45_D180, "VIPS_ANGLE45_D180", "d180"}, - {VIPS_ANGLE45_D225, "VIPS_ANGLE45_D225", "d225"}, - {VIPS_ANGLE45_D270, "VIPS_ANGLE45_D270", "d270"}, - {VIPS_ANGLE45_D315, "VIPS_ANGLE45_D315", "d315"}, - {VIPS_ANGLE45_LAST, "VIPS_ANGLE45_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsAngle45", values ); - } - - return( etype ); -} -GType -vips_interesting_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_INTERESTING_NONE, "VIPS_INTERESTING_NONE", "none"}, - {VIPS_INTERESTING_CENTRE, "VIPS_INTERESTING_CENTRE", "centre"}, - {VIPS_INTERESTING_ENTROPY, "VIPS_INTERESTING_ENTROPY", "entropy"}, - {VIPS_INTERESTING_ATTENTION, "VIPS_INTERESTING_ATTENTION", "attention"}, - {VIPS_INTERESTING_LOW, "VIPS_INTERESTING_LOW", "low"}, - {VIPS_INTERESTING_HIGH, "VIPS_INTERESTING_HIGH", "high"}, - {VIPS_INTERESTING_LAST, "VIPS_INTERESTING_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsInteresting", values ); - } - - return( etype ); -} -GType -vips_blend_mode_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_BLEND_MODE_CLEAR, "VIPS_BLEND_MODE_CLEAR", "clear"}, - {VIPS_BLEND_MODE_SOURCE, "VIPS_BLEND_MODE_SOURCE", "source"}, - {VIPS_BLEND_MODE_OVER, "VIPS_BLEND_MODE_OVER", "over"}, - {VIPS_BLEND_MODE_IN, "VIPS_BLEND_MODE_IN", "in"}, - {VIPS_BLEND_MODE_OUT, "VIPS_BLEND_MODE_OUT", "out"}, - {VIPS_BLEND_MODE_ATOP, "VIPS_BLEND_MODE_ATOP", "atop"}, - {VIPS_BLEND_MODE_DEST, "VIPS_BLEND_MODE_DEST", "dest"}, - {VIPS_BLEND_MODE_DEST_OVER, "VIPS_BLEND_MODE_DEST_OVER", "dest-over"}, - {VIPS_BLEND_MODE_DEST_IN, "VIPS_BLEND_MODE_DEST_IN", "dest-in"}, - {VIPS_BLEND_MODE_DEST_OUT, "VIPS_BLEND_MODE_DEST_OUT", "dest-out"}, - {VIPS_BLEND_MODE_DEST_ATOP, "VIPS_BLEND_MODE_DEST_ATOP", "dest-atop"}, - {VIPS_BLEND_MODE_XOR, "VIPS_BLEND_MODE_XOR", "xor"}, - {VIPS_BLEND_MODE_ADD, "VIPS_BLEND_MODE_ADD", "add"}, - {VIPS_BLEND_MODE_SATURATE, "VIPS_BLEND_MODE_SATURATE", "saturate"}, - {VIPS_BLEND_MODE_MULTIPLY, "VIPS_BLEND_MODE_MULTIPLY", "multiply"}, - {VIPS_BLEND_MODE_SCREEN, "VIPS_BLEND_MODE_SCREEN", "screen"}, - {VIPS_BLEND_MODE_OVERLAY, "VIPS_BLEND_MODE_OVERLAY", "overlay"}, - {VIPS_BLEND_MODE_DARKEN, "VIPS_BLEND_MODE_DARKEN", "darken"}, - {VIPS_BLEND_MODE_LIGHTEN, "VIPS_BLEND_MODE_LIGHTEN", "lighten"}, - {VIPS_BLEND_MODE_COLOUR_DODGE, "VIPS_BLEND_MODE_COLOUR_DODGE", "colour-dodge"}, - {VIPS_BLEND_MODE_COLOUR_BURN, "VIPS_BLEND_MODE_COLOUR_BURN", "colour-burn"}, - {VIPS_BLEND_MODE_HARD_LIGHT, "VIPS_BLEND_MODE_HARD_LIGHT", "hard-light"}, - {VIPS_BLEND_MODE_SOFT_LIGHT, "VIPS_BLEND_MODE_SOFT_LIGHT", "soft-light"}, - {VIPS_BLEND_MODE_DIFFERENCE, "VIPS_BLEND_MODE_DIFFERENCE", "difference"}, - {VIPS_BLEND_MODE_EXCLUSION, "VIPS_BLEND_MODE_EXCLUSION", "exclusion"}, - {VIPS_BLEND_MODE_LAST, "VIPS_BLEND_MODE_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsBlendMode", values ); - } - - return( etype ); -} -/* enumerations from "../../libvips/include/vips/convolution.h" */ -GType -vips_combine_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_COMBINE_MAX, "VIPS_COMBINE_MAX", "max"}, - {VIPS_COMBINE_SUM, "VIPS_COMBINE_SUM", "sum"}, - {VIPS_COMBINE_MIN, "VIPS_COMBINE_MIN", "min"}, - {VIPS_COMBINE_LAST, "VIPS_COMBINE_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsCombine", values ); - } - - return( etype ); -} -/* enumerations from "../../libvips/include/vips/draw.h" */ -GType -vips_combine_mode_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_COMBINE_MODE_SET, "VIPS_COMBINE_MODE_SET", "set"}, - {VIPS_COMBINE_MODE_ADD, "VIPS_COMBINE_MODE_ADD", "add"}, - {VIPS_COMBINE_MODE_LAST, "VIPS_COMBINE_MODE_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsCombineMode", values ); + etype = g_enum_register_static( "VipsSize", values ); } return( etype ); @@ -656,6 +248,380 @@ vips_foreign_dz_container_get_type( void ) return( etype ); } +/* enumerations from "../../libvips/include/vips/conversion.h" */ +GType +vips_extend_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_EXTEND_BLACK, "VIPS_EXTEND_BLACK", "black"}, + {VIPS_EXTEND_COPY, "VIPS_EXTEND_COPY", "copy"}, + {VIPS_EXTEND_REPEAT, "VIPS_EXTEND_REPEAT", "repeat"}, + {VIPS_EXTEND_MIRROR, "VIPS_EXTEND_MIRROR", "mirror"}, + {VIPS_EXTEND_WHITE, "VIPS_EXTEND_WHITE", "white"}, + {VIPS_EXTEND_BACKGROUND, "VIPS_EXTEND_BACKGROUND", "background"}, + {VIPS_EXTEND_LAST, "VIPS_EXTEND_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsExtend", values ); + } + + return( etype ); +} +GType +vips_compass_direction_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_COMPASS_DIRECTION_CENTRE, "VIPS_COMPASS_DIRECTION_CENTRE", "centre"}, + {VIPS_COMPASS_DIRECTION_NORTH, "VIPS_COMPASS_DIRECTION_NORTH", "north"}, + {VIPS_COMPASS_DIRECTION_EAST, "VIPS_COMPASS_DIRECTION_EAST", "east"}, + {VIPS_COMPASS_DIRECTION_SOUTH, "VIPS_COMPASS_DIRECTION_SOUTH", "south"}, + {VIPS_COMPASS_DIRECTION_WEST, "VIPS_COMPASS_DIRECTION_WEST", "west"}, + {VIPS_COMPASS_DIRECTION_NORTH_EAST, "VIPS_COMPASS_DIRECTION_NORTH_EAST", "north-east"}, + {VIPS_COMPASS_DIRECTION_SOUTH_EAST, "VIPS_COMPASS_DIRECTION_SOUTH_EAST", "south-east"}, + {VIPS_COMPASS_DIRECTION_SOUTH_WEST, "VIPS_COMPASS_DIRECTION_SOUTH_WEST", "south-west"}, + {VIPS_COMPASS_DIRECTION_NORTH_WEST, "VIPS_COMPASS_DIRECTION_NORTH_WEST", "north-west"}, + {VIPS_COMPASS_DIRECTION_LAST, "VIPS_COMPASS_DIRECTION_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsCompassDirection", values ); + } + + return( etype ); +} +GType +vips_direction_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_DIRECTION_HORIZONTAL, "VIPS_DIRECTION_HORIZONTAL", "horizontal"}, + {VIPS_DIRECTION_VERTICAL, "VIPS_DIRECTION_VERTICAL", "vertical"}, + {VIPS_DIRECTION_LAST, "VIPS_DIRECTION_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsDirection", values ); + } + + return( etype ); +} +GType +vips_align_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_ALIGN_LOW, "VIPS_ALIGN_LOW", "low"}, + {VIPS_ALIGN_CENTRE, "VIPS_ALIGN_CENTRE", "centre"}, + {VIPS_ALIGN_HIGH, "VIPS_ALIGN_HIGH", "high"}, + {VIPS_ALIGN_LAST, "VIPS_ALIGN_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsAlign", values ); + } + + return( etype ); +} +GType +vips_angle_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_ANGLE_D0, "VIPS_ANGLE_D0", "d0"}, + {VIPS_ANGLE_D90, "VIPS_ANGLE_D90", "d90"}, + {VIPS_ANGLE_D180, "VIPS_ANGLE_D180", "d180"}, + {VIPS_ANGLE_D270, "VIPS_ANGLE_D270", "d270"}, + {VIPS_ANGLE_LAST, "VIPS_ANGLE_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsAngle", values ); + } + + return( etype ); +} +GType +vips_angle45_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_ANGLE45_D0, "VIPS_ANGLE45_D0", "d0"}, + {VIPS_ANGLE45_D45, "VIPS_ANGLE45_D45", "d45"}, + {VIPS_ANGLE45_D90, "VIPS_ANGLE45_D90", "d90"}, + {VIPS_ANGLE45_D135, "VIPS_ANGLE45_D135", "d135"}, + {VIPS_ANGLE45_D180, "VIPS_ANGLE45_D180", "d180"}, + {VIPS_ANGLE45_D225, "VIPS_ANGLE45_D225", "d225"}, + {VIPS_ANGLE45_D270, "VIPS_ANGLE45_D270", "d270"}, + {VIPS_ANGLE45_D315, "VIPS_ANGLE45_D315", "d315"}, + {VIPS_ANGLE45_LAST, "VIPS_ANGLE45_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsAngle45", values ); + } + + return( etype ); +} +GType +vips_interesting_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_INTERESTING_NONE, "VIPS_INTERESTING_NONE", "none"}, + {VIPS_INTERESTING_CENTRE, "VIPS_INTERESTING_CENTRE", "centre"}, + {VIPS_INTERESTING_ENTROPY, "VIPS_INTERESTING_ENTROPY", "entropy"}, + {VIPS_INTERESTING_ATTENTION, "VIPS_INTERESTING_ATTENTION", "attention"}, + {VIPS_INTERESTING_LOW, "VIPS_INTERESTING_LOW", "low"}, + {VIPS_INTERESTING_HIGH, "VIPS_INTERESTING_HIGH", "high"}, + {VIPS_INTERESTING_LAST, "VIPS_INTERESTING_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsInteresting", values ); + } + + return( etype ); +} +GType +vips_blend_mode_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_BLEND_MODE_CLEAR, "VIPS_BLEND_MODE_CLEAR", "clear"}, + {VIPS_BLEND_MODE_SOURCE, "VIPS_BLEND_MODE_SOURCE", "source"}, + {VIPS_BLEND_MODE_OVER, "VIPS_BLEND_MODE_OVER", "over"}, + {VIPS_BLEND_MODE_IN, "VIPS_BLEND_MODE_IN", "in"}, + {VIPS_BLEND_MODE_OUT, "VIPS_BLEND_MODE_OUT", "out"}, + {VIPS_BLEND_MODE_ATOP, "VIPS_BLEND_MODE_ATOP", "atop"}, + {VIPS_BLEND_MODE_DEST, "VIPS_BLEND_MODE_DEST", "dest"}, + {VIPS_BLEND_MODE_DEST_OVER, "VIPS_BLEND_MODE_DEST_OVER", "dest-over"}, + {VIPS_BLEND_MODE_DEST_IN, "VIPS_BLEND_MODE_DEST_IN", "dest-in"}, + {VIPS_BLEND_MODE_DEST_OUT, "VIPS_BLEND_MODE_DEST_OUT", "dest-out"}, + {VIPS_BLEND_MODE_DEST_ATOP, "VIPS_BLEND_MODE_DEST_ATOP", "dest-atop"}, + {VIPS_BLEND_MODE_XOR, "VIPS_BLEND_MODE_XOR", "xor"}, + {VIPS_BLEND_MODE_ADD, "VIPS_BLEND_MODE_ADD", "add"}, + {VIPS_BLEND_MODE_SATURATE, "VIPS_BLEND_MODE_SATURATE", "saturate"}, + {VIPS_BLEND_MODE_MULTIPLY, "VIPS_BLEND_MODE_MULTIPLY", "multiply"}, + {VIPS_BLEND_MODE_SCREEN, "VIPS_BLEND_MODE_SCREEN", "screen"}, + {VIPS_BLEND_MODE_OVERLAY, "VIPS_BLEND_MODE_OVERLAY", "overlay"}, + {VIPS_BLEND_MODE_DARKEN, "VIPS_BLEND_MODE_DARKEN", "darken"}, + {VIPS_BLEND_MODE_LIGHTEN, "VIPS_BLEND_MODE_LIGHTEN", "lighten"}, + {VIPS_BLEND_MODE_COLOUR_DODGE, "VIPS_BLEND_MODE_COLOUR_DODGE", "colour-dodge"}, + {VIPS_BLEND_MODE_COLOUR_BURN, "VIPS_BLEND_MODE_COLOUR_BURN", "colour-burn"}, + {VIPS_BLEND_MODE_HARD_LIGHT, "VIPS_BLEND_MODE_HARD_LIGHT", "hard-light"}, + {VIPS_BLEND_MODE_SOFT_LIGHT, "VIPS_BLEND_MODE_SOFT_LIGHT", "soft-light"}, + {VIPS_BLEND_MODE_DIFFERENCE, "VIPS_BLEND_MODE_DIFFERENCE", "difference"}, + {VIPS_BLEND_MODE_EXCLUSION, "VIPS_BLEND_MODE_EXCLUSION", "exclusion"}, + {VIPS_BLEND_MODE_LAST, "VIPS_BLEND_MODE_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsBlendMode", values ); + } + + return( etype ); +} +/* enumerations from "../../libvips/include/vips/arithmetic.h" */ +GType +vips_operation_math_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_MATH_SIN, "VIPS_OPERATION_MATH_SIN", "sin"}, + {VIPS_OPERATION_MATH_COS, "VIPS_OPERATION_MATH_COS", "cos"}, + {VIPS_OPERATION_MATH_TAN, "VIPS_OPERATION_MATH_TAN", "tan"}, + {VIPS_OPERATION_MATH_ASIN, "VIPS_OPERATION_MATH_ASIN", "asin"}, + {VIPS_OPERATION_MATH_ACOS, "VIPS_OPERATION_MATH_ACOS", "acos"}, + {VIPS_OPERATION_MATH_ATAN, "VIPS_OPERATION_MATH_ATAN", "atan"}, + {VIPS_OPERATION_MATH_LOG, "VIPS_OPERATION_MATH_LOG", "log"}, + {VIPS_OPERATION_MATH_LOG10, "VIPS_OPERATION_MATH_LOG10", "log10"}, + {VIPS_OPERATION_MATH_EXP, "VIPS_OPERATION_MATH_EXP", "exp"}, + {VIPS_OPERATION_MATH_EXP10, "VIPS_OPERATION_MATH_EXP10", "exp10"}, + {VIPS_OPERATION_MATH_LAST, "VIPS_OPERATION_MATH_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationMath", values ); + } + + return( etype ); +} +GType +vips_operation_math2_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_MATH2_POW, "VIPS_OPERATION_MATH2_POW", "pow"}, + {VIPS_OPERATION_MATH2_WOP, "VIPS_OPERATION_MATH2_WOP", "wop"}, + {VIPS_OPERATION_MATH2_LAST, "VIPS_OPERATION_MATH2_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationMath2", values ); + } + + return( etype ); +} +GType +vips_operation_round_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_ROUND_RINT, "VIPS_OPERATION_ROUND_RINT", "rint"}, + {VIPS_OPERATION_ROUND_CEIL, "VIPS_OPERATION_ROUND_CEIL", "ceil"}, + {VIPS_OPERATION_ROUND_FLOOR, "VIPS_OPERATION_ROUND_FLOOR", "floor"}, + {VIPS_OPERATION_ROUND_LAST, "VIPS_OPERATION_ROUND_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationRound", values ); + } + + return( etype ); +} +GType +vips_operation_relational_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_RELATIONAL_EQUAL, "VIPS_OPERATION_RELATIONAL_EQUAL", "equal"}, + {VIPS_OPERATION_RELATIONAL_NOTEQ, "VIPS_OPERATION_RELATIONAL_NOTEQ", "noteq"}, + {VIPS_OPERATION_RELATIONAL_LESS, "VIPS_OPERATION_RELATIONAL_LESS", "less"}, + {VIPS_OPERATION_RELATIONAL_LESSEQ, "VIPS_OPERATION_RELATIONAL_LESSEQ", "lesseq"}, + {VIPS_OPERATION_RELATIONAL_MORE, "VIPS_OPERATION_RELATIONAL_MORE", "more"}, + {VIPS_OPERATION_RELATIONAL_MOREEQ, "VIPS_OPERATION_RELATIONAL_MOREEQ", "moreeq"}, + {VIPS_OPERATION_RELATIONAL_LAST, "VIPS_OPERATION_RELATIONAL_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationRelational", values ); + } + + return( etype ); +} +GType +vips_operation_boolean_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_BOOLEAN_AND, "VIPS_OPERATION_BOOLEAN_AND", "and"}, + {VIPS_OPERATION_BOOLEAN_OR, "VIPS_OPERATION_BOOLEAN_OR", "or"}, + {VIPS_OPERATION_BOOLEAN_EOR, "VIPS_OPERATION_BOOLEAN_EOR", "eor"}, + {VIPS_OPERATION_BOOLEAN_LSHIFT, "VIPS_OPERATION_BOOLEAN_LSHIFT", "lshift"}, + {VIPS_OPERATION_BOOLEAN_RSHIFT, "VIPS_OPERATION_BOOLEAN_RSHIFT", "rshift"}, + {VIPS_OPERATION_BOOLEAN_LAST, "VIPS_OPERATION_BOOLEAN_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationBoolean", values ); + } + + return( etype ); +} +GType +vips_operation_complex_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_COMPLEX_POLAR, "VIPS_OPERATION_COMPLEX_POLAR", "polar"}, + {VIPS_OPERATION_COMPLEX_RECT, "VIPS_OPERATION_COMPLEX_RECT", "rect"}, + {VIPS_OPERATION_COMPLEX_CONJ, "VIPS_OPERATION_COMPLEX_CONJ", "conj"}, + {VIPS_OPERATION_COMPLEX_LAST, "VIPS_OPERATION_COMPLEX_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationComplex", values ); + } + + return( etype ); +} +GType +vips_operation_complex2_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_COMPLEX2_CROSS_PHASE, "VIPS_OPERATION_COMPLEX2_CROSS_PHASE", "cross-phase"}, + {VIPS_OPERATION_COMPLEX2_LAST, "VIPS_OPERATION_COMPLEX2_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationComplex2", values ); + } + + return( etype ); +} +GType +vips_operation_complexget_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_OPERATION_COMPLEXGET_REAL, "VIPS_OPERATION_COMPLEXGET_REAL", "real"}, + {VIPS_OPERATION_COMPLEXGET_IMAG, "VIPS_OPERATION_COMPLEXGET_IMAG", "imag"}, + {VIPS_OPERATION_COMPLEXGET_LAST, "VIPS_OPERATION_COMPLEXGET_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsOperationComplexget", values ); + } + + return( etype ); +} +/* enumerations from "../../libvips/include/vips/util.h" */ +GType +vips_token_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_TOKEN_LEFT, "VIPS_TOKEN_LEFT", "left"}, + {VIPS_TOKEN_RIGHT, "VIPS_TOKEN_RIGHT", "right"}, + {VIPS_TOKEN_STRING, "VIPS_TOKEN_STRING", "string"}, + {VIPS_TOKEN_EQUALS, "VIPS_TOKEN_EQUALS", "equals"}, + {VIPS_TOKEN_COMMA, "VIPS_TOKEN_COMMA", "comma"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsToken", values ); + } + + return( etype ); +} /* enumerations from "../../libvips/include/vips/image.h" */ GType vips_demand_style_get_type( void ) @@ -803,6 +769,86 @@ vips_access_get_type( void ) return( etype ); } +/* enumerations from "../../libvips/include/vips/colour.h" */ +GType +vips_intent_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_INTENT_PERCEPTUAL, "VIPS_INTENT_PERCEPTUAL", "perceptual"}, + {VIPS_INTENT_RELATIVE, "VIPS_INTENT_RELATIVE", "relative"}, + {VIPS_INTENT_SATURATION, "VIPS_INTENT_SATURATION", "saturation"}, + {VIPS_INTENT_ABSOLUTE, "VIPS_INTENT_ABSOLUTE", "absolute"}, + {VIPS_INTENT_LAST, "VIPS_INTENT_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsIntent", values ); + } + + return( etype ); +} +GType +vips_pcs_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_PCS_LAB, "VIPS_PCS_LAB", "lab"}, + {VIPS_PCS_XYZ, "VIPS_PCS_XYZ", "xyz"}, + {VIPS_PCS_LAST, "VIPS_PCS_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsPCS", values ); + } + + return( etype ); +} +/* enumerations from "../../libvips/include/vips/operation.h" */ +GType +vips_operation_flags_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GFlagsValue values[] = { + {VIPS_OPERATION_NONE, "VIPS_OPERATION_NONE", "none"}, + {VIPS_OPERATION_SEQUENTIAL, "VIPS_OPERATION_SEQUENTIAL", "sequential"}, + {VIPS_OPERATION_SEQUENTIAL_UNBUFFERED, "VIPS_OPERATION_SEQUENTIAL_UNBUFFERED", "sequential-unbuffered"}, + {VIPS_OPERATION_NOCACHE, "VIPS_OPERATION_NOCACHE", "nocache"}, + {VIPS_OPERATION_DEPRECATED, "VIPS_OPERATION_DEPRECATED", "deprecated"}, + {0, NULL, NULL} + }; + + etype = g_flags_register_static( "VipsOperationFlags", values ); + } + + return( etype ); +} +/* enumerations from "../../libvips/include/vips/convolution.h" */ +GType +vips_combine_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_COMBINE_MAX, "VIPS_COMBINE_MAX", "max"}, + {VIPS_COMBINE_SUM, "VIPS_COMBINE_SUM", "sum"}, + {VIPS_COMBINE_MIN, "VIPS_COMBINE_MIN", "min"}, + {VIPS_COMBINE_LAST, "VIPS_COMBINE_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsCombine", values ); + } + + return( etype ); +} /* enumerations from "../../libvips/include/vips/morphology.h" */ GType vips_operation_morphology_get_type( void ) @@ -822,6 +868,45 @@ vips_operation_morphology_get_type( void ) return( etype ); } +/* enumerations from "../../libvips/include/vips/draw.h" */ +GType +vips_combine_mode_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_COMBINE_MODE_SET, "VIPS_COMBINE_MODE_SET", "set"}, + {VIPS_COMBINE_MODE_ADD, "VIPS_COMBINE_MODE_ADD", "add"}, + {VIPS_COMBINE_MODE_LAST, "VIPS_COMBINE_MODE_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsCombineMode", values ); + } + + return( etype ); +} +/* enumerations from "../../libvips/include/vips/basic.h" */ +GType +vips_precision_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_PRECISION_INTEGER, "VIPS_PRECISION_INTEGER", "integer"}, + {VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"}, + {VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"}, + {VIPS_PRECISION_LAST, "VIPS_PRECISION_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsPrecision", values ); + } + + return( etype ); +} /* enumerations from "../../libvips/include/vips/object.h" */ GType vips_argument_flags_get_type( void ) @@ -847,27 +932,6 @@ vips_argument_flags_get_type( void ) return( etype ); } -/* enumerations from "../../libvips/include/vips/operation.h" */ -GType -vips_operation_flags_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GFlagsValue values[] = { - {VIPS_OPERATION_NONE, "VIPS_OPERATION_NONE", "none"}, - {VIPS_OPERATION_SEQUENTIAL, "VIPS_OPERATION_SEQUENTIAL", "sequential"}, - {VIPS_OPERATION_SEQUENTIAL_UNBUFFERED, "VIPS_OPERATION_SEQUENTIAL_UNBUFFERED", "sequential-unbuffered"}, - {VIPS_OPERATION_NOCACHE, "VIPS_OPERATION_NOCACHE", "nocache"}, - {VIPS_OPERATION_DEPRECATED, "VIPS_OPERATION_DEPRECATED", "deprecated"}, - {0, NULL, NULL} - }; - - etype = g_flags_register_static( "VipsOperationFlags", values ); - } - - return( etype ); -} /* enumerations from "../../libvips/include/vips/region.h" */ GType vips_region_shrink_get_type( void ) @@ -888,70 +952,6 @@ vips_region_shrink_get_type( void ) return( etype ); } -/* enumerations from "../../libvips/include/vips/resample.h" */ -GType -vips_kernel_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_KERNEL_NEAREST, "VIPS_KERNEL_NEAREST", "nearest"}, - {VIPS_KERNEL_LINEAR, "VIPS_KERNEL_LINEAR", "linear"}, - {VIPS_KERNEL_CUBIC, "VIPS_KERNEL_CUBIC", "cubic"}, - {VIPS_KERNEL_MITCHELL, "VIPS_KERNEL_MITCHELL", "mitchell"}, - {VIPS_KERNEL_LANCZOS2, "VIPS_KERNEL_LANCZOS2", "lanczos2"}, - {VIPS_KERNEL_LANCZOS3, "VIPS_KERNEL_LANCZOS3", "lanczos3"}, - {VIPS_KERNEL_LAST, "VIPS_KERNEL_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsKernel", values ); - } - - return( etype ); -} -GType -vips_size_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_SIZE_BOTH, "VIPS_SIZE_BOTH", "both"}, - {VIPS_SIZE_UP, "VIPS_SIZE_UP", "up"}, - {VIPS_SIZE_DOWN, "VIPS_SIZE_DOWN", "down"}, - {VIPS_SIZE_FORCE, "VIPS_SIZE_FORCE", "force"}, - {VIPS_SIZE_LAST, "VIPS_SIZE_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsSize", values ); - } - - return( etype ); -} -/* enumerations from "../../libvips/include/vips/util.h" */ -GType -vips_token_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_TOKEN_LEFT, "VIPS_TOKEN_LEFT", "left"}, - {VIPS_TOKEN_RIGHT, "VIPS_TOKEN_RIGHT", "right"}, - {VIPS_TOKEN_STRING, "VIPS_TOKEN_STRING", "string"}, - {VIPS_TOKEN_EQUALS, "VIPS_TOKEN_EQUALS", "equals"}, - {VIPS_TOKEN_COMMA, "VIPS_TOKEN_COMMA", "comma"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsToken", values ); - } - - return( etype ); -} /* Generated data ends here */ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 7520f70b..2116f222 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -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", diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 8c7a9e99..39567f53 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -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, diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index 42f84c0c..327b95b9 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -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 ); } diff --git a/libvips/iofuncs/reorder.c b/libvips/iofuncs/reorder.c index 30259a3e..0994a900 100644 --- a/libvips/iofuncs/reorder.c +++ b/libvips/iofuncs/reorder.c @@ -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 diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 3d5b84c1..b815d605 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -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; diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index b715403b..e0eeb734 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -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 diff --git a/libvips/resample/interpolate.c b/libvips/resample/interpolate.c index a002070d..ffa4f476 100644 --- a/libvips/resample/interpolate.c +++ b/libvips/resample/interpolate.c @@ -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; \ diff --git a/libvips/resample/mapim.c b/libvips/resample/mapim.c index b582b8ad..a15ce6bc 100644 --- a/libvips/resample/mapim.c +++ b/libvips/resample/mapim.c @@ -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: diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index d3acdf4c..35d44c72 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -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,