wrap im_remosaic() as a class
This commit is contained in:
parent
781a7d4dc9
commit
b8886fc209
@ -33,8 +33,8 @@
|
||||
- added im_tile_cache_random() to help nip2
|
||||
- added hough_circle() to vips7 C++ API
|
||||
- added Travis CI config, thanks Lovell
|
||||
- im_*merge(), im_*mosaic(), im_match*(), im_global_balance*() redone as
|
||||
classes
|
||||
- im_*merge(), im_*mosaic(), im_match*(), im_global_balance*(), im_remosaic()
|
||||
redone as classes
|
||||
|
||||
6/3/14 started 7.38.6
|
||||
- grey ramp minimum was wrong
|
||||
|
15
TODO
15
TODO
@ -1,13 +1,10 @@
|
||||
- more mosaicing?
|
||||
|
||||
- quickly wrap the useful bits of mosaicing
|
||||
|
||||
nip2 uses:
|
||||
|
||||
im_*merge() done
|
||||
im_*mosaic() done
|
||||
im_match_linear*() done
|
||||
im_global_balancef() done
|
||||
im_remosaic()
|
||||
im_lrmerge1(), im_tbmerge1()
|
||||
im_lrmosaic1(), im_tbmosaic1()
|
||||
im_correl
|
||||
im_align_bands()
|
||||
im_maxpos_subpel()
|
||||
|
||||
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
||||
|
||||
|
@ -5134,3 +5134,20 @@ im_global_balancef( IMAGE *in, IMAGE *out, double gamma )
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_remosaic( IMAGE *in, IMAGE *out, const char *old_str, const char *new_str )
|
||||
{
|
||||
VipsImage *x;
|
||||
|
||||
if( vips_remosaic( in, &x, old_str, new_str, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_copy( x, out ) ) {
|
||||
g_object_unref( x );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( x );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -44,12 +44,17 @@ int vips_merge( VipsImage *ref, VipsImage *sec, VipsImage **out,
|
||||
int vips_mosaic( VipsImage *ref, VipsImage *sec, VipsImage **out,
|
||||
VipsDirection direction, int xref, int yref, int xsec, int ysec, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
int vips_match( VipsImage *ref, VipsImage *sec, VipsImage **out,
|
||||
int xr1, int yr1, int xs1, int ys1,
|
||||
int xr2, int yr2, int xs2, int ys2, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
int vips_globalbalance( VipsImage *in, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_remosaic( VipsImage *in, VipsImage **out,
|
||||
const char *old_str, const char *new_str, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
||||
#include <vips/vips.h>
|
||||
@ -82,8 +87,6 @@ int im_correl( VipsImage *ref, VipsImage *sec,
|
||||
int xref, int yref, int xsec, int ysec,
|
||||
int hwindowsize, int hsearchsize,
|
||||
double *correlation, int *x, int *y );
|
||||
int im_remosaic( VipsImage *in, VipsImage *out,
|
||||
const char *old_str, const char *new_str );
|
||||
|
||||
int im_align_bands( VipsImage *in, VipsImage *out );
|
||||
int im_maxpos_subpel( VipsImage *in, double *x, double *y );
|
||||
|
@ -1064,6 +1064,9 @@ int im_match_linear_search( VipsImage *ref, VipsImage *sec, VipsImage *out,
|
||||
int im_global_balance( VipsImage *in, VipsImage *out, double gamma );
|
||||
int im_global_balancef( VipsImage *in, VipsImage *out, double gamma );
|
||||
|
||||
int im_remosaic( VipsImage *in, VipsImage *out,
|
||||
const char *old_str, const char *new_str );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -56,15 +56,25 @@
|
||||
#include "mosaic.h"
|
||||
#include "global_balance.h"
|
||||
|
||||
typedef struct _RemosaicData {
|
||||
const char *old_str;
|
||||
const char *new_str;
|
||||
typedef struct {
|
||||
VipsOperation parent_instance;
|
||||
|
||||
VipsImage *in;
|
||||
VipsImage *out;
|
||||
char *old_str;
|
||||
char *new_str;
|
||||
|
||||
int new_len;
|
||||
int old_len;
|
||||
} RemosaicData;
|
||||
|
||||
} VipsRemosaic;
|
||||
|
||||
typedef VipsOperationClass VipsRemosaicClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsRemosaic, vips_remosaic, VIPS_TYPE_OPERATION );
|
||||
|
||||
static IMAGE *
|
||||
remosaic( JoinNode *node, RemosaicData *rd )
|
||||
remosaic_fn( JoinNode *node, VipsRemosaic *remosaic )
|
||||
{
|
||||
SymbolTable *st = node->st;
|
||||
IMAGE *im = node->im;
|
||||
@ -79,17 +89,17 @@ remosaic( JoinNode *node, RemosaicData *rd )
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Remove substring rd->old_str from in->filename, replace with
|
||||
* rd->new_str.
|
||||
/* Remove substring remosaic->old_str from in->filename, replace with
|
||||
* remosaic->new_str.
|
||||
*/
|
||||
im_strncpy( filename, im->filename, FILENAME_MAX );
|
||||
if( (p = im_strrstr( filename, rd->old_str )) ) {
|
||||
if( (p = im_strrstr( filename, remosaic->old_str )) ) {
|
||||
int offset = p - &filename[0];
|
||||
|
||||
im_strncpy( p, rd->new_str, FILENAME_MAX - offset );
|
||||
im_strncpy( p + rd->new_len,
|
||||
im->filename + offset + rd->old_len,
|
||||
FILENAME_MAX - offset - rd->new_len );
|
||||
im_strncpy( p, remosaic->new_str, FILENAME_MAX - offset );
|
||||
im_strncpy( p + remosaic->new_len,
|
||||
im->filename + offset + remosaic->old_len,
|
||||
FILENAME_MAX - offset - remosaic->new_len );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -111,46 +121,111 @@ remosaic( JoinNode *node, RemosaicData *rd )
|
||||
return( out );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_remosaic:
|
||||
* @in: mosaic to rebuild
|
||||
* @out: output image
|
||||
* @old_str: gamma of source images
|
||||
* @new_str: gamma of source images
|
||||
*
|
||||
* im_remosaic() works rather as im_global_balance(). It takes apart the
|
||||
* mosaiced image in and rebuilds it, substituting images.
|
||||
*
|
||||
* Unlike im_global_balance(), images are substituted based on their file‐
|
||||
* names. The rightmost occurence of the string @old_str is swapped
|
||||
* for @new_str, that file is opened, and that image substituted for
|
||||
* the old image.
|
||||
*
|
||||
* It's convenient for multispectral images. You can mosaic one band, then
|
||||
* use that mosaic as a template for mosaicing the others automatically.
|
||||
*
|
||||
* See also: im_lrmosaic(), im_global_balance().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_remosaic( IMAGE *in, IMAGE *out, const char *old_str, const char *new_str )
|
||||
static int
|
||||
vips_remosaic_build( VipsObject *object )
|
||||
{
|
||||
SymbolTable *st;
|
||||
RemosaicData rd;
|
||||
VipsRemosaic *remosaic = (VipsRemosaic *) object;
|
||||
|
||||
if( !(st = im__build_symtab( out, SYM_TAB_SIZE )) ||
|
||||
im__parse_desc( st, in ) )
|
||||
SymbolTable *st;
|
||||
|
||||
g_object_set( remosaic, "out", vips_image_new(), NULL );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_remosaic_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
/* Re-make mosaic.
|
||||
*/
|
||||
rd.old_str = old_str;
|
||||
rd.new_str = new_str;
|
||||
rd.new_len = strlen( new_str );
|
||||
rd.old_len = strlen( old_str );
|
||||
if( im__build_mosaic( st, out, (transform_fn) remosaic, &rd ) )
|
||||
if( !(st = im__build_symtab( remosaic->out, SYM_TAB_SIZE )) ||
|
||||
im__parse_desc( st, remosaic->in ) )
|
||||
return( -1 );
|
||||
|
||||
remosaic->old_len = strlen( remosaic->old_str );
|
||||
remosaic->new_len = strlen( remosaic->new_str );
|
||||
if( im__build_mosaic( st, remosaic->out,
|
||||
(transform_fn) remosaic_fn, remosaic ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_remosaic_class_init( VipsRemosaicClass *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 = "remosaic";
|
||||
object_class->description = _( "global balance an image mosaic" );
|
||||
object_class->build = vips_remosaic_build;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsRemosaic, in ) );
|
||||
|
||||
VIPS_ARG_IMAGE( class, "out", 2,
|
||||
_( "Output" ),
|
||||
_( "Output image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsRemosaic, out ) );
|
||||
|
||||
VIPS_ARG_STRING( class, "old_str", 5,
|
||||
_( "old_str" ),
|
||||
_( "Search for this string" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsRemosaic, old_str ),
|
||||
"" );
|
||||
|
||||
VIPS_ARG_STRING( class, "new_str", 6,
|
||||
_( "new_str" ),
|
||||
_( "And swap for this string" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsRemosaic, new_str ),
|
||||
"" );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_remosaic_init( VipsRemosaic *remosaic )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_remosaic:
|
||||
* @in: mosaic to rebuild
|
||||
* @out: output image
|
||||
* @old_str: gamma of source images
|
||||
* @new_str: gamma of source images
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* vips_remosaic() works rather as vips_globalbalance(). It takes apart the
|
||||
* mosaiced image @in and rebuilds it, substituting images.
|
||||
*
|
||||
* Unlike vips_globalbalance(), images are substituted based on their file‐
|
||||
* names. The rightmost occurence of the string @old_str is swapped
|
||||
* for @new_str, that file is opened, and that image substituted for
|
||||
* the old image.
|
||||
*
|
||||
* It's convenient for multispectral images. You can mosaic one band, then
|
||||
* use that mosaic as a template for mosaicing the others automatically.
|
||||
*
|
||||
* See also: vips_globalbalance().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_remosaic( VipsImage *in, VipsImage **out,
|
||||
const char *old_str, const char *new_str, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, new_str );
|
||||
result = vips_call_split( "remosaic", ap, in, out, old_str, new_str );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user