From 3276c636f7ff76132c8bc4ae2203bc60aecdfdf7 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 6 Aug 2012 16:06:17 +0100 Subject: [PATCH 1/5] add support for VipsInterpolate to the C++ API quick and ugly hack, this will be replaced in vips8 necessary to get affinei and affinei_all in Python --- TODO | 2 ++ libvips/deprecated/dispatch_types.c | 8 +++++--- libvips/include/vips/internal.h | 2 ++ libvipsCC/VImage.cc | 2 ++ tools/vips.c | 12 ++++++++++-- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 68d0d9be..d1ec1ca6 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,8 @@ - C++/Python need an im_affinei_all, perhaps with a char* for the interpolator? + test new affinei C++ stuff, esp freeing + blocking bugs ============= diff --git a/libvips/deprecated/dispatch_types.c b/libvips/deprecated/dispatch_types.c index de103d7a..9ff4f932 100644 --- a/libvips/deprecated/dispatch_types.c +++ b/libvips/deprecated/dispatch_types.c @@ -870,9 +870,11 @@ im_type_desc im__output_gvalue = { }; /* Init function for input interpolate. + * + * This is used as a helper function by the C++ interface, so amke it public. */ -static int -input_interpolate_init( im_object *obj, char *str ) +int +vips__input_interpolate_init( im_object *obj, char *str ) { GType type = g_type_from_name( "VipsInterpolate" ); VipsObjectClass *class = VIPS_OBJECT_CLASS( g_type_class_ref( type ) ); @@ -903,7 +905,7 @@ im_type_desc im__input_interpolate = { IM_TYPE_INTERPOLATE, 0, /* No storage required */ IM_TYPE_ARG, /* It requires a command-line arg */ - input_interpolate_init, /* Init function */ + vips__input_interpolate_init, /* Init function */ input_interpolate_dest /* Destroy function */ }; diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 00971e86..a5f4ae9a 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -304,6 +304,8 @@ guint64 vips__parse_size( const char *size_string ); IMAGE *vips__deprecated_open_read( const char *filename, gboolean sequential ); IMAGE *vips__deprecated_open_write( const char *filename ); +int vips__input_interpolate_init( im_object *obj, char *str ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvipsCC/VImage.cc b/libvipsCC/VImage.cc index dff543a4..c1ee9885 100644 --- a/libvipsCC/VImage.cc +++ b/libvipsCC/VImage.cc @@ -484,6 +484,8 @@ Vargv::~Vargv() io->vec = NULL; } } + else if( strcmp( ty->type, IM_TYPE_INTERPOLATE ) == 0 ) + g_object_unref( base[i] ); } } diff --git a/tools/vips.c b/tools/vips.c index 63be2fa2..afff7169 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -332,7 +332,8 @@ vips2cpp( im_type_desc *ty ) IM_TYPE_DISPLAY, IM_TYPE_IMAGEVEC, IM_TYPE_DOUBLEVEC, - IM_TYPE_INTVEC + IM_TYPE_INTVEC, + IM_TYPE_INTERPOLATE }; /* Corresponding C++ types. @@ -348,7 +349,8 @@ vips2cpp( im_type_desc *ty ) "VDisplay", "std::vector", "std::vector", - "std::vector" + "std::vector", + "char*" }; for( k = 0; k < IM_NUMBER( vtypes ); k++ ) @@ -771,6 +773,12 @@ print_cppdef( im_function *fn ) else if( strcmp( ty->type, IM_TYPE_INTVEC ) == 0 ) print_invec( j, fn->argv[j].name, "im_intvec_object", "int", "" ); + else if( strcmp( ty->type, IM_TYPE_INTERPOLATE ) == 0 ) { + printf( "\tif( vips__input_interpolate_init( " + "&_vec.data(%d), %s ) )\n", + j, fn->argv[j].name ); + printf( "\t\tverror();\n" ); + } else /* Just use vips2cpp(). */ From 4cb63cf1ba96bf0591d8e5b6bb237493d61c0c1c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 6 Aug 2012 22:02:34 +0100 Subject: [PATCH 2/5] update the C++ binding and the Python one --- ChangeLog | 5 ++ TODO | 6 -- libvipsCC/include/vips/vipsc++.h | 39 +++++---- libvipsCC/vipsc++.cc | 138 +++++++++++++++++++++++-------- 4 files changed, 131 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0ce0a55..447c3333 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ 6/8/12 started 7.30.1 +- fixes to dzsave: shrink down to a 1x1 pixel tile, round image size up on + shrink, write a .dzi file with the pyramid params, default tile size and + overlap now matches the openslide writer +- wrap VipsInterpolate for C++ +- so affinei and affinei_all appear in Python 20/7/12 started 7.30.0 - support "rs" mode in vips7 diff --git a/TODO b/TODO index d1ec1ca6..e4e24aca 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,3 @@ -- C++/Python need an im_affinei_all, perhaps with a char* for the - interpolator? - - test new affinei C++ stuff, esp freeing - - blocking bugs ============= diff --git a/libvipsCC/include/vips/vipsc++.h b/libvipsCC/include/vips/vipsc++.h index 49e7008f..070c40e0 100644 --- a/libvipsCC/include/vips/vipsc++.h +++ b/libvipsCC/include/vips/vipsc++.h @@ -1,13 +1,14 @@ // headers for package arithmetic // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage abs() throw( VError ); VImage acos() throw( VError ); VImage add( VImage add_in2 ) throw( VError ); VImage asin() throw( VError ); VImage atan() throw( VError ); double avg() throw( VError ); +double point( char* point_interpolate, double point_x, double point_y, int point_band ) throw( VError ); double point_bilinear( double point_bilinear_x, double point_bilinear_y, int point_bilinear_band ) throw( VError ); VImage bandmean() throw( VError ); VImage ceil() throw( VError ); @@ -48,13 +49,13 @@ VImage tan() throw( VError ); // headers for package cimg // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage greyc( int greyc_iterations, double greyc_amplitude, double greyc_sharpness, double greyc_anisotropy, double greyc_alpha, double greyc_sigma, double greyc_dl, double greyc_da, double greyc_gauss_prec, int greyc_interpolation, int greyc_fast_approx ) throw( VError ); VImage greyc_mask( VImage greyc_mask_mask, int greyc_mask_iterations, double greyc_mask_amplitude, double greyc_mask_sharpness, double greyc_mask_anisotropy, double greyc_mask_alpha, double greyc_mask_sigma, double greyc_mask_dl, double greyc_mask_da, double greyc_mask_gauss_prec, int greyc_mask_interpolation, int greyc_mask_fast_approx ) throw( VError ); // headers for package colour // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage LCh2Lab() throw( VError ); VImage LCh2UCS() throw( VError ); VImage Lab2LCh() throw( VError ); @@ -89,7 +90,6 @@ VImage dE_fromdisp( VImage dE_fromdisp_in2, VDisplay dE_fromdisp_disp ) throw( V VImage disp2Lab( VDisplay disp2Lab_disp ) throw( VError ); VImage disp2XYZ( VDisplay disp2XYZ_disp ) throw( VError ); VImage float2rad() throw( VError ); -VImage argb2rgba() throw( VError ); VImage icc_ac2rc( char* icc_ac2rc_profile ) throw( VError ); VImage icc_export_depth( int icc_export_depth_depth, char* icc_export_depth_output_profile, int icc_export_depth_intent ) throw( VError ); VImage icc_import( char* icc_import_input_profile, int icc_import_intent ) throw( VError ); @@ -101,7 +101,7 @@ VImage sRGB2XYZ() throw( VError ); // headers for package conversion // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 static VImage gaussnoise( int gaussnoise_xsize, int gaussnoise_ysize, double gaussnoise_mean, double gaussnoise_sigma ) throw( VError ); VImage bandjoin( VImage bandjoin_in2 ) throw( VError ); static VImage black( int black_x_size, int black_y_size, int black_bands ) throw( VError ); @@ -149,7 +149,7 @@ VImage zoom( int zoom_xfac, int zoom_yfac ) throw( VError ); // headers for package convolution // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage aconvsep( VDMask aconvsep_matrix, int aconvsep_n_layers ) throw( VError ); VImage aconv( VDMask aconv_matrix, int aconv_n_layers, int aconv_cluster ) throw( VError ); VImage addgnoise( double addgnoise_sigma ) throw( VError ); @@ -170,7 +170,8 @@ VImage spcor( VImage spcor_in2 ) throw( VError ); // headers for package deprecated // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 +VImage argb2rgba() throw( VError ); VImage flood_copy( int flood_copy_start_x, int flood_copy_start_y, std::vector flood_copy_ink ) throw( VError ); VImage flood_blob_copy( int flood_blob_copy_start_x, int flood_blob_copy_start_y, std::vector flood_blob_copy_ink ) throw( VError ); VImage flood_other_copy( VImage flood_other_copy_mark, int flood_other_copy_start_x, int flood_other_copy_start_y, int flood_other_copy_serial ) throw( VError ); @@ -255,7 +256,7 @@ VImage notequal( double notequal_c ) throw( VError ); // headers for package format // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 static VImage csv2vips( char* csv2vips_filename ) throw( VError ); static VImage fits2vips( char* fits2vips_in ) throw( VError ); static VImage jpeg2vips( char* jpeg2vips_in ) throw( VError ); @@ -274,7 +275,7 @@ void vips2tiff( char* vips2tiff_out ) throw( VError ); // headers for package freq_filt // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 static VImage create_fmask( int create_fmask_width, int create_fmask_height, int create_fmask_type, double create_fmask_p1, double create_fmask_p2, double create_fmask_p3, double create_fmask_p4, double create_fmask_p5 ) throw( VError ); VImage disp_ps() throw( VError ); VImage flt_image_freq( int flt_image_freq_type, double flt_image_freq_p1, double flt_image_freq_p2, double flt_image_freq_p3, double flt_image_freq_p4, double flt_image_freq_p5 ) throw( VError ); @@ -288,7 +289,7 @@ VImage invfftr() throw( VError ); // headers for package histograms_lut // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage gammacorrect( double gammacorrect_exponent ) throw( VError ); VImage heq( int heq_band_number ) throw( VError ); VImage hist( int hist_band_number ) throw( VError ); @@ -318,7 +319,7 @@ VImage tone_map( VImage tone_map_lut ) throw( VError ); // headers for package inplace // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 void draw_circle( int draw_circle_cx, int draw_circle_cy, int draw_circle_radius, int draw_circle_fill, std::vector draw_circle_ink ) throw( VError ); void draw_rect( int draw_rect_left, int draw_rect_top, int draw_rect_width, int draw_rect_height, int draw_rect_fill, std::vector draw_rect_ink ) throw( VError ); void draw_line( int draw_line_x1, int draw_line_y1, int draw_line_x2, int draw_line_y2, std::vector draw_line_ink ) throw( VError ); @@ -333,7 +334,7 @@ VImage line( VImage line_mask, VImage line_ink, std::vector line_x1, std::v // headers for package iofuncs // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 static VImage binfile( char* binfile_filename, int binfile_width, int binfile_height, int binfile_bands, int binfile_offset ) throw( VError ); VImage cache( int cache_tile_width, int cache_tile_height, int cache_max_tiles ) throw( VError ); char* getext() throw( VError ); @@ -346,11 +347,11 @@ void printdesc() throw( VError ); // headers for package mask // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // headers for package morphology // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 double cntlines( int cntlines_direction ) throw( VError ); VImage dilate( VIMask dilate_mask ) throw( VError ); VImage rank( int rank_xsize, int rank_ysize, int rank_n ) throw( VError ); @@ -363,7 +364,7 @@ VImage profile( int profile_direction ) throw( VError ); // headers for package mosaicing // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage align_bands() throw( VError ); double correl( VImage correl_sec, int correl_xref, int correl_yref, int correl_xsec, int correl_ysec, int correl_hwindowsize, int correl_hsearchsize, int& correl_x, int& correl_y ) throw( VError ); int _find_lroverlap( VImage _find_lroverlap_sec, int _find_lroverlap_bandno, int _find_lroverlap_xr, int _find_lroverlap_yr, int _find_lroverlap_xs, int _find_lroverlap_ys, int _find_lroverlap_halfcorrelation, int _find_lroverlap_halfarea, int& _find_lroverlap_dy0, double& _find_lroverlap_scale1, double& _find_lroverlap_angle1, double& _find_lroverlap_dx1, double& _find_lroverlap_dy1 ) throw( VError ); @@ -385,7 +386,7 @@ VImage tbmosaic1( VImage tbmosaic1_sec, int tbmosaic1_bandno, int tbmosaic1_xr1, // headers for package other // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage benchmark() throw( VError ); double benchmark2() throw( VError ); VImage benchmarkn( int benchmarkn_n ) throw( VError ); @@ -400,14 +401,16 @@ static VImage zone( int zone_size ) throw( VError ); // headers for package resample // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 VImage rightshift_size( int rightshift_size_xshift, int rightshift_size_yshift, int rightshift_size_band_fmt ) throw( VError ); VImage shrink( double shrink_xfac, double shrink_yfac ) throw( VError ); VImage stretch3( double stretch3_xdisp, double stretch3_ydisp ) throw( VError ); +VImage affinei( char* affinei_interpolate, double affinei_a, double affinei_b, double affinei_c, double affinei_d, double affinei_dx, double affinei_dy, int affinei_x, int affinei_y, int affinei_w, int affinei_h ) throw( VError ); +VImage affinei_all( char* affinei_all_interpolate, double affinei_all_a, double affinei_all_b, double affinei_all_c, double affinei_all_d, double affinei_all_dx, double affinei_all_dy ) throw( VError ); // headers for package video // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 static VImage video_test( int video_test_brightness, int video_test_error ) throw( VError ); static VImage video_v4l1( char* video_v4l1_device, int video_v4l1_channel, int video_v4l1_brightness, int video_v4l1_colour, int video_v4l1_contrast, int video_v4l1_hue, int video_v4l1_ngrabs ) throw( VError ); diff --git a/libvipsCC/vipsc++.cc b/libvipsCC/vipsc++.cc index 2d576042..ddea477e 100644 --- a/libvipsCC/vipsc++.cc +++ b/libvipsCC/vipsc++.cc @@ -1,7 +1,7 @@ // bodies for package arithmetic // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_abs: absolute value VImage VImage::abs() throw( VError ) { @@ -99,6 +99,26 @@ double VImage::avg() throw( VError ) return( value ); } +// im_point: interpolate value at single point +double VImage::point( char* interpolate, double x, double y, int band ) throw( VError ) +{ + VImage in = *this; + double out; + + Vargv _vec( "im_point" ); + + _vec.data(0) = in.image(); + if( vips__input_interpolate_init( &_vec.data(1), interpolate ) ) + verror(); + *((double*) _vec.data(2)) = x; + *((double*) _vec.data(3)) = y; + *((int*) _vec.data(4)) = band; + _vec.call(); + out = *((double*)_vec.data(5)); + + return( out ); +} + // im_point_bilinear: interpolate value at single point, linearly double VImage::point_bilinear( double x, double y, int band ) throw( VError ) { @@ -741,7 +761,7 @@ VImage VImage::tan() throw( VError ) // bodies for package cimg // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_greyc: noise-removing filter VImage VImage::greyc( int iterations, double amplitude, double sharpness, double anisotropy, double alpha, double sigma, double dl, double da, double gauss_prec, int interpolation, int fast_approx ) throw( VError ) { @@ -801,7 +821,7 @@ VImage VImage::greyc_mask( VImage mask, int iterations, double amplitude, double // bodies for package colour // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_LCh2Lab: convert LCh to Lab VImage VImage::LCh2Lab() throw( VError ) { @@ -1371,22 +1391,6 @@ VImage VImage::float2rad() throw( VError ) return( out ); } -// im_argb2rgba: convert pre-multipled argb to png-style rgba -VImage VImage::argb2rgba() throw( VError ) -{ - VImage in = *this; - VImage out; - - Vargv _vec( "im_argb2rgba" ); - - _vec.data(0) = in.image(); - _vec.data(1) = out.image(); - _vec.call(); - out._ref->addref( in._ref ); - - return( out ); -} - // im_icc_ac2rc: convert LAB from AC to RC using an ICC profile VImage VImage::icc_ac2rc( char* profile ) throw( VError ) { @@ -1533,7 +1537,7 @@ VImage VImage::sRGB2XYZ() throw( VError ) // bodies for package conversion // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_gaussnoise: generate image of gaussian noise with specified statistics VImage VImage::gaussnoise( int xsize, int ysize, double mean, double sigma ) throw( VError ) { @@ -2317,7 +2321,7 @@ VImage VImage::zoom( int xfac, int yfac ) throw( VError ) // bodies for package convolution // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_aconvsep: approximate separable convolution VImage VImage::aconvsep( VDMask matrix, int n_layers ) throw( VError ) { @@ -2620,7 +2624,23 @@ VImage VImage::spcor( VImage in2 ) throw( VError ) // bodies for package deprecated // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 +// im_argb2rgba: convert pre-multipled argb to png-style rgba +VImage VImage::argb2rgba() throw( VError ) +{ + VImage in = *this; + VImage out; + + Vargv _vec( "im_argb2rgba" ); + + _vec.data(0) = in.image(); + _vec.data(1) = out.image(); + _vec.call(); + out._ref->addref( in._ref ); + + return( out ); +} + // im_flood_copy: flood with ink from start_x, start_y while pixel == start pixel VImage VImage::flood_copy( int start_x, int start_y, std::vector ink ) throw( VError ) { @@ -4078,7 +4098,7 @@ VImage VImage::notequal( double c ) throw( VError ) // bodies for package format // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_csv2vips: read a file in csv format VImage VImage::csv2vips( char* filename ) throw( VError ) { @@ -4274,7 +4294,7 @@ void VImage::vips2tiff( char* out ) throw( VError ) // bodies for package freq_filt // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_create_fmask: create frequency domain filter mask VImage VImage::create_fmask( int width, int height, int type, double p1, double p2, double p3, double p4, double p5 ) throw( VError ) { @@ -4442,7 +4462,7 @@ VImage VImage::invfftr() throw( VError ) // bodies for package histograms_lut // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_gammacorrect: gamma-correct image VImage VImage::gammacorrect( double exponent ) throw( VError ) { @@ -4889,7 +4909,7 @@ VImage VImage::tone_map( VImage lut ) throw( VError ) // bodies for package inplace // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_draw_circle: draw circle on image void VImage::draw_circle( int cx, int cy, int radius, int fill, std::vector ink ) throw( VError ) { @@ -5087,7 +5107,7 @@ VImage VImage::line( VImage mask, VImage ink, std::vector x1, std::vectoraddref( in._ref ); + + return( out ); +} + +// im_affinei_all: affine transform of whole image +VImage VImage::affinei_all( char* interpolate, double a, double b, double c, double d, double dx, double dy ) throw( VError ) +{ + VImage in = *this; + VImage out; + + Vargv _vec( "im_affinei_all" ); + + _vec.data(0) = in.image(); + _vec.data(1) = out.image(); + if( vips__input_interpolate_init( &_vec.data(2), interpolate ) ) + verror(); + *((double*) _vec.data(3)) = a; + *((double*) _vec.data(4)) = b; + *((double*) _vec.data(5)) = c; + *((double*) _vec.data(6)) = d; + *((double*) _vec.data(7)) = dx; + *((double*) _vec.data(8)) = dy; + _vec.call(); + out._ref->addref( in._ref ); + + return( out ); +} + // bodies for package video // this file automatically generated from -// VIPS library 7.28.0-Tue Jan 31 10:51:45 GMT 2012 +// VIPS library 7.30.1-Mon Aug 6 21:21:06 BST 2012 // im_video_test: test video grabber VImage VImage::video_test( int brightness, int error ) throw( VError ) { From a9c7a3667015610ed9197e80969dd4ba81638270 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 7 Aug 2012 12:17:25 +0100 Subject: [PATCH 3/5] be more cautious enabling tiff ycbcr we were turning on ycbcr for all jpeg tiffs and relying on the jpeg compressor to only use it when possible ... now just turn on ycbcr for 8-bit RGB images --- ChangeLog | 1 + libvips/foreign/vips2tiff.c | 44 +++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 447c3333..4e05a2e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ overlap now matches the openslide writer - wrap VipsInterpolate for C++ - so affinei and affinei_all appear in Python +- be more cautious enabling YCbCr mode in tiff write 20/7/12 started 7.30.0 - support "rs" mode in vips7 diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 55d17e7b..d383412e 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -131,6 +131,8 @@ * 2/6/12 * - copy jpeg pyramid in gather in RGB mode ... tiff4 doesn't do ycbcr * mode + * 7/8/12 + * - be more cautious enabling YCbCr mode */ /* @@ -458,15 +460,9 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) TIFFSetField( tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT ); TIFFSetField( tif, TIFFTAG_COMPRESSION, tw->compression ); - if( tw->compression == COMPRESSION_JPEG ) { + if( tw->compression == COMPRESSION_JPEG ) TIFFSetField( tif, TIFFTAG_JPEGQUALITY, tw->jpqual ); - /* Enable rgb->ycbcr conversion in the jpeg write. See also - * the photometric selection below. - */ - TIFFSetField( tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); - } - if( tw->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE ) TIFFSetField( tif, TIFFTAG_PREDICTOR, tw->predictor ); @@ -515,6 +511,9 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) case 3: case 4: + /* could be: RGB, RGBA, CMYK, LAB, LABA, generic + * multi-band image. + */ if( tw->im->Type == VIPS_INTERPRETATION_LAB || tw->im->Type == VIPS_INTERPRETATION_LABS ) photometric = PHOTOMETRIC_CIELAB; @@ -524,12 +523,16 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) TIFFTAG_INKSET, INKSET_CMYK ); } else if( tw->compression == COMPRESSION_JPEG && - tw->im->Bands == 3 ) + tw->im->Bands == 3 && + tw->im->BandFmt == VIPS_FORMAT_UCHAR ) { /* This signals to libjpeg that it can do * YCbCr chrominance subsampling from RGB, not * that we will supply the image as YCbCr. */ photometric = PHOTOMETRIC_YCBCR; + TIFFSetField( tif, TIFFTAG_JPEGCOLORMODE, + JPEGCOLORMODE_RGB ); + } else photometric = PHOTOMETRIC_RGB; @@ -538,9 +541,12 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) v[0] = EXTRASAMPLE_ASSOCALPHA; TIFFSetField( tif, TIFFTAG_EXTRASAMPLES, 1, v ); } + break; case 5: + /* Only CMYKA + */ if( tw->im->Type == VIPS_INTERPRETATION_CMYK ) { photometric = PHOTOMETRIC_SEPARATED; TIFFSetField( tif, @@ -1358,16 +1364,22 @@ tiff_copy( TiffWrite *tw, TIFF *out, TIFF *in ) if( tw->compression == COMPRESSION_JPEG ) { TIFFSetField( out, TIFFTAG_JPEGQUALITY, tw->jpqual ); - /* Enable rgb->ycbcr conversion in the jpeg write. See also - * the photometric selection below. + /* Only for three-band, 8-bit images. */ - TIFFSetField( out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); + if( tw->im->Bands == 3 && + tw->im->BandFmt == VIPS_FORMAT_UCHAR ) { + /* Enable rgb->ycbcr conversion in the jpeg write. + */ + TIFFSetField( out, + TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); - /* And we want ycbcr expanded to rgb on read. Otherwise - * TIFFTileSize() will give us the size of a chrominance - * subsampled tile. - */ - TIFFSetField( in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); + /* And we want ycbcr expanded to rgb on read. Otherwise + * TIFFTileSize() will give us the size of a chrominance + * subsampled tile. + */ + TIFFSetField( in, + TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); + } } /* We can't copy profiles :( Set again from TiffWrite. From 0c35f461dc6f94c0f7aee375d844a6bdc8775001 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 7 Aug 2012 12:52:50 +0100 Subject: [PATCH 4/5] add "deprecated" flag to vips arguments deprecated arguments still work, but are not shown in help, nor are they checked for "have-been-set" you can tag required and optional args as deprecated ... obviously if you deprecate a required argument you must replace it with a new argument or scripts will break --- libvips/include/vips/object.h | 4 +++- libvips/iofuncs/enumtypes.c | 1 + libvips/iofuncs/object.c | 1 + libvips/iofuncs/operation.c | 15 +++++++++++---- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index b916161f..392a3f54 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -53,6 +53,7 @@ typedef struct _VipsObjectClass VipsObjectClass; * @VIPS_ARGUMENT_SET_ALWAYS: don't do use-before-set checks * @VIPS_ARGUMENT_INPUT: is an input argument (one we depend on) * @VIPS_ARGUMENT_OUTPUT: is an output argument (depends on us) + * @VIPS_ARGUMENT_DEPRECATED: just there for back-compat, hide * * Flags we associate with each object argument. * @@ -73,7 +74,8 @@ typedef enum /*< flags >*/ { VIPS_ARGUMENT_SET_ONCE = 4, VIPS_ARGUMENT_SET_ALWAYS = 8, VIPS_ARGUMENT_INPUT = 16, - VIPS_ARGUMENT_OUTPUT = 32 + VIPS_ARGUMENT_OUTPUT = 32, + VIPS_ARGUMENT_DEPRECATED = 64 } VipsArgumentFlags; /* Useful flag combinations. User-visible ones are: diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index 676d279b..aa2634d7 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -526,6 +526,7 @@ vips_argument_flags_get_type( void ) {VIPS_ARGUMENT_SET_ALWAYS, "VIPS_ARGUMENT_SET_ALWAYS", "set-always"}, {VIPS_ARGUMENT_INPUT, "VIPS_ARGUMENT_INPUT", "input"}, {VIPS_ARGUMENT_OUTPUT, "VIPS_ARGUMENT_OUTPUT", "output"}, + {VIPS_ARGUMENT_DEPRECATED, "VIPS_ARGUMENT_DEPRECATED", "deprecated"}, {0, NULL, NULL} }; diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 1c27fde7..a9693e14 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -144,6 +144,7 @@ vips_object_check_required( VipsObject *object, GParamSpec *pspec, if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) && (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + !(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) && (argument_class->flags & *iomask) && !argument_instance->assigned ) { vips_error( class->nickname, diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index f93cc4a9..1d75eedf 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -85,7 +85,8 @@ vips_operation_class_usage_arg( VipsObjectClass *object_class, */ if( usage->required == ((argument_class->flags & VIPS_ARGUMENT_REQUIRED) != 0) && - (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ) { + (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + !(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) { if( usage->message && usage->n == 0 ) vips_buf_appendf( buf, "%s\n", usage->message ); @@ -775,12 +776,16 @@ vips_call_options_add( VipsObject *object, entry[0].long_name = name; entry[0].short_name = name[0]; + entry[0].description = g_param_spec_get_blurb( pspec ); + entry[0].flags = 0; if( !needs_string ) entry[0].flags |= G_OPTION_FLAG_NO_ARG; + if( argument_class->flags & VIPS_ARGUMENT_DEPRECATED ) + entry[0].flags |= G_OPTION_FLAG_HIDDEN; + entry[0].arg = G_OPTION_ARG_CALLBACK; entry[0].arg_data = (gpointer) vips_call_options_set; - entry[0].description = g_param_spec_get_blurb( pspec ); if( needs_string ) entry[0].arg_description = g_type_name( G_PARAM_SPEC_VALUE_TYPE( pspec ) ); @@ -837,7 +842,8 @@ vips_call_argv_input( VipsObject *object, /* Loop over all required construct args. */ if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) && - (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ) { + (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + !(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) { const char *name = g_param_spec_get_name( pspec ); if( (argument_class->flags & VIPS_ARGUMENT_INPUT) ) { @@ -872,7 +878,8 @@ vips_call_argv_output( VipsObject *object, /* Loop over all required construct args. */ if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) && - (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ) { + (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + !(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) { if( (argument_class->flags & VIPS_ARGUMENT_INPUT) ) call->i += 1; else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) { From 8214d15982e6a1983e46d0415d622ce20efbe019 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 7 Aug 2012 13:29:03 +0100 Subject: [PATCH 5/5] more improvements to dzsave now writes x_files and x.dzi, as per spec (thanks Benjamin) deprecate tile_width and tile_height, just have tile_size now --- ChangeLog | 1 + libvips/foreign/dzsave.c | 140 +++++++++++++++++++++++---------- libvips/foreign/foreign.c | 43 ---------- libvips/include/vips/foreign.h | 3 + libvips/include/vips/object.h | 5 ++ 5 files changed, 109 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e05a2e8..42ca4b7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - wrap VipsInterpolate for C++ - so affinei and affinei_all appear in Python - be more cautious enabling YCbCr mode in tiff write +- add "DEPRECATED" flag to arguments 20/7/12 started 7.30.0 - support "rs" mode in vips7 diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index b4810747..45e0a22b 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -13,6 +13,10 @@ * - round image size up on shrink * - write a .dzi file with the pyramid params * - default tile size and overlap now matches the openslide writer + * 7/8/12 (thanks to Benjamin Gilbert again for more testing) + * - reorganise the directory structure + * - rename to basename and tile_size + * - deprecate tile_width/_height and dirname */ /* @@ -97,14 +101,13 @@ struct _Layer { struct _VipsForeignSaveDz { VipsForeignSave parent_object; - /* Directory to create and write to. + /* Name to write to. */ - char *dirname; + char *basename; char *suffix; int overlap; - int tile_width; - int tile_height; + int tile_size; Layer *layer; /* x2 shrink pyr layer */ }; @@ -188,14 +191,14 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, int width, int height ) * overlap, but the first row is missing the top edge. * * We add one so that we will have the extra scan line for the shrink - * in case tile_height is odd and there's no overlap. + * in case tile_size is odd and there's no overlap. */ layer->y = 0; layer->write_y = 0; strip.left = 0; strip.top = 0; strip.width = layer->image->Xsize; - strip.height = dz->tile_height + dz->overlap + 1; + strip.height = dz->tile_size + dz->overlap + 1; if( vips_region_buffer( layer->strip, &strip ) ) { layer_free( layer ); return( NULL ); @@ -224,15 +227,15 @@ pyramid_mkdir( VipsForeignSaveDz *dz ) { Layer *layer; - if( vips_existsf( "%s", dz->dirname ) ) { + if( vips_existsf( "%s_files", dz->basename ) ) { vips_error( "dzsave", - _( "Directory \"%s\" exists" ), dz->dirname ); + _( "Directory \"%s_files\" exists" ), dz->basename ); return( -1 ); } - if( vips_mkdirf( "%s", dz->dirname ) ) + if( vips_mkdirf( "%s_files", dz->basename ) ) return( -1 ); for( layer = dz->layer; layer; layer = layer->below ) - if( vips_mkdirf( "%s/%d", dz->dirname, layer->n ) ) + if( vips_mkdirf( "%s_files/%d", dz->basename, layer->n ) ) return( -1 ); return( 0 ); @@ -243,11 +246,8 @@ write_dzi( VipsForeignSaveDz *dz ) { FILE *fp; char buf[PATH_MAX]; - char *name; - name = g_path_get_basename( dz->dirname ); - vips_snprintf( buf, PATH_MAX, "%s/%s.dzi", dz->dirname, name ); - g_free( name ); + vips_snprintf( buf, PATH_MAX, "%s.dzi", dz->basename ); if( !(fp = vips__file_open_write( buf, TRUE )) ) return( -1 ); @@ -256,7 +256,7 @@ write_dzi( VipsForeignSaveDz *dz ) "xmlns=\"http://schemas.microsoft.com/deepzoom/2008\"\n" ); fprintf( fp, " Format=\"%s\"\n", dz->suffix + 1 ); fprintf( fp, " Overlap=\"%d\"\n", dz->overlap ); - fprintf( fp, " TileSize=\"%d\"\n", dz->tile_width ); + fprintf( fp, " TileSize=\"%d\"\n", dz->tile_size ); fprintf( fp, " >\n" ); fprintf( fp, " layer->height ); @@ -433,7 +433,7 @@ strip_init( Strip *strip, Layer *layer ) line.left = 0; line.top = layer->y - dz->overlap; line.width = image.width; - line.height = dz->tile_height + 2 * dz->overlap; + line.height = dz->tile_size + 2 * dz->overlap; vips_rect_intersectrect( &image, &line, &line ); @@ -464,14 +464,14 @@ strip_allocate( VipsThreadState *state, void *a, gboolean *stop ) */ state->pos.left = strip->x - dz->overlap; state->pos.top = 0; - state->pos.width = dz->tile_width + 2 * dz->overlap; + state->pos.width = dz->tile_size + 2 * dz->overlap; state->pos.height = state->im->Ysize; vips_rect_intersectrect( &image, &state->pos, &state->pos ); state->x = strip->x; state->y = layer->y; - strip->x += dz->tile_width; + strip->x += dz->tile_size; if( vips_rect_isempty( &state->pos ) ) { *stop = TRUE; @@ -499,10 +499,10 @@ strip_work( VipsThreadState *state, void *a ) state->pos.width, state->pos.height, NULL ) ) return( -1 ); - vips_buf_appendf( &buf, "%s/%d/%d_%d%s", - dz->dirname, layer->n, - state->x / dz->tile_width, - state->y / dz->tile_height, + vips_buf_appendf( &buf, "%s_files/%d/%d_%d%s", + dz->basename, layer->n, + state->x / dz->tile_size, + state->y / dz->tile_size, dz->suffix ); if( vips_image_write_to_file( extr, vips_buf_all( &buf ) ) ) { @@ -689,13 +689,13 @@ strip_arrived( Layer *layer ) /* Position our strip down the image. We add one to the strip height * to make sure we will have enough pixels for any shrinking even if - * tile_height is odd and there's no overlap. + * tile_size is odd and there's no overlap. */ - layer->y += dz->tile_height; + layer->y += dz->tile_size; new_strip.left = 0; new_strip.top = layer->y - dz->overlap; new_strip.width = layer->image->Xsize; - new_strip.height = dz->tile_height + 2 * dz->overlap + 1; + new_strip.height = dz->tile_size + 2 * dz->overlap + 1; /* What pixels that we will need do we already have? Save them in * overlap. @@ -782,8 +782,8 @@ vips_foreign_save_dz_build( VipsObject *object ) build( object ) ) return( -1 ); - if( dz->overlap >= dz->tile_width || - dz->overlap >= dz->tile_height ) { + if( dz->overlap >= dz->tile_size || + dz->overlap >= dz->tile_size ) { vips_error( "dzsave", "%s", _( "overlap must be less than tile " "width and height" ) ) ; @@ -847,11 +847,11 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class ) save_class->format_table = bandfmt_dz; save_class->coding[VIPS_CODING_LABQ] = TRUE; - VIPS_ARG_STRING( class, "dirname", 1, - _( "Directory name" ), - _( "Directory name to save to" ), + VIPS_ARG_STRING( class, "basename", 1, + _( "Base name" ), + _( "Base name to save to" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsForeignSaveDz, dirname ), + G_STRUCT_OFFSET( VipsForeignSaveDz, basename ), NULL ); VIPS_ARG_STRING( class, "suffix", 9, @@ -868,19 +868,36 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class ) G_STRUCT_OFFSET( VipsForeignSaveDz, overlap ), 0, 1024, 0 ); - VIPS_ARG_INT( class, "tile_width", 11, + VIPS_ARG_INT( class, "tile_size", 11, + _( "Tile size" ), + _( "Tile size in pixels" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignSaveDz, tile_size ), + 1, 1024, 256 ); + + /* How annoying. We stupidly had these in earlier versions. + */ + + VIPS_ARG_STRING( class, "dirname", 1, + _( "Base name" ), + _( "Base name to save to" ), + VIPS_ARGUMENT_REQUIRED_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET( VipsForeignSaveDz, basename ), + NULL ); + + VIPS_ARG_INT( class, "tile_width", 12, _( "Tile width" ), _( "Tile width in pixels" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsForeignSaveDz, tile_width ), - 1, 1024, 128 ); + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET( VipsForeignSaveDz, tile_size ), + 1, 1024, 256 ); VIPS_ARG_INT( class, "tile_height", 12, _( "Tile height" ), _( "Tile height in pixels" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsForeignSaveDz, tile_height ), - 1, 1024, 128 ); + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET( VipsForeignSaveDz, tile_size ), + 1, 1024, 256 ); } @@ -889,6 +906,49 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz ) { VIPS_SETSTR( dz->suffix, ".jpeg" ); dz->overlap = 1; - dz->tile_width = 256; - dz->tile_height = 256; + dz->tile_size = 256; } + +/** + * vips_dzsave: + * @in: image to save + * @basename: basename to save to + * @...: %NULL-terminated list of optional named arguments + * + * Optional arguments: + * + * @suffix: suffix for tile tiles (default ".jpg") + * @overlap; set tile overlap (default 1) + * @tile_size; set tile size (default 256) + * + * Save an image to a deep zoom - style directory tree. A directory called + * "@basename_files" is created to hold the tiles, and an XML file called + * "@basename.dzi" is written with the image metadata, + * + * The image is shrunk in a series of x2 reductions until it fits within a + * single pixel. Each layer is written out to a separate subdirectory of + * @dirname_files, with directory "0" holding the smallest, single pixel image. + * + * Each tile is written as a separate file named as "@x_@y@suffix", where @x + * and @y are the tile coordinates, with (0, 0) as the top-left tile. + * + * You can set @suffix to something like ".jpg[Q=85]" to set the tile write + * options. + * + * See also: vips_tiffsave(). + * + * Returns: 0 on success, -1 on error. + */ +int +vips_dzsave( VipsImage *in, const char *basename, ... ) +{ + va_list ap; + int result; + + va_start( ap, basename ); + result = vips_call_split( "dzsave", ap, in, basename ); + va_end( ap ); + + return( result ); +} + diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 36e0bba7..b3e0ce18 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -2382,46 +2382,3 @@ vips_matload( const char *filename, VipsImage **out, ... ) return( result ); } - -/** - * vips_dzsave: - * @in: image to save - * @dirname: directory to save to - * @...: %NULL-terminated list of optional named arguments - * - * Optional arguments: - * - * @suffix: suffix for tile tiles (default ".jpg") - * @overlap; set tile overlap - * @tile_width; set tile size - * @tile_height; set tile size - * - * Save an image to a deep zoom - style directory tree. - * - * The image is shrunk in a series of x2 reductions until it fits within a - * tile. Each layer is written out to a separate subdirectory of @dirname, - * with directory "0" holding the smallest, single tile image. - * - * Each tile is written as a separate file named as "@x_@y@suffix", where @x - * and @y are the tile coordinates, with (0, 0) as the top-left tile. - * - * You can set @suffix to something like ".jpg[Q=85]" to set the tile write - * options. - * - * See also: vips_tiffsave(). - * - * Returns: 0 on success, -1 on error. - */ -int -vips_dzsave( VipsImage *in, const char *dirname, ... ) -{ - va_list ap; - int result; - - va_start( ap, dirname ); - result = vips_call_split( "dzsave", ap, in, dirname ); - va_end( ap ); - - return( result ); -} - diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 09d27c6f..533456cc 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -424,6 +424,9 @@ int vips_radload( const char *filename, VipsImage **out, ... ) int vips_radsave( VipsImage *in, const char *filename, ... ) __attribute__((sentinel)); +int vips_dzsave( VipsImage *in, const char *basename, ... ) + __attribute__((sentinel)); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index 392a3f54..06a89944 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -66,6 +66,11 @@ typedef struct _VipsObjectClass VipsObjectClass; * example, VipsImage::width is a property that gives access to the Xsize * member of struct _VipsImage. We default its 'assigned' to TRUE * since the field is always set directly by C. + * + * @VIPS_ARGUMENT_DEPRECATED arguments are not shown in help text, are not + * looked for if required, are not checked for "have-been-set". You can + * deprecate a required argument, but you must obviously add a new required + * argument if you do. */ typedef enum /*< flags >*/ { VIPS_ARGUMENT_NONE = 0,