libvips/libvips/mosaicing/remosaic.c

234 lines
5.7 KiB
C
Raw Normal View History

2009-08-16 17:00:08 +02:00
/* Use one mosiaced file to mosaic another set of images.
*
* 1/11/01 JC
* - from global_balance
* 25/02/02 JC
* - detect size change
* 10/4/06
* - spot file-not-found
* 18/6/20 kleisauke
* - convert to vips8
2009-08-16 17:00:08 +02:00
*/
/*
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
2009-08-16 17:00:08 +02:00
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
/* Define for debug output.
#define DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <glib/gi18n-lib.h>
2009-08-16 17:00:08 +02:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <vips/vips.h>
#include <vips/transform.h>
2014-05-29 10:35:17 +02:00
#include "pmosaicing.h"
2009-08-16 17:00:08 +02:00
#include "global_balance.h"
2014-05-27 16:18:19 +02:00
typedef struct {
VipsOperation parent_instance;
VipsImage *in;
VipsImage *out;
char *old_str;
char *new_str;
2009-08-16 17:00:08 +02:00
int new_len;
int old_len;
2014-05-27 16:18:19 +02:00
} VipsRemosaic;
typedef VipsOperationClass VipsRemosaicClass;
G_DEFINE_TYPE( VipsRemosaic, vips_remosaic, VIPS_TYPE_OPERATION );
2009-08-16 17:00:08 +02:00
static VipsImage *
2014-05-27 16:18:19 +02:00
remosaic_fn( JoinNode *node, VipsRemosaic *remosaic )
2009-08-16 17:00:08 +02:00
{
SymbolTable *st = node->st;
VipsImage *im = node->im;
2009-08-16 17:00:08 +02:00
VipsImage *out;
2009-08-16 17:00:08 +02:00
char filename[FILENAME_MAX];
char *p;
if( !im ) {
vips_error( "vips_remosaic", _( "file \"%s\" not found" ),
2009-08-16 17:00:08 +02:00
node->name );
return( NULL );
}
2014-05-27 16:18:19 +02:00
/* Remove substring remosaic->old_str from in->filename, replace with
* remosaic->new_str.
2009-08-16 17:00:08 +02:00
*/
vips_strncpy( filename, im->filename, FILENAME_MAX );
if( (p = vips_strrstr( filename, remosaic->old_str )) ) {
2009-08-16 17:00:08 +02:00
int offset = p - &filename[0];
vips_strncpy( p, remosaic->new_str, FILENAME_MAX - offset );
vips_strncpy( p + remosaic->new_len,
2014-05-27 16:18:19 +02:00
im->filename + offset + remosaic->old_len,
FILENAME_MAX - offset - remosaic->new_len );
2009-08-16 17:00:08 +02:00
}
#ifdef DEBUG
printf( "vips_remosaic: filename \"%s\" -> \"%s\"\n",
2009-08-16 17:00:08 +02:00
im->filename, filename );
#endif /*DEBUG*/
if( !(out = vips__global_open_image( st, filename )) )
2009-08-16 17:00:08 +02:00
return( NULL );
if( out->Xsize != im->Xsize || out->Ysize != im->Ysize ) {
vips_error( "vips_remosaic",
2009-08-16 17:00:08 +02:00
_( "substitute image \"%s\" is not "
"the same size as \"%s\"" ),
filename, im->filename );
return( NULL );
}
return( out );
}
2014-05-27 16:18:19 +02:00
static int
vips_remosaic_build( VipsObject *object )
{
VipsRemosaic *remosaic = (VipsRemosaic *) object;
SymbolTable *st;
g_object_set( remosaic, "out", vips_image_new(), NULL );
if( VIPS_OBJECT_CLASS( vips_remosaic_parent_class )->
build( object ) )
return( -1 );
if( !(st = vips__build_symtab( remosaic->out, SYM_TAB_SIZE )) ||
vips__parse_desc( st, remosaic->in ) )
2014-05-27 16:18:19 +02:00
return( -1 );
remosaic->old_len = strlen( remosaic->old_str );
remosaic->new_len = strlen( remosaic->new_str );
if( vips__build_mosaic( st, remosaic->out,
2014-05-27 16:18:19 +02:00
(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 = _( "rebuild an mosaiced image" );
2014-05-27 16:18:19 +02:00
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 )
{
}
2011-01-25 14:12:22 +01:00
/**
* vips_remosaic: (method)
2011-01-25 14:12:22 +01:00
* @in: mosaic to rebuild
* @out: (out): output image
2011-01-25 14:12:22 +01:00
* @old_str: gamma of source images
* @new_str: gamma of source images
2014-05-27 16:18:19 +02:00
* @...: %NULL-terminated list of optional named arguments
2011-01-25 14:12:22 +01:00
*
2014-05-27 16:18:19 +02:00
* vips_remosaic() works rather as vips_globalbalance(). It takes apart the
* mosaiced image @in and rebuilds it, substituting images.
2011-01-25 14:12:22 +01:00
*
2014-05-27 16:18:19 +02:00
* Unlike vips_globalbalance(), images are substituted based on their file
* names. The rightmost occurrence of the string @old_str is swapped
2011-01-25 14:12:22 +01:00
* for @new_str, that file is opened, and that image substituted for
2014-05-27 16:18:19 +02:00
* the old image.
2011-01-25 14:12:22 +01:00
*
* It's convenient for multispectral images. You can mosaic one band, then
* use that mosaic as a template for mosaicing the others automatically.
*
2014-05-27 16:18:19 +02:00
* See also: vips_globalbalance().
2011-01-25 14:12:22 +01:00
*
* Returns: 0 on success, -1 on error
*/
2014-05-27 16:18:19 +02:00
int
vips_remosaic( VipsImage *in, VipsImage **out,
const char *old_str, const char *new_str, ... )
2009-08-16 17:00:08 +02:00
{
2014-05-27 16:18:19 +02:00
va_list ap;
int result;
2009-08-16 17:00:08 +02:00
2014-05-27 16:18:19 +02:00
va_start( ap, new_str );
result = vips_call_split( "remosaic", ap, in, out, old_str, new_str );
va_end( ap );
2009-08-16 17:00:08 +02:00
2014-05-27 16:18:19 +02:00
return( result );
2009-08-16 17:00:08 +02:00
}