diff --git a/ChangeLog b/ChangeLog index 5224f5ab..4fe292b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,9 @@ 20/8/11 started 7.27.0 - version bump for new dev cycle - im_subtract(), im_avg(), im_min(), im_minpos(), im_copy(), im_embed(), - im_flophor(), im_flipver(), im_insert(), im_insert_noexpand() redone as - classes + im_flophor(), im_flipver(), im_insert(), im_insert_noexpand(), im_lrjoin(), + im_tbjoin() + redone as classes - added VIPS_ARGUMENT_APPEND to help control arg ordering - generate has a 'stop' param to signal successful early termination - added optional output args, eg. x/y for min diff --git a/TODO b/TODO index 61268245..7a7cd779 100644 --- a/TODO +++ b/TODO @@ -1,22 +1,19 @@ -- finish join.c +- do extract_area, needed by join +- note member free stuff in vipsobject docs -- lintra_vec next ... how should we do vips_lin() vs. vips_lin_vec()? do we - need two separate things? + should boxed get freed in finalise rather than dispose? - perhaps just have vips_lin() as a convenience function - - how about a "squash" param to VipsLin which clips the output type back to - the input type? maybe not a great idea - -- all things that use sizealike could take a --background param? or an - --extend param? maybe not a great idea (maybe handy for convolve affine etc. - though) +- vipsimage should be cached too, eg. + VipsImage *a = vips_image_new_from_file( "poop.jpg" ); + can be reused +- we should cache on "written" ... we should emit written for all objects, and + there should be a a vipsarg flag to block updates after written - the lifetime of an object is @@ -48,14 +45,17 @@ -vips im_copy_set /home/john/GIT/nip2/test/tmp/t1.v - /home/john/GIT/nip2/test/tmp/cmyk.v 15 1 1 0 0 +- lintra_vec next ... how should we do vips_lin() vs. vips_lin_vec()? do we + need two separate things? - VIPS-WARNING **: object.c:775: VipsImage can only assign 'xoffset' once + perhaps just have vips_lin() as a convenience function + how about a "squash" param to VipsLin which clips the output type back to + the input type? maybe not a great idea -HH - +- all things that use sizealike could take a --background param? or an + --extend param? maybe not a great idea (maybe handy for convolve affine etc. + though) diff --git a/libvips/conversion/Makefile.am b/libvips/conversion/Makefile.am index e9d4bada..02314a01 100644 --- a/libvips/conversion/Makefile.am +++ b/libvips/conversion/Makefile.am @@ -7,6 +7,7 @@ libconversion_la_SOURCES = \ embed.c \ flip.c \ insert.c \ + join.c \ conver_dispatch.c \ im_black.c \ im_c2amph.c \ @@ -19,7 +20,6 @@ libconversion_la_SOURCES = \ im_falsecolour.c \ im_gbandjoin.c \ im_insert.c \ - im_lrjoin.c \ im_mask2vips.c \ im_msb.c \ im_replicate.c \ @@ -33,7 +33,6 @@ libconversion_la_SOURCES = \ im_subsample.c \ im_system.c \ im_system_image.c \ - im_tbjoin.c \ im_text.c \ im_gaussnoise.c \ im_vips2mask.c \ diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index 8f509354..90fd17e9 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -106,10 +106,12 @@ vips_conversion_operation_init( void ) extern GType vips_embed_get_type( void ); extern GType vips_flip_get_type( void ); extern GType vips_insert_get_type( void ); + extern GType vips_join_get_type( void ); vips_copy_get_type(); vips_embed_get_type(); vips_flip_get_type(); vips_insert_get_type(); + vips_join_get_type(); } diff --git a/libvips/conversion/im_lrjoin.c b/libvips/conversion/im_lrjoin.c deleted file mode 100644 index 0b2b4546..00000000 --- a/libvips/conversion/im_lrjoin.c +++ /dev/null @@ -1,100 +0,0 @@ -/* im_lrjoin - * - * Copyright 1990, 1991: Kirk Martinez, N. Dessipris - * Author: Kirk Martinez, N. Dessipris - * Written on: 9/6/90 - * Modified on: 17/04/1991 - * 31/8/93 JC - * - args to memcpy() were reversed - * 14/11/94 JC - * - tided up and ANSIfied - * - now accepts IM_CODING_LABQ - * - memory leaks removed - * - bug in calculation of output Xsize removed (thanks Thomson!) - * - bug in checking of image compatibility fixed - * 23/10/95 JC - * - rewritten in terms of im_insert() - * 14/4/04 - * - sets Xoffset / Yoffset - * 1/2/10 - * - gtkdoc - * - cleanups - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include - -#include - - -/** - * im_lrjoin: - * @left: image to go on left - * @right: image to go on right - * @out: output image - * - * Join @left and @right together, left-right. If one is taller than the - * other, @out will be has high as the smaller. - * - * If the number of bands differs, one of the images - * must have one band. In this case, an n-band image is formed from the - * one-band image by joining n copies of the one-band image together, and then - * the two n-band images are operated upon. - * - * The two input images are cast up to the smallest common type (see table - * Smallest common format in - * arithmetic). - * - * See also: im_insert(), im_tbjoin(). - * - * Returns: 0 on success, -1 on error - */ -int -im_lrjoin( IMAGE *left, IMAGE *right, IMAGE *out ) -{ - IMAGE *t1; - - /* Paste right and left together, trim the bottom edge. - */ - if( !(t1 = im_open_local( out, "im_lrjoin:1", "p" )) || - im_insert( left, right, t1, left->Xsize, 0 ) || - im_extract_area( t1, out, - 0, 0, t1->Xsize, IM_MIN( left->Ysize, right->Ysize ) ) ) - return( -1 ); - - out->Xoffset = left->Xsize; - out->Yoffset = 0; - - return( 0 ); -} diff --git a/libvips/conversion/im_tbjoin.c b/libvips/conversion/im_tbjoin.c deleted file mode 100644 index 30d708ca..00000000 --- a/libvips/conversion/im_tbjoin.c +++ /dev/null @@ -1,99 +0,0 @@ -/* im_tbjoin - * - * Copyright: 1990, 1991 Kirk Martinez, N. Dessipris - * Author: Kirk Martinez, N. Dessipris - * Written on: 9/6/90 - * Updated: 15/03/1991, N. Dessipris - * 31/8/93 JC - * - externs removed - * 14/11/94 JC - * - tidied up - * - now works for IM_CODING_LABQ too - * - image compatibility bug fixed - * 28/4/95 JC - * - y arg to 2nd set of im_writeline()s was wrong - * 23/10/95 JC - * - rewritten in terms of im_insert() - * 14/4/04 - * - sets Xoffset / Yoffset - * 1/2/10 - * - gtkdoc - * - cleanups - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include - -#include - -/** - * im_tbjoin: - * @top: image to go on top - * @bottom: image to go on bottom - * @out: output image - * - * Join @top and @bottom together, up-down. If one is wider than the - * other, @out will be has wide as the smaller. - * - * If the number of bands differs, one of the images - * must have one band. In this case, an n-band image is formed from the - * one-band image by joining n copies of the one-band image together, and then - * the two n-band images are operated upon. - * - * The two input images are cast up to the smallest common type (see table - * Smallest common format in - * arithmetic). - * - * See also: im_insert(), im_tbjoin(). - * - * Returns: 0 on success, -1 on error - */ -int -im_tbjoin( IMAGE *top, IMAGE *bottom, IMAGE *out ) -{ - IMAGE *t1; - - /* Paste top and bottom together, cut off any leftovers. - */ - if( !(t1 = im_open_local( out, "im_tbjoin:1", "p" )) || - im_insert( top, bottom, t1, 0, top->Ysize ) || - im_extract_area( t1, out, - 0, 0, IM_MIN( top->Xsize, bottom->Xsize ), t1->Ysize ) ) - return( -1 ); - - out->Xoffset = 0; - out->Yoffset = top->Ysize; - - return( 0 ); -} diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index 537e2d06..f0c9e1f1 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -267,11 +267,6 @@ vips__vector_to_ink( const char *domain, VipsImage *im, double *vec, int n ) return( (PEL *) t[2]->data ); } -/* xy range we sanity check on ... just to stop crazy numbers from 1/0 etc. - * causing g_assert() failures later. - */ -#define RANGE (100000000) - static int vips_insert_build( VipsObject *object ) { @@ -281,14 +276,6 @@ vips_insert_build( VipsObject *object ) VipsImage *t[4]; VipsImage **arry; - /* Check args. - */ - if( insert->x > RANGE || insert->x < -RANGE || - insert->y > RANGE || insert->y < -RANGE ) { - vips_error( "VipsInsert", "%s", _( "xy out of range" ) ); - return( -1 ); - } - if( VIPS_OBJECT_CLASS( vips_insert_parent_class )->build( object ) ) return( -1 ); @@ -366,6 +353,11 @@ vips_insert_build( VipsObject *object ) return( 0 ); } +/* xy range we sanity check on ... just to stop crazy numbers from 1/0 etc. + * causing g_assert() failures later. + */ +#define RANGE (100000000) + static void vips_insert_class_init( VipsInsertClass *class ) { @@ -398,14 +390,14 @@ vips_insert_class_init( VipsInsertClass *class ) _( "Left edge of sub in main" ), VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsInsert, x ), - 0, 1000000, 0 ); + -RANGE, RANGE, 0 ); VIPS_ARG_INT( class, "y", 3, _( "Y" ), _( "Top edge of sub in main" ), VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsInsert, y ), - 0, 1000000, 0 ); + -RANGE, RANGE, 0 ); VIPS_ARG_BOOL( class, "expand", 4, _( "Expand" ), diff --git a/libvips/conversion/join.c b/libvips/conversion/join.c index ad20de27..af39a3d6 100644 --- a/libvips/conversion/join.c +++ b/libvips/conversion/join.c @@ -72,16 +72,28 @@ * VipsJoin: * @in1: first input image * @in2: second input image - * @out: output image + * @output: output image * @direction: join horizontally or vertically - * @expand: TRUE to expand the output image to hold all of the input pixels + * @expand: %TRUE to expand the output image to hold all of the input pixels * @shim: space between images, in pixels * @background: background ink colour * @align: low, centre or high alignment * - * Join @left and @right together, left-right. If one is taller than the - * other, @out will be has high as the smaller. + * Join @in1 and @in2 together, left-right or up-down depending on the value + * of @direction. * + * If one is taller or wider than the + * other, @output will be has high as the smaller. If @expand is %TRUE, then + * the output will be expanded to contain all of the input pixels. + * + * Use @align to set the edge that the images align on. By default, they align + * on the edge with the lower value coordinate. + * + * Use @background to set the colour of any pixels in @output which are not + * present in either @in1 or @in2. + * + * Use @shim to set the spacing between the images. By default this is 0. + * * If the number of bands differs, one of the images * must have one band. In this case, an n-band image is formed from the * one-band image by joining n copies of the one-band image together, and then @@ -101,8 +113,8 @@ typedef struct _VipsJoin { /* Params. */ - VipsImage *main; - VipsImage *sub; + VipsImage *in1; + VipsImage *in2; VipsDirection direction; gboolean expand; int shim; @@ -119,14 +131,16 @@ vips_join_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsJoin *join = (VipsJoin *) object; + int x, y; + VipsImage *t; if( VIPS_OBJECT_CLASS( vips_join_parent_class )->build( object ) ) return( -1 ); switch( join->direction ) { case VIPS_DIRECTION_HORIZONTAL: - x = join->main->Xsize + join->shim; + x = join->in1->Xsize + join->shim; switch( join->align ) { case VIPS_ALIGN_LOW: @@ -134,21 +148,90 @@ vips_join_build( VipsObject *object ) break; case VIPS_ALIGN_CENTRE: - mx = VIPS_MAX( join->main->Ysize, join->sub->Ysize ); - y = + y = join->in1->Ysize / 2 - join->in2->Ysize / 2; break; case VIPS_ALIGN_HIGH: - y = 0; + y = join->in1->Ysize - join->in2->Ysize; break; + default: + g_assert( 0 ); + } + + break; case VIPS_DIRECTION_VERTICAL: + y = join->in1->Ysize + join->shim; + + switch( join->align ) { + case VIPS_ALIGN_LOW: + x = 0; + break; + + case VIPS_ALIGN_CENTRE: + x = join->in1->Xsize / 2 - join->in2->Xsize / 2; + break; + + case VIPS_ALIGN_HIGH: + x = join->in1->Xsize - join->in2->Xsize; + break; + + default: + g_assert( 0 ); + } + + break; default: - g_asert( 0 ); + g_assert( 0 ); } - + + if( vips_insert( join->in1, join->in2, &t, x, y, + "expand", TRUE, + "background", join->background, + NULL ) ) + return( -1 ); + + if( !join->expand ) { + VipsImage *t2; + int left, top, width, height; + + switch( join->direction ) { + case VIPS_DIRECTION_HORIZONTAL: + left = 0; + top = VIPS_MAX( 0, y ) - y; + width = t->Xsize; + height = VIPS_MIN( join->in1->Ysize, join->in2->Ysize ); + break; + + case VIPS_DIRECTION_VERTICAL: + left = VIPS_MAX( 0, x ) - x; + top = 0; + width = VIPS_MIN( join->in1->Xsize, join->in2->Xsize ); + height = t->Ysize; + break; + + default: + g_assert( 0 ); + } + + if( vips_call( "extract_area", t, &t2, + left, top, width, height, NULL ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + t = t2; + } + + + if( vips_image_write( t, conversion->output ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); return( 0 ); } @@ -168,17 +251,17 @@ vips_join_class_init( VipsJoinClass *class ) vobject_class->description = _( "join an image" ); vobject_class->build = vips_join_build; - VIPS_ARG_IMAGE( class, "main", -1, - _( "Main" ), - _( "Main input image" ), + VIPS_ARG_IMAGE( class, "in1", -1, + _( "in1" ), + _( "First input image" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsJoin, main ) ); + G_STRUCT_OFFSET( VipsJoin, in1 ) ); - VIPS_ARG_IMAGE( class, "sub", 0, - _( "Sub-image" ), - _( "Sub-image to join into main image" ), + VIPS_ARG_IMAGE( class, "in2", 0, + _( "in2" ), + _( "Second input image" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsJoin, sub ) ); + G_STRUCT_OFFSET( VipsJoin, in2 ) ); VIPS_ARG_ENUM( class, "direction", 2, _( "direction" ), @@ -198,7 +281,7 @@ vips_join_class_init( VipsJoinClass *class ) _( "Shim" ), _( "Pixels between images" ), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsInsert, shim ), + G_STRUCT_OFFSET( VipsJoin, shim ), 0, 1000000, 0 ); VIPS_ARG_BOXED( class, "background", 6, @@ -211,7 +294,7 @@ vips_join_class_init( VipsJoinClass *class ) VIPS_ARG_ENUM( class, "align", 2, _( "Align" ), _( "Align on the low, centre or high coordinate edge" ), - VIPS_ARGUMENT_REQUIRED_INPUT, + VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET( VipsJoin, align ), VIPS_TYPE_ALIGN, VIPS_ALIGN_LOW ); } @@ -227,14 +310,14 @@ vips_join_init( VipsJoin *join ) } int -vips_join( VipsImage *main, VipsImage *sub, VipsImage **out, +vips_join( VipsImage *in1, VipsImage *in2, VipsImage **output, VipsDirection direction, ... ) { va_list ap; int result; - va_start( ap, y ); - result = vips_call_split( "join", ap, main, sub, out, direction ); + va_start( ap, direction ); + result = vips_call_split( "join", ap, in1, in2, output, direction ); va_end( ap ); return( result ); diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 6788c9cc..d2a4bbc2 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -1146,4 +1146,37 @@ im_insert_noexpand( IMAGE *main, IMAGE *sub, IMAGE *out, int x, int y ) return( 0 ); } +int +im_lrjoin( IMAGE *left, IMAGE *right, IMAGE *out ) +{ + VipsImage *t; + + if( vips_join( left, right, &t, VIPS_DIRECTION_HORIZONTAL, + NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + return( 0 ); +} + +int +im_tbjoin( IMAGE *left, IMAGE *right, IMAGE *out ) +{ + VipsImage *t; + + if( vips_join( left, right, &t, VIPS_DIRECTION_VERTICAL, + NULL ) ) + return( -1 ); + if( vips_image_write( t, out ) ) { + g_object_unref( t ); + return( -1 ); + } + g_object_unref( t ); + + return( 0 ); +} diff --git a/libvips/deprecated/wrapvips7.c b/libvips/deprecated/wrapvips7.c index 55108689..d8d1744b 100644 --- a/libvips/deprecated/wrapvips7.c +++ b/libvips/deprecated/wrapvips7.c @@ -801,7 +801,6 @@ vips_wrap7_subclass_class_init( VipsWrap7Class *class ) case VIPS_WRAP7_INTVEC: case VIPS_WRAP7_GVALUE: case VIPS_WRAP7_INTERPOLATE: - case VIPS_WRAP7_INT: case VIPS_WRAP7_COMPLEX: case VIPS_WRAP7_STRING: case VIPS_WRAP7_NONE: @@ -812,6 +811,14 @@ vips_wrap7_subclass_class_init( VipsWrap7Class *class ) pspec = NULL; break; + case VIPS_WRAP7_INT: + pspec = g_param_spec_int( arg->name, + arg->name, + arg->name, + -G_MAXINT, G_MAXINT, 0, + G_PARAM_READWRITE ); + break; + case VIPS_WRAP7_DOUBLE: pspec = g_param_spec_double( arg->name, arg->name, diff --git a/libvips/include/vips/conversion.h b/libvips/include/vips/conversion.h index 0b6c0650..c0e4c45e 100644 --- a/libvips/include/vips/conversion.h +++ b/libvips/include/vips/conversion.h @@ -164,8 +164,6 @@ int im_extract_areabands( VipsImage *in, VipsImage *out, int im_bandjoin( VipsImage *in1, VipsImage *in2, VipsImage *out ); int im_gbandjoin( VipsImage **in, VipsImage *out, int n ); int im_insertset( VipsImage *main, VipsImage *sub, VipsImage *out, int n, int *x, int *y ); -int im_lrjoin( VipsImage *left, VipsImage *right, VipsImage *out ); -int im_tbjoin( VipsImage *top, VipsImage *bottom, VipsImage *out ); int im_replicate( VipsImage *in, VipsImage *out, int across, int down ); int im_grid( VipsImage *in, VipsImage *out, int tile_height, int across, int down ); int im_wrap( VipsImage *in, VipsImage *out, int x, int y ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 9b8edcf7..0470ed97 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -546,6 +546,9 @@ int im_flipver( VipsImage *in, VipsImage *out ); int im_insert( VipsImage *main, VipsImage *sub, VipsImage *out, int x, int y ); int im_insert_noexpand( VipsImage *main, VipsImage *sub, VipsImage *out, int x, int y ); +int im_lrjoin( VipsImage *left, VipsImage *right, VipsImage *out ); +int im_tbjoin( VipsImage *top, VipsImage *bottom, VipsImage *out ); + /* ruby-vips uses this */ #define vips_class_map_concrete_all vips_class_map_all diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index 98ae367a..d88f0da1 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -54,6 +54,7 @@ vips_align_get_type( void ) {VIPS_ALIGN_LOW, "VIPS_ALIGN_LOW", "low"}, {VIPS_ALIGN_CENTRE, "VIPS_ALIGN_CENTRE", "centre"}, {VIPS_ALIGN_HIGH, "VIPS_ALIGN_HIGH", "high"}, + {VIPS_ALIGN_LAST, "VIPS_ALIGN_LAST", "last"}, {0, NULL, NULL} };