Merge branch 'master' into revise-thumbnail
This commit is contained in:
commit
15ee957ea9
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
12
configure.ac
12
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)]))
|
||||
|
@ -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
|
||||
|
@ -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 )) ) {
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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';
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
|
@ -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*/
|
||||
|
@ -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
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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; \
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user