diff --git a/ChangeLog b/ChangeLog index 2419c38a..3417db6c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,11 @@ 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 +- 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/TODO b/TODO index 68d0d9be..e4e24aca 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,3 @@ -- C++/Python need an im_affinei_all, perhaps with a char* for the - interpolator? - - 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/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/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. 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/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/libvips/include/vips/object.h b/libvips/include/vips/object.h index b916161f..06a89944 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. * @@ -65,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, @@ -73,7 +79,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) ) { 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/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 ) { 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(). */