diff --git a/ChangeLog b/ChangeLog index 846f3e47..6cd85103 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,10 +36,8 @@ we get expat as part of glib - add vips_smartcrop(), based on sharp's smartcropper - vipsthumbnail has a --smartcrop option -- the C functions vips_math2_const(), vips_boolean_const() and - vips_relational_const() have changed argument order to match - Python/CLI/C++ ... sorry - added vips_rot90() etc. convenience functions +- fix vips_resize() bug when hscale and vscale were very different 8/12/16 started 8.4.5 - allow libgsf-1.14.26 to help centos, thanks tdiprima diff --git a/TODO b/TODO index f2d03d0f..36f83c6e 100644 --- a/TODO +++ b/TODO @@ -17,10 +17,6 @@ - try moving some more of the CLI tests to py -- try SEQ_UNBUFFERED on jpg source, get out of order error? - -- could load pdf thumbnails? - - colour needs to split _build() into preprocess / process / postprocess phases @@ -63,32 +59,20 @@ - why can't we do - -im = Vips.Image.new_from_file("/data/john/pics/k2.jpg", access = "sequential") - - - -import logging -logging.basicConfig(level = logging.DEBUG) -from gi.repository import Vips -im = Vips.Image.new_from_file("/data/john/pics/k2.jpg", access = "sequential") - -DEBUG:gi.overrides.Vips:assigning sequential to access -DEBUG:gi.overrides.Vips:access needs a -DEBUG:gi.overrides.Vips:assigning sequential - - ValueError: invalid literal for int() with base 10: 'sequential' + im = Vips.Image.new_from_file("/data/john/pics/k2.jpg", access = "sequential") no idea ... this works fine: im.embed(10, 10, 100, 100, extend = "copy") - what about + test: - im = Vips.Image.jpegload(sys.argv[1], access = "sequential") - - nope, fails too ... mysterious! + op = Vips.Operation.new("embed") + op.props.__setattr__("extend", "copy") + op = Vips.Operation.new("jpegload") + op.props.__setattr__("access", "sequential") + first setattr works fine, second fails with invalid literal @@ -437,4 +421,3 @@ new operations http://www.nature.com/srep/2015/150730/srep12096/full/srep12096.html sounds useful for BM? - diff --git a/cplusplus/VImage.cpp b/cplusplus/VImage.cpp index e617b3f7..27b29fdf 100644 --- a/cplusplus/VImage.cpp +++ b/cplusplus/VImage.cpp @@ -982,29 +982,29 @@ operator<( VImage a, VImage b ) VImage operator<( double a, VImage b ) { - return( b.relational_const( to_vector( a ), - VIPS_OPERATION_RELATIONAL_MORE ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_MORE, + to_vector( a ) ) ); } VImage operator<( VImage a, double b ) { - return( a.relational_const( to_vector( b ), - VIPS_OPERATION_RELATIONAL_LESS ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_LESS, + to_vector( b ) ) ); } VImage operator<( std::vector a, VImage b ) { - return( b.relational_const( a, - VIPS_OPERATION_RELATIONAL_MORE ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_MORE, + a ) ); } VImage operator<( VImage a, std::vector b ) { - return( a.relational_const( b, - VIPS_OPERATION_RELATIONAL_LESS ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_LESS, + b ) ); } VImage @@ -1016,29 +1016,29 @@ operator<=( VImage a, VImage b ) VImage operator<=( double a, VImage b ) { - return( b.relational_const( to_vector( a ), - VIPS_OPERATION_RELATIONAL_MOREEQ ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_MOREEQ, + to_vector( a ) ) ); } VImage operator<=( VImage a, double b ) { - return( a.relational_const( to_vector( b ), - VIPS_OPERATION_RELATIONAL_LESSEQ ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_LESSEQ, + to_vector( b ) ) ); } VImage operator<=( std::vector a, VImage b ) { - return( b.relational_const( a, - VIPS_OPERATION_RELATIONAL_MOREEQ ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_MOREEQ, + a ) ); } VImage operator<=( VImage a, std::vector b ) { - return( a.relational_const( b, - VIPS_OPERATION_RELATIONAL_LESSEQ ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_LESSEQ, + b ) ); } VImage @@ -1050,29 +1050,29 @@ operator>( VImage a, VImage b ) VImage operator>( double a, VImage b ) { - return( b.relational_const( to_vector( a ), - VIPS_OPERATION_RELATIONAL_LESS ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_LESS, + to_vector( a ) ) ); } VImage operator>( VImage a, double b ) { - return( a.relational_const( to_vector( b ), - VIPS_OPERATION_RELATIONAL_MORE ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_MORE, + to_vector( b ) ) ); } VImage operator>( std::vector a, VImage b ) { - return( b.relational_const( a, - VIPS_OPERATION_RELATIONAL_LESS ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_LESS, + a ) ); } VImage operator>( VImage a, std::vector b ) { - return( a.relational_const( b, - VIPS_OPERATION_RELATIONAL_MORE ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_MORE, + b ) ); } VImage @@ -1084,29 +1084,29 @@ operator>=( VImage a, VImage b ) VImage operator>=( double a, VImage b ) { - return( b.relational_const( to_vector( a ), - VIPS_OPERATION_RELATIONAL_LESSEQ ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_LESSEQ, + to_vector( a ) ) ); } VImage operator>=( VImage a, double b ) { - return( a.relational_const( to_vector( b ), - VIPS_OPERATION_RELATIONAL_MOREEQ ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_MOREEQ, + to_vector( b ) ) ); } VImage operator>=( std::vector a, VImage b ) { - return( b.relational_const( a, - VIPS_OPERATION_RELATIONAL_LESSEQ ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_LESSEQ, + a ) ); } VImage operator>=( VImage a, std::vector b ) { - return( a.relational_const( b, - VIPS_OPERATION_RELATIONAL_MOREEQ ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_MOREEQ, + b ) ); } VImage @@ -1118,29 +1118,29 @@ operator==( VImage a, VImage b ) VImage operator==( double a, VImage b ) { - return( b.relational_const( to_vector( a ), - VIPS_OPERATION_RELATIONAL_EQUAL ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_EQUAL, + to_vector( a ) ) ); } VImage operator==( VImage a, double b ) { - return( a.relational_const( to_vector( b ), - VIPS_OPERATION_RELATIONAL_EQUAL ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_EQUAL, + to_vector( b ) ) ); } VImage operator==( std::vector a, VImage b ) { - return( b.relational_const( a, - VIPS_OPERATION_RELATIONAL_EQUAL ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_EQUAL, + a ) ); } VImage operator==( VImage a, std::vector b ) { - return( a.relational_const( b, - VIPS_OPERATION_RELATIONAL_EQUAL ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_EQUAL, + b ) ); } VImage @@ -1152,29 +1152,29 @@ operator!=( VImage a, VImage b ) VImage operator!=( double a, VImage b ) { - return( b.relational_const( to_vector( a ), - VIPS_OPERATION_RELATIONAL_NOTEQ ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_NOTEQ, + to_vector( a ) ) ); } VImage operator!=( VImage a, double b ) { - return( a.relational_const( to_vector( b ), - VIPS_OPERATION_RELATIONAL_NOTEQ ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_NOTEQ, + to_vector( b ) ) ); } VImage operator!=( std::vector a, VImage b ) { - return( b.relational_const( a, - VIPS_OPERATION_RELATIONAL_NOTEQ ) ); + return( b.relational_const( VIPS_OPERATION_RELATIONAL_NOTEQ, + a ) ); } VImage operator!=( VImage a, std::vector b ) { - return( a.relational_const( b, - VIPS_OPERATION_RELATIONAL_NOTEQ ) ); + return( a.relational_const( VIPS_OPERATION_RELATIONAL_NOTEQ, + b ) ); } VImage @@ -1186,27 +1186,27 @@ operator&( VImage a, VImage b ) VImage operator&( double a, VImage b ) { - return( b.boolean_const( to_vector( a ), - VIPS_OPERATION_BOOLEAN_AND ) ); + return( b.boolean_const( VIPS_OPERATION_BOOLEAN_AND, + to_vector( a ) ) ); } VImage operator&( VImage a, double b ) { - return( a.boolean_const( to_vector( b ), - VIPS_OPERATION_BOOLEAN_AND ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_AND, + to_vector( b ) ) ); } VImage operator&( std::vector a, VImage b ) { - return( b.boolean_const( a, VIPS_OPERATION_BOOLEAN_AND ) ); + return( b.boolean_const( VIPS_OPERATION_BOOLEAN_AND, a ) ); } VImage operator&( VImage a, std::vector b ) { - return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_AND ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_AND, b ) ); } VImage & @@ -1236,27 +1236,29 @@ operator|( VImage a, VImage b ) VImage operator|( double a, VImage b ) { - return( b.boolean_const( to_vector( a ), - VIPS_OPERATION_BOOLEAN_OR ) ); + return( b.boolean_const( VIPS_OPERATION_BOOLEAN_OR, + to_vector( a ) ) ); } VImage operator|( VImage a, double b ) { - return( a.boolean_const( to_vector( b ), - VIPS_OPERATION_BOOLEAN_OR ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_OR, + to_vector( b ) ) ); } VImage operator|( std::vector a, VImage b ) { - return( b.boolean_const( a, VIPS_OPERATION_BOOLEAN_OR ) ); + return( b.boolean_const( VIPS_OPERATION_BOOLEAN_OR, + a ) ); } VImage operator|( VImage a, std::vector b ) { - return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_OR ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_OR, + b ) ); } VImage & @@ -1286,27 +1288,29 @@ operator^( VImage a, VImage b ) VImage operator^( double a, VImage b ) { - return( b.boolean_const( to_vector( a ), - VIPS_OPERATION_BOOLEAN_EOR ) ); + return( b.boolean_const( VIPS_OPERATION_BOOLEAN_EOR, + to_vector( a ) ) ); } VImage operator^( VImage a, double b ) { - return( a.boolean_const( to_vector( b ), - VIPS_OPERATION_BOOLEAN_EOR ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_EOR, + to_vector( b ) ) ); } VImage operator^( std::vector a, VImage b ) { - return( b.boolean_const( a, VIPS_OPERATION_BOOLEAN_EOR ) ); + return( b.boolean_const( VIPS_OPERATION_BOOLEAN_EOR, + a ) ); } VImage operator^( VImage a, std::vector b ) { - return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_EOR ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_EOR, + b ) ); } VImage & @@ -1336,14 +1340,15 @@ operator<<( VImage a, VImage b ) VImage operator<<( VImage a, double b ) { - return( a.boolean_const( to_vector( b ), - VIPS_OPERATION_BOOLEAN_LSHIFT ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_LSHIFT, + to_vector( b ) ) ); } VImage operator<<( VImage a, std::vector b ) { - return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_LSHIFT ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_LSHIFT, + b ) ); } VImage & @@ -1373,14 +1378,15 @@ operator>>( VImage a, VImage b ) VImage operator>>( VImage a, double b ) { - return( a.boolean_const( to_vector( b ), - VIPS_OPERATION_BOOLEAN_RSHIFT ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_RSHIFT, + to_vector( b ) ) ); } VImage operator>>( VImage a, std::vector b ) { - return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_RSHIFT ) ); + return( a.boolean_const( VIPS_OPERATION_BOOLEAN_RSHIFT, + b ) ); } VImage & diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index 00d05896..b23a76d8 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -699,15 +699,15 @@ public: VImage pow( double other, VOption *options = 0 ) { - return( math2_const( to_vector( other ), - VIPS_OPERATION_MATH2_POW, options ) ); + return( math2_const( VIPS_OPERATION_MATH2_POW, + to_vector( other ), options ) ); } VImage pow( std::vector other, VOption *options = 0 ) { - return( math2_const( other, - VIPS_OPERATION_MATH2_POW, options ) ); + return( math2_const( VIPS_OPERATION_MATH2_POW, + other, options ) ); } VImage @@ -719,15 +719,15 @@ public: VImage wop( double other, VOption *options = 0 ) { - return( math2_const( to_vector( other ), - VIPS_OPERATION_MATH2_WOP, options ) ); + return( math2_const( VIPS_OPERATION_MATH2_WOP, + to_vector( other ), options ) ); } VImage wop( std::vector other, VOption *options = 0 ) { - return( math2_const( other, - VIPS_OPERATION_MATH2_WOP, options ) ); + return( math2_const( VIPS_OPERATION_MATH2_WOP, + other, options ) ); } VImage diff --git a/cplusplus/include/vips/vips-operators.h b/cplusplus/include/vips/vips-operators.h index 889f7440..68df252a 100644 --- a/cplusplus/include/vips/vips-operators.h +++ b/cplusplus/include/vips/vips-operators.h @@ -1,5 +1,5 @@ // headers for vips operations -// Wed 1 Mar 15:40:22 GMT 2017 +// Mon 13 Mar 13:22:09 GMT 2017 // this file is generated automatically, do not edit! static void system( char * cmd_format , VOption *options = 0 ); @@ -20,10 +20,10 @@ VImage math( VipsOperationMath math , VOption *options = 0 ); VImage abs( VOption *options = 0 ); VImage sign( VOption *options = 0 ); VImage round( VipsOperationRound round , VOption *options = 0 ); -VImage relational_const( std::vector c , VipsOperationRelational relational , VOption *options = 0 ); +VImage relational_const( VipsOperationRelational relational , std::vector c , VOption *options = 0 ); VImage remainder_const( std::vector c , VOption *options = 0 ); -VImage boolean_const( std::vector c , VipsOperationBoolean boolean , VOption *options = 0 ); -VImage math2_const( std::vector c , VipsOperationMath2 math2 , VOption *options = 0 ); +VImage boolean_const( VipsOperationBoolean boolean , std::vector c , VOption *options = 0 ); +VImage math2_const( VipsOperationMath2 math2 , std::vector c , VOption *options = 0 ); VImage complex( VipsOperationComplex cmplx , VOption *options = 0 ); VImage complexget( VipsOperationComplexget get , VOption *options = 0 ); double avg( VOption *options = 0 ); diff --git a/cplusplus/vips-operators.cpp b/cplusplus/vips-operators.cpp index a063cb09..bff2a745 100644 --- a/cplusplus/vips-operators.cpp +++ b/cplusplus/vips-operators.cpp @@ -1,5 +1,5 @@ // bodies for vips operations -// Wed 1 Mar 15:40:06 GMT 2017 +// Mon 13 Mar 13:22:17 GMT 2017 // this file is generated automatically, do not edit! void VImage::system( char * cmd_format , VOption *options ) @@ -231,7 +231,7 @@ VImage VImage::round( VipsOperationRound round , VOption *options ) return( out ); } -VImage VImage::relational_const( std::vector c , VipsOperationRelational relational , VOption *options ) +VImage VImage::relational_const( VipsOperationRelational relational , std::vector c , VOption *options ) { VImage out; @@ -239,8 +239,8 @@ VImage VImage::relational_const( std::vector c , VipsOperationRelational (options ? options : VImage::option()) -> set( "in", *this ) -> set( "out", &out ) -> - set( "c", c ) -> - set( "relational", relational ) ); + set( "relational", relational ) -> + set( "c", c ) ); return( out ); } @@ -258,7 +258,7 @@ VImage VImage::remainder_const( std::vector c , VOption *options ) return( out ); } -VImage VImage::boolean_const( std::vector c , VipsOperationBoolean boolean , VOption *options ) +VImage VImage::boolean_const( VipsOperationBoolean boolean , std::vector c , VOption *options ) { VImage out; @@ -266,13 +266,13 @@ VImage VImage::boolean_const( std::vector c , VipsOperationBoolean boole (options ? options : VImage::option()) -> set( "in", *this ) -> set( "out", &out ) -> - set( "c", c ) -> - set( "boolean", boolean ) ); + set( "boolean", boolean ) -> + set( "c", c ) ); return( out ); } -VImage VImage::math2_const( std::vector c , VipsOperationMath2 math2 , VOption *options ) +VImage VImage::math2_const( VipsOperationMath2 math2 , std::vector c , VOption *options ) { VImage out; @@ -280,8 +280,8 @@ VImage VImage::math2_const( std::vector c , VipsOperationMath2 math2 , V (options ? options : VImage::option()) -> set( "in", *this ) -> set( "out", &out ) -> - set( "c", c ) -> - set( "math2", math2 ) ); + set( "math2", math2 ) -> + set( "c", c ) ); return( out ); } @@ -493,8 +493,8 @@ VImage VImage::copy( VOption *options ) call( "copy" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -505,8 +505,8 @@ VImage VImage::tilecache( VOption *options ) call( "tilecache" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -517,8 +517,8 @@ VImage VImage::linecache( VOption *options ) call( "linecache" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -529,8 +529,8 @@ VImage VImage::sequential( VOption *options ) call( "sequential" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -541,8 +541,8 @@ VImage VImage::cache( VOption *options ) call( "cache" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -569,8 +569,8 @@ VImage VImage::flip( VipsDirection direction , VOption *options ) call( "flip" , (options ? options : VImage::option()) -> - set( "out", &out ) -> set( "in", *this ) -> + set( "out", &out ) -> set( "direction", direction ) ); return( out ); @@ -742,8 +742,8 @@ VImage VImage::cast( VipsBandFormat format , VOption *options ) call( "cast" , (options ? options : VImage::option()) -> - set( "out", &out ) -> set( "in", *this ) -> + set( "out", &out ) -> set( "format", format ) ); return( out ); @@ -755,8 +755,8 @@ VImage VImage::rot( VipsAngle angle , VOption *options ) call( "rot" , (options ? options : VImage::option()) -> - set( "out", &out ) -> set( "in", *this ) -> + set( "out", &out ) -> set( "angle", angle ) ); return( out ); @@ -768,8 +768,8 @@ VImage VImage::rot45( VOption *options ) call( "rot45" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -780,8 +780,8 @@ VImage VImage::autorot( VOption *options ) call( "autorot" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -819,8 +819,8 @@ VImage VImage::bandfold( VOption *options ) call( "bandfold" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -831,8 +831,8 @@ VImage VImage::bandunfold( VOption *options ) call( "bandunfold" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -843,8 +843,8 @@ VImage VImage::flatten( VOption *options ) call( "flatten" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -855,8 +855,8 @@ VImage VImage::premultiply( VOption *options ) call( "premultiply" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -867,8 +867,8 @@ VImage VImage::unpremultiply( VOption *options ) call( "unpremultiply" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -879,8 +879,8 @@ VImage VImage::grid( int tile_height , int across , int down , VOption *options call( "grid" , (options ? options : VImage::option()) -> - set( "out", &out ) -> set( "in", *this ) -> + set( "out", &out ) -> set( "tile-height", tile_height ) -> set( "across", across ) -> set( "down", down ) ); @@ -894,8 +894,8 @@ VImage VImage::scale( VOption *options ) call( "scale" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -906,8 +906,8 @@ VImage VImage::wrap( VOption *options ) call( "wrap" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } @@ -958,8 +958,8 @@ VImage VImage::byteswap( VOption *options ) call( "byteswap" , (options ? options : VImage::option()) -> - set( "out", &out ) -> - set( "in", *this ) ); + set( "in", *this ) -> + set( "out", &out ) ); return( out ); } diff --git a/libvips/arithmetic/boolean.c b/libvips/arithmetic/boolean.c index 80e2272c..2ed8594e 100644 --- a/libvips/arithmetic/boolean.c +++ b/libvips/arithmetic/boolean.c @@ -533,7 +533,7 @@ vips_boolean_const_init( VipsBooleanConst *boolean_const ) static int vips_boolean_constv( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationBoolean operation, va_list ap ) + VipsOperationBoolean operation, double *c, int n, va_list ap ) { VipsArea *area_c; double *array; @@ -546,7 +546,7 @@ vips_boolean_constv( VipsImage *in, VipsImage **out, array[i] = c[i]; result = vips_call_split( "boolean_const", ap, - in, out, area_c, operation ); + in, out, operation, area_c ); vips_area_unref( area_c ); @@ -557,9 +557,9 @@ vips_boolean_constv( VipsImage *in, VipsImage **out, * vips_boolean_const: * @in: input image * @out: output image + * @boolean: boolean operation to perform * @c: array of constants * @n: number of constants in @c - * @boolean: boolean operation to perform * @...: %NULL-terminated list of optional named arguments * * Perform various boolean operations on an image against an array of @@ -580,13 +580,13 @@ vips_boolean_constv( VipsImage *in, VipsImage **out, */ int vips_boolean_const( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationBoolean boolean, ... ) + VipsOperationBoolean boolean, double *c, int n, ... ) { va_list ap; int result; - va_start( ap, boolean ); - result = vips_boolean_constv( in, out, c, n, boolean, ap ); + va_start( ap, n ); + result = vips_boolean_constv( in, out, boolean, c, n, ap ); va_end( ap ); return( result ); @@ -615,7 +615,7 @@ vips_andimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_boolean_constv( in, out, - c, n, VIPS_OPERATION_BOOLEAN_AND, ap ); + VIPS_OPERATION_BOOLEAN_AND, c, n, ap ); va_end( ap ); return( result ); @@ -644,7 +644,7 @@ vips_orimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_boolean_constv( in, out, - c, n, VIPS_OPERATION_BOOLEAN_OR, ap ); + VIPS_OPERATION_BOOLEAN_OR, c, n, ap ); va_end( ap ); return( result ); @@ -673,7 +673,7 @@ vips_eorimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_boolean_constv( in, out, - c, n, VIPS_OPERATION_BOOLEAN_EOR, ap ); + VIPS_OPERATION_BOOLEAN_EOR, c, n, ap ); va_end( ap ); return( result ); @@ -702,7 +702,7 @@ vips_lshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_boolean_constv( in, out, - c, n, VIPS_OPERATION_BOOLEAN_LSHIFT, ap ); + VIPS_OPERATION_BOOLEAN_LSHIFT, c, n, ap ); va_end( ap ); return( result ); @@ -731,7 +731,7 @@ vips_rshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_boolean_constv( in, out, - c, n, VIPS_OPERATION_BOOLEAN_RSHIFT, ap ); + VIPS_OPERATION_BOOLEAN_RSHIFT, c, n, ap ); va_end( ap ); return( result ); @@ -754,13 +754,13 @@ vips_rshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) */ int vips_boolean_const1( VipsImage *in, VipsImage **out, - double c, VipsOperationBoolean boolean, ... ) + VipsOperationBoolean boolean, double c, ... ) { va_list ap; int result; - va_start( ap, boolean ); - result = vips_boolean_constv( in, out, &c, 1, boolean, ap ); + va_start( ap, c ); + result = vips_boolean_constv( in, out, boolean, &c, 1, ap ); va_end( ap ); return( result ); @@ -788,7 +788,7 @@ vips_andimage_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_boolean_constv( in, out, - &c, 1, VIPS_OPERATION_BOOLEAN_AND, ap ); + VIPS_OPERATION_BOOLEAN_AND, &c, 1, ap ); va_end( ap ); return( result ); @@ -816,7 +816,7 @@ vips_orimage_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_boolean_constv( in, out, - &c, 1, VIPS_OPERATION_BOOLEAN_OR, ap ); + VIPS_OPERATION_BOOLEAN_OR, &c, 1, ap ); va_end( ap ); return( result ); @@ -844,7 +844,7 @@ vips_eorimage_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_boolean_constv( in, out, - &c, 1, VIPS_OPERATION_BOOLEAN_EOR, ap ); + VIPS_OPERATION_BOOLEAN_EOR, &c, 1, ap ); va_end( ap ); return( result ); @@ -872,7 +872,7 @@ vips_lshift_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_boolean_constv( in, out, - &c, 1, VIPS_OPERATION_BOOLEAN_LSHIFT, ap ); + VIPS_OPERATION_BOOLEAN_LSHIFT, &c, 1, ap ); va_end( ap ); return( result ); @@ -900,7 +900,7 @@ vips_rshift_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_boolean_constv( in, out, - &c, 1, VIPS_OPERATION_BOOLEAN_RSHIFT, ap ); + VIPS_OPERATION_BOOLEAN_RSHIFT, &c, 1, ap ); va_end( ap ); return( result ); diff --git a/libvips/arithmetic/math2.c b/libvips/arithmetic/math2.c index 651e5829..90adecaf 100644 --- a/libvips/arithmetic/math2.c +++ b/libvips/arithmetic/math2.c @@ -421,7 +421,7 @@ vips_math2_const_init( VipsMath2Const *math2_const ) static int vips_math2_constv( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationMath2 math2, va_list ap ) + VipsOperationMath2 math2, double *c, int n, va_list ap ) { VipsArea *area_c; double *array; @@ -433,7 +433,7 @@ vips_math2_constv( VipsImage *in, VipsImage **out, for( i = 0; i < n; i++ ) array[i] = c[i]; - result = vips_call_split( "math2_const", ap, in, out, area_c, math2 ); + result = vips_call_split( "math2_const", ap, in, out, math2, area_c ); vips_area_unref( area_c ); @@ -444,9 +444,9 @@ vips_math2_constv( VipsImage *in, VipsImage **out, * vips_math2_const: * @in: input image * @out: output image + * @math2: math operation to perform * @c: array of constants * @n: number of constants in @c - * @math2: math operation to perform * @...: %NULL-terminated list of optional named arguments * * This operation calculates various 2-ary maths operations on an image and @@ -471,13 +471,13 @@ vips_math2_constv( VipsImage *in, VipsImage **out, */ int vips_math2_const( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationMath2 math2, ... ) + VipsOperationMath2 math2, double *c, int n, ... ) { va_list ap; int result; - va_start( ap, math2 ); - result = vips_math2_constv( in, out, c, n, math2, ap ); + va_start( ap, n ); + result = vips_math2_constv( in, out, math2, c, n, ap ); va_end( ap ); return( result ); @@ -504,7 +504,7 @@ vips_pow_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_math2_constv( in, out, - c, n, VIPS_OPERATION_MATH2_POW, ap ); + VIPS_OPERATION_MATH2_POW, c, n, ap ); va_end( ap ); return( result ); @@ -531,7 +531,7 @@ vips_wop_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_math2_constv( in, out, - c, n, VIPS_OPERATION_MATH2_WOP, ap ); + VIPS_OPERATION_MATH2_WOP, c, n, ap ); va_end( ap ); return( result ); @@ -552,13 +552,13 @@ vips_wop_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) */ int vips_math2_const1( VipsImage *in, VipsImage **out, - double c, VipsOperationMath2 math2, ... ) + VipsOperationMath2 math2, double c, ... ) { va_list ap; int result; - va_start( ap, math2 ); - result = vips_math2_constv( in, out, &c, 1, math2, ap ); + va_start( ap, c ); + result = vips_math2_constv( in, out, math2, &c, 1, ap ); va_end( ap ); return( result ); @@ -584,7 +584,7 @@ vips_pow_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_math2_constv( in, out, - &c, 1, VIPS_OPERATION_MATH2_POW, ap ); + VIPS_OPERATION_MATH2_POW, &c, 1, ap ); va_end( ap ); return( result ); @@ -610,7 +610,7 @@ vips_wop_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_math2_constv( in, out, - &c, 1, VIPS_OPERATION_MATH2_WOP, ap ); + VIPS_OPERATION_MATH2_WOP, &c, 1, ap ); va_end( ap ); return( result ); diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index 1898c8e1..96dda30d 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -574,7 +574,7 @@ vips_relational_const_init( VipsRelationalConst *relational_const ) static int vips_relational_constv( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationRelational relational, va_list ap ) + VipsOperationRelational relational, double *c, int n, va_list ap ) { VipsArea *area_c; double *array; @@ -587,7 +587,7 @@ vips_relational_constv( VipsImage *in, VipsImage **out, array[i] = c[i]; result = vips_call_split( "relational_const", ap, - in, out, area_c, relational ); + in, out, relational, area_c ); vips_area_unref( area_c ); @@ -598,9 +598,9 @@ vips_relational_constv( VipsImage *in, VipsImage **out, * vips_relational_const: * @in: input image * @out: output image + * @relational: relational operation to perform * @c: array of constants * @n: number of constants in @c - * @relational: relational operation to perform * @...: %NULL-terminated list of optional named arguments * * Perform various relational operations on an image and an array of @@ -621,13 +621,13 @@ vips_relational_constv( VipsImage *in, VipsImage **out, */ int vips_relational_const( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationRelational relational, ... ) + VipsOperationRelational relational, double *c, int n, ... ) { va_list ap; int result; - va_start( ap, relational ); - result = vips_relational_constv( in, out, c, n, relational, ap ); + va_start( ap, n ); + result = vips_relational_constv( in, out, relational, c, n, ap ); va_end( ap ); return( result ); @@ -654,7 +654,7 @@ vips_equal_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_relational_constv( in, out, - c, n, VIPS_OPERATION_RELATIONAL_EQUAL, ap ); + VIPS_OPERATION_RELATIONAL_EQUAL, c, n, ap ); va_end( ap ); return( result ); @@ -681,7 +681,7 @@ vips_notequal_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_relational_constv( in, out, - c, n, VIPS_OPERATION_RELATIONAL_NOTEQ, ap ); + VIPS_OPERATION_RELATIONAL_NOTEQ, c, n, ap ); va_end( ap ); return( result ); @@ -708,7 +708,7 @@ vips_less_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_relational_constv( in, out, - c, n, VIPS_OPERATION_RELATIONAL_LESS, ap ); + VIPS_OPERATION_RELATIONAL_LESS, c, n, ap ); va_end( ap ); return( result ); @@ -735,7 +735,7 @@ vips_lesseq_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_relational_constv( in, out, - c, n, VIPS_OPERATION_RELATIONAL_LESSEQ, ap ); + VIPS_OPERATION_RELATIONAL_LESSEQ, c, n, ap ); va_end( ap ); return( result ); @@ -762,7 +762,7 @@ vips_more_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_relational_constv( in, out, - c, n, VIPS_OPERATION_RELATIONAL_MORE, ap ); + VIPS_OPERATION_RELATIONAL_MORE, c, n, ap ); va_end( ap ); return( result ); @@ -789,7 +789,7 @@ vips_moreeq_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) va_start( ap, n ); result = vips_relational_constv( in, out, - c, n, VIPS_OPERATION_RELATIONAL_MOREEQ, ap ); + VIPS_OPERATION_RELATIONAL_MOREEQ, c, n, ap ); va_end( ap ); return( result ); @@ -799,8 +799,8 @@ vips_moreeq_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) * vips_relational_const1: * @in: input image * @out: output image - * @c: constant * @relational: relational operation to perform + * @c: constant * @...: %NULL-terminated list of optional named arguments * * Perform various relational operations on an image and a constant. See @@ -812,13 +812,13 @@ vips_moreeq_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) */ int vips_relational_const1( VipsImage *in, VipsImage **out, - double c, VipsOperationRelational relational, ... ) + VipsOperationRelational relational, double c, ... ) { va_list ap; int result; - va_start( ap, relational ); - result = vips_relational_constv( in, out, &c, 1, relational, ap ); + va_start( ap, c ); + result = vips_relational_constv( in, out, relational, &c, 1, ap ); va_end( ap ); return( result ); @@ -844,7 +844,7 @@ vips_equal_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_relational_constv( in, out, - &c, 1, VIPS_OPERATION_RELATIONAL_EQUAL, ap ); + VIPS_OPERATION_RELATIONAL_EQUAL, &c, 1, ap ); va_end( ap ); return( result ); @@ -870,7 +870,7 @@ vips_notequal_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_relational_constv( in, out, - &c, 1, VIPS_OPERATION_RELATIONAL_NOTEQ, ap ); + VIPS_OPERATION_RELATIONAL_NOTEQ, &c, 1, ap ); va_end( ap ); return( result ); @@ -896,7 +896,7 @@ vips_less_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_relational_constv( in, out, - &c, 1, VIPS_OPERATION_RELATIONAL_LESS, ap ); + VIPS_OPERATION_RELATIONAL_LESS, &c, 1, ap ); va_end( ap ); return( result ); @@ -922,7 +922,7 @@ vips_lesseq_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_relational_constv( in, out, - &c, 1, VIPS_OPERATION_RELATIONAL_LESSEQ, ap ); + VIPS_OPERATION_RELATIONAL_LESSEQ, &c, 1, ap ); va_end( ap ); return( result ); @@ -948,7 +948,7 @@ vips_more_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_relational_constv( in, out, - &c, 1, VIPS_OPERATION_RELATIONAL_MORE, ap ); + VIPS_OPERATION_RELATIONAL_MORE, &c, 1, ap ); va_end( ap ); return( result ); @@ -974,7 +974,7 @@ vips_moreeq_const1( VipsImage *in, VipsImage **out, double c, ... ) va_start( ap, c ); result = vips_relational_constv( in, out, - &c, 1, VIPS_OPERATION_RELATIONAL_MOREEQ, ap ); + VIPS_OPERATION_RELATIONAL_MOREEQ, &c, 1, ap ); va_end( ap ); return( result ); diff --git a/libvips/arithmetic/unaryconst.c b/libvips/arithmetic/unaryconst.c index a3eacad7..b5cbf797 100644 --- a/libvips/arithmetic/unaryconst.c +++ b/libvips/arithmetic/unaryconst.c @@ -203,7 +203,7 @@ vips_unary_const_class_init( VipsUnaryConstClass *class ) object_class->description = _( "unary operations with a constant" ); object_class->build = vips_unary_const_build; - VIPS_ARG_BOXED( class, "c", 199, + VIPS_ARG_BOXED( class, "c", 201, _( "c" ), _( "Array of constants" ), VIPS_ARGUMENT_REQUIRED_INPUT, diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 29de1e09..db23ec21 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2749,7 +2749,7 @@ vips__relational_vec( IMAGE *in, IMAGE *out, { VipsImage *t; - if( vips_relational_const( in, &t, c, n, relational, + if( vips_relational_const( in, &t, relational, c, n, NULL ) ) return( -1 ); if( vips_image_write( t, out ) ) { @@ -2921,7 +2921,7 @@ vips__boolean_vec( IMAGE *in, IMAGE *out, { VipsImage *t; - if( vips_boolean_const( in, &t, c, n, boolean, + if( vips_boolean_const( in, &t, boolean, c, n, NULL ) ) return( -1 ); if( vips_image_write( t, out ) ) { @@ -3008,7 +3008,7 @@ vips__math2_vec( IMAGE *in, IMAGE *out, { VipsImage *t; - if( vips_math2_const( in, &t, c, n, math2, + if( vips_math2_const( in, &t, math2, c, n, NULL ) ) return( -1 ); if( vips_image_write( t, out ) ) { diff --git a/libvips/foreign/gifload.c b/libvips/foreign/gifload.c index 5b347ac6..c97a047c 100644 --- a/libvips/foreign/gifload.c +++ b/libvips/foreign/gifload.c @@ -805,7 +805,7 @@ vips_foreign_load_gif_class_init( VipsForeignLoadGifClass *class ) gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->nickname = "gifload"; + object_class->nickname = "gifload_base"; object_class->description = _( "load GIF with giflib" ); load_class->get_flags_filename = diff --git a/libvips/foreign/pdfload.c b/libvips/foreign/pdfload.c index a32591c2..7a621125 100644 --- a/libvips/foreign/pdfload.c +++ b/libvips/foreign/pdfload.c @@ -455,7 +455,7 @@ vips_foreign_load_pdf_class_init( VipsForeignLoadPdfClass *class ) gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->nickname = "pdfload"; + object_class->nickname = "pdfload_base"; object_class->description = _( "load PDF with libpoppler" ); object_class->build = vips_foreign_load_pdf_build; diff --git a/libvips/include/vips/arithmetic.h b/libvips/include/vips/arithmetic.h index ccee62f4..7c42e2d3 100644 --- a/libvips/include/vips/arithmetic.h +++ b/libvips/include/vips/arithmetic.h @@ -279,7 +279,7 @@ int vips_more( VipsImage *left, VipsImage *right, VipsImage **out, ... ) int vips_moreeq( VipsImage *left, VipsImage *right, VipsImage **out, ... ) __attribute__((sentinel)); int vips_relational_const( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationRelational relational, ... ) + VipsOperationRelational relational, double *c, int n, ... ) __attribute__((sentinel)); int vips_equal_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) __attribute__((sentinel)); @@ -294,7 +294,7 @@ int vips_more_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) int vips_moreeq_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) __attribute__((sentinel)); int vips_relational_const1( VipsImage *in, VipsImage **out, - double c, VipsOperationRelational relational, ... ) + VipsOperationRelational relational, double c, ... ) __attribute__((sentinel)); int vips_equal_const1( VipsImage *in, VipsImage **out, double c, ... ) __attribute__((sentinel)); @@ -324,7 +324,7 @@ int vips_rshift( VipsImage *left, VipsImage *right, VipsImage **out, ... ) __attribute__((sentinel)); int vips_boolean_const( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationBoolean boolean, ... ) + VipsOperationBoolean boolean, double *c, int n, ... ) __attribute__((sentinel)); int vips_andimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) __attribute__((sentinel)); @@ -337,7 +337,7 @@ int vips_lshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) int vips_rshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) __attribute__((sentinel)); int vips_boolean_const1( VipsImage *in, VipsImage **out, - double c, VipsOperationBoolean boolean, ... ) + VipsOperationBoolean boolean, double c, ... ) __attribute__((sentinel)); int vips_andimage_const1( VipsImage *in, VipsImage **out, double c, ... ) __attribute__((sentinel)); @@ -358,14 +358,14 @@ int vips_pow( VipsImage *left, VipsImage *right, VipsImage **out, ... ) int vips_wop( VipsImage *left, VipsImage *right, VipsImage **out, ... ) __attribute__((sentinel)); int vips_math2_const( VipsImage *in, VipsImage **out, - double *c, int n, VipsOperationMath2 math2, ... ) + VipsOperationMath2 math2, double *c, int n, ... ) __attribute__((sentinel)); int vips_pow_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) __attribute__((sentinel)); int vips_wop_const( VipsImage *in, VipsImage **out, double *c, int n, ... ) __attribute__((sentinel)); int vips_math2_const1( VipsImage *in, VipsImage **out, - double c, VipsOperationMath2 math2, ... ) + VipsOperationMath2 math2, double c, ... ) __attribute__((sentinel)); int vips_pow_const1( VipsImage *in, VipsImage **out, double c, ... ) __attribute__((sentinel)); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 79475600..8cd35a80 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1622,12 +1622,12 @@ vips_image_set_progress( VipsImage *image, gboolean progress ) * vips_image_iskilled: * @image: image to test * - * If @image has been killed (see vips_image_kill()), set an error message, + * If @image has been killed (see vips_image_set_kill()), set an error message, * clear the #VipsImage.kill flag and return %FALSE. Otherwise return %TRUE. * * Handy for loops which need to run sets of threads which can fail. * - * See also: vips_image_kill(). + * See also: vips_image_set_kill(). * * Returns: %FALSE if @image has been killed. */ diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 3cf3d7f7..8dab1ad5 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -832,6 +832,8 @@ vips_reducev_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_reducev_parent_class )->build( object ) ) return( -1 ); + g_info( "reducev by factor %g", reducev->vshrink ); + in = resample->in; if( reducev->vshrink < 1 ) { diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index 419717e5..52c88af8 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -127,7 +127,7 @@ vips_resize_int_shrink( VipsResize *resize, double scale ) case VIPS_KERNEL_LANCZOS2: case VIPS_KERNEL_LANCZOS3: - return( VIPS_MAX( 1, VIPS_FLOOR( 1.0 / (resize->scale * 2) ) ) ); + return( VIPS_MAX( 1, VIPS_FLOOR( 1.0 / (scale * 2) ) ) ); } } diff --git a/python/packages/gi/overrides/Vips.py b/python/packages/gi/overrides/Vips.py index f4440c6e..55043ae2 100644 --- a/python/packages/gi/overrides/Vips.py +++ b/python/packages/gi/overrides/Vips.py @@ -60,6 +60,11 @@ vips_type_image = GObject.GType.from_name("VipsImage") vips_type_operation = GObject.GType.from_name("VipsOperation") vips_type_ref_string = GObject.GType.from_name("VipsRefString") +# 8.4 and earlier had a bug which swapped the order of const args to enum +# operations +swap_const_args = Vips.version(0) < 8 or (Vips.version(0) == 8 and + Vips.version(1) <= 4) + def is_2D(value): if not isinstance(value, list): return False @@ -415,6 +420,27 @@ def _call_base(name, required, optional, self = None, option_string = None): return out +# handy for expanding enums +def _call_enum(self, name, enum, other): + if isinstance(other, Vips.Image): + return _call_base(name, [other, enum], {}, self) + elif swap_const_args: + return _call_base(name + "_const", [other, enum], {}, self) + else: + return _call_base(name + "_const", [enum, other], {}, self) + +# for equality style operations, we need to allow comparison with None +def _call_enum_eq(self, name, enum, other): + if isinstance(other, Vips.Image): + return _call_base(name, [other, enum], {}, self) + elif isinstance(other, list) or isinstance(other, numbers.Number): + if swap_const_args: + return _call_base(name + "_const", [other, enum], {}, self) + else: + return _call_base(name + "_const", [enum, other], {}, self) + else: + return False + # general user entrypoint def call(name, *args, **kwargs): return _call_base(name, args, kwargs) @@ -712,52 +738,34 @@ class Image(Vips.Image): return self.remainder_const(other) def __pow__(self, other): - if isinstance(other, Vips.Image): - return self.math2(other, Vips.OperationMath2.POW) - else: - return self.math2_const(other, Vips.OperationMath2.POW) + return _call_enum(self, "math2", Vips.OperationMath2.POW, other) def __rpow__(self, other): - return self.math2_const(other, Vips.OperationMath2.WOP) + return _call_enum(self, "math2", Vips.OperationMath2.WOP, other) def __abs__(self): return self.abs() def __lshift__(self, other): - if isinstance(other, Vips.Image): - return self.boolean(other, Vips.OperationBoolean.LSHIFT) - else: - return self.boolean_const(other, Vips.OperationBoolean.LSHIFT) + return _call_enum(self, "boolean", Vips.OperationBoolean.LSHIFT, other) def __rshift__(self, other): - if isinstance(other, Vips.Image): - return self.boolean(other, Vips.OperationBoolean.RSHIFT) - else: - return self.boolean_const(other, Vips.OperationBoolean.RSHIFT) + return _call_enum(self, "boolean", Vips.OperationBoolean.RSHIFT, other) def __and__(self, other): - if isinstance(other, Vips.Image): - return self.boolean(other, Vips.OperationBoolean.AND) - else: - return self.boolean_const(other, Vips.OperationBoolean.AND) + return _call_enum(self, "boolean", Vips.OperationBoolean.AND, other) def __rand__(self, other): return self.__and__(other) def __or__(self, other): - if isinstance(other, Vips.Image): - return self.boolean(other, Vips.OperationBoolean.OR) - else: - return self.boolean_const(other, Vips.OperationBoolean.OR) + return _call_enum(self, "boolean", Vips.OperationBoolean.OR, other) def __ror__(self, other): return self.__or__(other) def __xor__(self, other): - if isinstance(other, Vips.Image): - return self.boolean(other, Vips.OperationBoolean.EOR) - else: - return self.boolean_const(other, Vips.OperationBoolean.EOR) + return _call_enum(self, "boolean", Vips.OperationBoolean.EOR, other) def __rxor__(self, other): return self.__xor__(other) @@ -772,49 +780,30 @@ class Image(Vips.Image): return self ^ -1 def __gt__(self, other): - if isinstance(other, Vips.Image): - return self.relational(other, Vips.OperationRelational.MORE) - else: - return self.relational_const(other, Vips.OperationRelational.MORE) + return _call_enum(self, + "relational", Vips.OperationRelational.MORE, other) def __ge__(self, other): - if isinstance(other, Vips.Image): - return self.relational(other, Vips.OperationRelational.MOREEQ) - else: - return self.relational_const(other, Vips.OperationRelational.MOREEQ) + return _call_enum(self, + "relational", Vips.OperationRelational.MOREEQ, other) def __lt__(self, other): - if isinstance(other, Vips.Image): - return self.relational(other, Vips.OperationRelational.LESS) - else: - return self.relational_const(other, Vips.OperationRelational.LESS) + return _call_enum(self, + "relational", Vips.OperationRelational.LESS, other) def __le__(self, other): - if isinstance(other, Vips.Image): - return self.relational(other, Vips.OperationRelational.LESSEQ) - else: - return self.relational_const(other, Vips.OperationRelational.LESSEQ) + return _call_enum(self, + "relational", Vips.OperationRelational.LESSEQ, other) def __eq__(self, other): - # for == and != we need to allow comparison to None - if isinstance(other, Vips.Image): - return self.relational(other, Vips.OperationRelational.EQUAL) - elif isinstance(other, list): - return self.relational_const(other, Vips.OperationRelational.EQUAL) - elif isinstance(other, numbers.Number): - return self.relational_const(other, Vips.OperationRelational.EQUAL) - else: - return False + # _eq version allows comparison to None + return _call_enum_eq(self, + "relational", Vips.OperationRelational.EQUAL, other) def __ne__(self, other): - if isinstance(other, Vips.Image): - return self.relational(other, Vips.OperationRelational.NOTEQ) - elif isinstance(other, list): - return self.relational_const(other, Vips.OperationRelational.NOTEQ) - elif isinstance(other, numbers.Number): - return self.relational_const(other, Vips.OperationRelational.NOTEQ) - else: - return False + # _eq version allows comparison to None + return _call_enum_eq(self, + "relational", Vips.OperationRelational.NOTEQ, other) def __getitem__(self, arg): if isinstance(arg, slice): diff --git a/whatsnew-8.5.md b/whatsnew-8.5.md new file mode 100644 index 00000000..79bdbbc0 --- /dev/null +++ b/whatsnew-8.5.md @@ -0,0 +1,97 @@ +This branch has a new implementation of sequential mode: + +https://github.com/jcupitt/libvips/tree/remove-seq-stalling + +It'd be great to get this merged to master for 8.5, but it needs some testing. + +How seq used to work: + +* The vips sink functions create a set of N threads and scan images +top-to-bottom in tiles, allocating tiles to workers as they finish. + +* They have extra logic to keep workers together. They track the position +of the most-delayed worker and if the lead thread gets more than M scanlines +ahead, it stalls until the stragglers catch up. + +* There is more logic in the loaders: they keep track of the current +Y position, and if the lead request thread gets ahead of the current +read point, it stalls with a 60s timeout until the intermediate tiles are +requested. This logic is implemented in the `vips_sequential()` operation. + +The point of trying to keep thread locality and ordering is that we want +to limit the number of scanlines that loaders have to keep behind the read +point. We want to stream images through memory, not be forced into a load / +process / save model. + +This works reasonably well for simple cases, like thumbnailing single images, +but can fail in more complex cases, such as repeated `vips_insert()`. Consider +this Python program: + +```python +#!/usr/bin/python + +import sys import random + +import gi gi.require_version('Vips', '8.0') from gi.repository import Vips + +composite = Vips.Image.black(100000, 100000) + +for filename in sys.argv[2:]: + tile = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL) + x = random.randint(0, composite.width - tile.width) y = random.randint(0, + composite.height - tile.height) composite = composite.insert(tile, x, y) + +composite.write_to_file(sys.argv[1]) +``` + +This makes a 100,000 x 100,000 pixel black image, then inserts a lot of +other files into it and writes the result. + +With vips8.4, this could very easily fail. Imagine this situation: + +* image1 is very tall and thin + +* image2 is short and fat, and by chance covers the centre of image1 + +* we'll write the top part of image1, then write the body of image2 + +* after image2 has been written, we need to write the bottom of image1, +so a thread will ask for a set of pixels near the end of image1 + +* image1 knows that the previous request was for some scanlines near the top, +so it thinks this request must be from a thread that has run way ahead of +the pack and stalls it + +And we have a deadlock. In fact, vips wouldn't deadlock, it would just +pause on a 60s timeout on each thread. Sad! + +Here's how the new seq works: + +* Sinks work as before. + +* Loaders use a revised `vips_sequential()` with the stalling logic +removed. All it does now is track the read position, cache a few 100 lines +behind the read point, and makes sure that lines are evaluated in order +with no missing areas. + +* Operations like `vips_shrinkv()` which can cause large non-local references +have an extra bit of code which, if the input comes from a sequential source, +adds a an extra `vips_sequential()` operator on the output. This forces +`vips_shrinkv()` input to be sequential. + +The old one constrained thread location on output, and on input as well. The +new idea is to get rid of input constraints, and instead add extra code +to the operations which could trigger large non-local references. Rather +than tying threads down to stop them drifting apart, it makes sure they +can never get too far apart in the first place. + +Running the test program with git master gives this result: + +``` +real 1m2.317s +user 2m58.472s +sys 0m7.568s +peak mem: 10gb +``` + +Not bad!