diff --git a/TODO b/TODO index a987f55c..398820af 100644 --- a/TODO +++ b/TODO @@ -1,25 +1,3 @@ -- fix vipsthumbnail Chicago.png, again - - $ vipsthumbnail Chicago.png - vips_shrink_build: shrinking 29257 x 4196 image to 128 x 18 - vips_shrink_build: 228 x 228 block average - vips_shrink_gen: generating 128 x 10 at 0 x 0 - shrink_gen: requesting 29184 x 228 at 0 x 0 - vips_shrink_gen: generating 128 x 8 at 0 x 10 -1 shrink_gen: requesting 29184 x 228 at 0 x 2280 - shrink_gen: requesting 29184 x 228 at 0 x 228 - shrink_gen: requesting 29184 x 228 at 0 x 456 - shrink_gen: requesting 29184 x 228 at 0 x 684 - shrink_gen: requesting 29184 x 228 at 0 x 912 - shrink_gen: requesting 29184 x 228 at 0 x 1140 - ** VIPS:ERROR:vipspng.c:462:png2vips_generate: assertion failed: (r->top == read->y_pos) - - why does line 1 ask for a block so far down? - - - - - - quickly wrap the useful bits of mosaicing/ @@ -73,7 +51,6 @@ -- need to do mosaicing - now vips_linear() has uchar output, can we do something with orc? diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 6baae9ce..edc8ddf5 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -305,6 +305,7 @@ void vips_create_operation_init( void ); void vips_morphology_operation_init( void ); void vips_convolution_operation_init( void ); void vips_draw_operation_init( void ); +void vips_mosaicing_operation_init( void ); guint64 vips__parse_size( const char *size_string ); int vips__substitute( const char *domain, char *buf, size_t len, char *sub ); diff --git a/libvips/include/vips/mosaicing.h b/libvips/include/vips/mosaicing.h index d171dd00..fee25e76 100644 --- a/libvips/include/vips/mosaicing.h +++ b/libvips/include/vips/mosaicing.h @@ -38,6 +38,15 @@ extern "C" { #endif /*__cplusplus*/ +int vips_merge( VipsImage *ref, VipsImage *sec, VipsImage **out, + VipsDirection direction, int dx, int dy, ... ) + __attribute__((sentinel)); + + + + + + #include int im_match_linear( VipsImage *ref, VipsImage *sec, VipsImage *out, diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 8491706b..680fdc70 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -278,6 +278,7 @@ vips__init( const char *argv0 ) vips_freqfilt_operation_init(); vips_morphology_operation_init(); vips_draw_operation_init(); + vips_mosaicing_operation_init(); /* Load up any plugins in the vips libdir. We don't error on failure, * it's too annoying to have VIPS refuse to start because of a broken diff --git a/libvips/mosaicing/Makefile.am b/libvips/mosaicing/Makefile.am index eb5ca4da..985b1c71 100644 --- a/libvips/mosaicing/Makefile.am +++ b/libvips/mosaicing/Makefile.am @@ -1,6 +1,8 @@ noinst_LTLIBRARIES = libmosaicing.la libmosaicing_la_SOURCES = \ + merge.c \ + \ im_align_bands.c \ match.c \ mosaic1.c \ @@ -19,7 +21,6 @@ libmosaicing_la_SOURCES = \ im_tbmerge.c \ im_remosaic.c \ im_tbmosaic.c \ - merge.h \ global_balance.h \ mosaic.h diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index 16adff04..72d532f5 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -110,7 +110,7 @@ #include #include -#include "merge.h" +#include "mosaic.h" #include "global_balance.h" #define MAX_ITEMS (50) diff --git a/libvips/mosaicing/im_lrmerge.c b/libvips/mosaicing/im_lrmerge.c index bb2f26d7..79057039 100644 --- a/libvips/mosaicing/im_lrmerge.c +++ b/libvips/mosaicing/im_lrmerge.c @@ -81,6 +81,8 @@ * 24/1/11 * - gtk-doc * - match formats and bands automatically + * 22/5/14 + * - wrap as a class */ /* @@ -130,7 +132,7 @@ #include #include -#include "merge.h" +#include "mosaic.h" /* Blend luts. Shared between all lr and tb blends. */ diff --git a/libvips/mosaicing/im_remosaic.c b/libvips/mosaicing/im_remosaic.c index 6a53f61e..1433338a 100644 --- a/libvips/mosaicing/im_remosaic.c +++ b/libvips/mosaicing/im_remosaic.c @@ -53,7 +53,7 @@ #include #include -#include "merge.h" +#include "mosaic.h" #include "global_balance.h" typedef struct _RemosaicData { diff --git a/libvips/mosaicing/im_tbmerge.c b/libvips/mosaicing/im_tbmerge.c index f2cf2b79..1aea0d56 100644 --- a/libvips/mosaicing/im_tbmerge.c +++ b/libvips/mosaicing/im_tbmerge.c @@ -114,7 +114,7 @@ #include #include -#include "merge.h" +#include "mosaic.h" /* Return the position of the first non-zero pel from the top. */ diff --git a/libvips/mosaicing/merge.c b/libvips/mosaicing/merge.c new file mode 100644 index 00000000..869bb647 --- /dev/null +++ b/libvips/mosaicing/merge.c @@ -0,0 +1,220 @@ +/* merge two images left/right or up/down + * + * 22/5/14 + * - from vips_merge() + */ + +/* + + 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +/* This is a simple wrapper over the old vips7 functions. At some point we + * should rewrite this as a pure vips8 class and redo the vips7 functions as + * wrappers over this. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include + +#include + +typedef struct { + VipsOperation parent_instance; + + VipsImage *ref; + VipsImage *sec; + VipsImage *out; + VipsDirection direction; + int dx; + int dy; + int mblend; + +} VipsMerge; + +typedef VipsOperationClass VipsMergeClass; + +G_DEFINE_TYPE( VipsMerge, vips_merge, VIPS_TYPE_OPERATION ); + +static int +vips_merge_build( VipsObject *object ) +{ + VipsMerge *merge = (VipsMerge *) object; + + g_object_set( merge, "out", vips_image_new(), NULL ); + + if( VIPS_OBJECT_CLASS( vips_merge_parent_class )->build( object ) ) + return( -1 ); + + switch( merge->direction ) { + case VIPS_DIRECTION_HORIZONTAL: + if( im_lrmerge( merge->ref, merge->sec, merge->out, + merge->dx, merge->dy, merge->mblend ) ) + return( -1 ); + break; + + case VIPS_DIRECTION_VERTICAL: + if( im_tbmerge( merge->ref, merge->sec, merge->out, + merge->dx, merge->dy, merge->mblend ) ) + break; + + default: + g_assert( 0 ); + } + + return( 0 ); +} + +static void +vips_merge_class_init( VipsMergeClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *object_class = (VipsObjectClass *) class; + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + object_class->nickname = "merge"; + object_class->description = _( "merge two images" ); + object_class->build = vips_merge_build; + + VIPS_ARG_IMAGE( class, "ref", 1, + _( "Reference" ), + _( "Reference image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMerge, ref ) ); + + VIPS_ARG_IMAGE( class, "sec", 2, + _( "Secondary" ), + _( "Secondary image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMerge, sec ) ); + + VIPS_ARG_IMAGE( class, "out", 10, + _( "Output" ), + _( "Output image" ), + VIPS_ARGUMENT_REQUIRED_OUTPUT, + G_STRUCT_OFFSET( VipsMerge, out ) ); + + VIPS_ARG_ENUM( class, "direction", 103, + _( "Direction" ), + _( "Horizontal or vertcial merge" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMerge, direction ), + VIPS_TYPE_DIRECTION, VIPS_DIRECTION_HORIZONTAL ); + + VIPS_ARG_ENUM( class, "direction", 103, + _( "Direction" ), + _( "Horizontal or vertcial merge" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMerge, direction ), + VIPS_TYPE_DIRECTION, VIPS_DIRECTION_HORIZONTAL ); + + VIPS_ARG_INT( class, "dx", 5, + _( "dx" ), + _( "Horizontal displacement from sec to ref" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMerge, dx ), + -100000000, 1000000000, 1 ); + + VIPS_ARG_INT( class, "dy", 5, + _( "dy" ), + _( "Vertical displacement from sec to ref" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsMerge, dy ), + -100000000, 1000000000, 1 ); + + VIPS_ARG_INT( class, "mblend", 5, + _( "Max blend" ), + _( "Maximum blend size" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsMerge, mblend ), + 0, 10000, 10 ); + +} + +static void +vips_merge_init( VipsMerge *merge ) +{ + merge->mblend = 10; +} + +/** + * vips_merge: + * @ref: reference image + * @sec: secondary image + * @out: output image + * @direction: horizontal or vertical merge + * @dx: displacement of ref from sec + * @dy: displacement of ref from sec + * @...: %NULL-terminated list of optional named arguments + * + * @mblend: maximum blend size + * + * This operation joins two images left-right (with @ref on the left) or + * up-down (with @ref above) with a smooth seam. + * + * 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). + * + * @dx and @dy give the displacement of @sec relative to @ref, in other words, + * the vector to get from the origin of @sec to the origin of @ref, in other + * words, @dx will generally be a negative number. + * + * @mblend limits the maximum width of the + * blend area. A value of "-1" means "unlimited". The two images are blended + * with a raised cosine. + * + * Pixels with all bands equal to zero are "transparent", that + * is, zero pixels in the overlap area do not contribute to the merge. + * This makes it possible to join non-rectangular images. + * + * See also: im_lrmosaic(), im_tbmerge(), im_match_linear(), im_insert(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_merge( VipsImage *ref, VipsImage *sec, VipsImage **out, + VipsDirection direction, int dx, int dy, ... ) +{ + va_list ap; + int result; + + va_start( ap, dy ); + result = vips_call_split( "merge", ap, ref, sec, out, direction ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/mosaicing/merge.h b/libvips/mosaicing/merge.h deleted file mode 100644 index 16cd5028..00000000 --- a/libvips/mosaicing/merge.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Declarations for code shared between im_lrmerge() and im_tbmerge(). - */ - -/* - - Copyright (C) 1991-2003 The National Gallery - - This program 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -/* Number of entries in blend table. As a power of two as well, for >>ing. - */ -#define BLEND_SHIFT (10) -#define BLEND_SIZE (1<>ing. + */ +#define BLEND_SHIFT (10) +#define BLEND_SIZE (1< #include "mosaic.h" -#include "merge.h" /* #define DEBUG diff --git a/libvips/mosaicing/mosaicing.c b/libvips/mosaicing/mosaicing.c new file mode 100644 index 00000000..dab6f3cf --- /dev/null +++ b/libvips/mosaicing/mosaicing.c @@ -0,0 +1,101 @@ +/* base class for all mosaicing operations + * + */ + +/* + + Copyright (C) 1991-2005 The National Gallery + + This library 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.1 of the License, or (at your option) any later version. + + This library 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 library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +/* +#define DEBUG + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include +#include + +#include +#include + +/** + * SECTION: mosaicing + * @short_description: build image mosaics + * @stability: Stable + * @include: vips/vips.h + * + * These functions are useful for joining many small images together to make + * one large image. They can cope with unstable contrast and arbitary sub-image + * layout, but will not do any geometric correction. Geometric errors should + * be removed before using these functions. + * + * The mosaicing functions can be grouped into layers: + * + * The lowest level functions are im_correl(), im_lrmerge() and im_tbmerge(). + * im_correl() + * searches a large image for a small sub-image, returning + * the position of the best sub-image match. im_lrmerge() and im_tbmerge() + * join two images together + * left-right or up-down with a smooth seam. + * + * Next, im_lrmosaic() and im_tbmosaic() use the + * search function plus the two low-level merge operations to join two images + * given just an approximate overlap as a start point. + * + * The functions im_lrmosaic1() and im_tbmosaic1() are + * first-order + * analogues of the basic mosaic functions: they take two approximate + * tie-points and use + * them to rotate and scale the right-hand or bottom image before starting to + * join. + * + * Finally, im_global_balance() can be used to remove contrast differences in + * a mosaic + * which has been assembled with these functions. It takes the mosaic apart, + * measures image contrast differences along the seams, finds a set of + * correction factors which will minimise these differences, and reassembles + * the mosaic. + * im_remosaic() uses the + * same + * techniques, but will reassemble the image from a different set of source + * images. + * + */ + +/* Called from iofuncs to init all operations in this dir. Use a plugin system + * instead? + */ +void +vips_mosaicing_operation_init( void ) +{ + extern int vips_merge_get_type( void ); + + vips_merge_get_type(); +} diff --git a/libvips/mosaicing/mosaicing_dispatch.c b/libvips/mosaicing/mosaicing_dispatch.c index b6af4929..df724b22 100644 --- a/libvips/mosaicing/mosaicing_dispatch.c +++ b/libvips/mosaicing/mosaicing_dispatch.c @@ -41,51 +41,7 @@ #include #include -#include "merge.h" - -/** - * SECTION: mosaicing - * @short_description: build image mosaics - * @stability: Stable - * @include: vips/vips.h - * - * These functions are useful for joining many small images together to make - * one large image. They can cope with unstable contrast and arbitary sub-image - * layout, but will not do any geometric correction. Geometric errors should - * be removed before using these functions. - * - * The mosaicing functions can be grouped into layers: - * - * The lowest level functions are im_correl(), im_lrmerge() and im_tbmerge(). - * im_correl() - * searches a large image for a small sub-image, returning - * the position of the best sub-image match. im_lrmerge() and im_tbmerge() - * join two images together - * left-right or up-down with a smooth seam. - * - * Next, im_lrmosaic() and im_tbmosaic() use the - * search function plus the two low-level merge operations to join two images - * given just an approximate overlap as a start point. - * - * The functions im_lrmosaic1() and im_tbmosaic1() are - * first-order - * analogues of the basic mosaic functions: they take two approximate - * tie-points and use - * them to rotate and scale the right-hand or bottom image before starting to - * join. - * - * Finally, im_global_balance() can be used to remove contrast differences in - * a mosaic - * which has been assembled with these functions. It takes the mosaic apart, - * measures image contrast differences along the seams, finds a set of - * correction factors which will minimise these differences, and reassembles - * the mosaic. - * im_remosaic() uses the - * same - * techniques, but will reassemble the image from a different set of source - * images. - * - */ +#include "mosaic.h" /* Merge args. */