232 lines
5.1 KiB
C
232 lines
5.1 KiB
C
/* @(#) Function to perform a band-wise join of no images.
|
|
* @(#) Input images can have any number of bands; for instance if im[0] has j
|
|
* @(#) bands, im[1] k, ...., im[no-1] l bands, output has j+k+...+l bands
|
|
* @(#) respectively
|
|
* @(#)
|
|
* @(#) Function im_gbandjoin() assumes that the imin image
|
|
* @(#) is either memory mapped or in buffer
|
|
* @(#)
|
|
* @(#) int im_gbandjoin( imarray, imout, no )
|
|
* @(#) IMAGE *imarray[], *imout;
|
|
* @(#) int no;
|
|
* @(#)
|
|
* @(#) All functions return 0 on success and -1 on error
|
|
* @(#)
|
|
*
|
|
* Copyright: 1991, N. Dessipris, modification of im_bandjoin()
|
|
*
|
|
* Author: N. Dessipris
|
|
* Written on: 17/04/1991
|
|
* Modified on :
|
|
* 16/3/94 JC
|
|
* - rewritten for partials
|
|
* - now in ANSI C
|
|
* - now works for any number of input images, except zero
|
|
* 7/10/94 JC
|
|
* - new IM_NEW()
|
|
* 16/4/07
|
|
* - fall back to im_copy() for 1 input image
|
|
*/
|
|
|
|
/*
|
|
|
|
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 <config.h>
|
|
#endif /*HAVE_CONFIG_H*/
|
|
#include <vips/intl.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <vips/vips.h>
|
|
|
|
#ifdef WITH_DMALLOC
|
|
#include <dmalloc.h>
|
|
#endif /*WITH_DMALLOC*/
|
|
|
|
/* Struct we carry stuff around in.
|
|
*/
|
|
typedef struct joins {
|
|
int nim; /* Number of input images */
|
|
IMAGE **in; /* Array of input images, NULL-terminated */
|
|
int *is; /* An int for SIZEOF_PEL() for each image */
|
|
} Join;
|
|
|
|
/* Make a Join struct.
|
|
*/
|
|
static Join *
|
|
make_join( IMAGE *out, IMAGE **in, int nim )
|
|
{
|
|
Join *jn;
|
|
int i;
|
|
|
|
if( !(jn = IM_NEW( out, Join )) )
|
|
return( NULL );
|
|
jn->nim = nim;
|
|
if( !(jn->in = IM_ARRAY( out, nim + 1, IMAGE * )) ||
|
|
!(jn->is = IM_ARRAY( out, nim, int )) )
|
|
return( NULL );
|
|
|
|
/* Remember to NULL-terminate.
|
|
*/
|
|
for( i = 0; i < nim; i++ ) {
|
|
jn->in[i] = in[i];
|
|
jn->is[i] = IM_IMAGE_SIZEOF_PEL( in[i] );
|
|
}
|
|
jn->in[nim] = NULL;
|
|
|
|
return( jn );
|
|
}
|
|
|
|
/* Perform join.
|
|
*/
|
|
static int
|
|
join_bands( REGION *or, void *seq, void *a, void *b )
|
|
{
|
|
REGION **ir = (REGION **) seq;
|
|
Join *jn = (Join *) b;
|
|
int x, y, z, i;
|
|
Rect *r = &or->valid;
|
|
int le = r->left;
|
|
int ri = IM_RECT_RIGHT(r);
|
|
int to = r->top;
|
|
int bo = IM_RECT_BOTTOM(r);
|
|
int ps = IM_IMAGE_SIZEOF_PEL( or->im );
|
|
|
|
/* Prepare each input area.
|
|
*/
|
|
for( i = 0; i < jn->nim; i++ )
|
|
if( im_prepare( ir[i], r ) )
|
|
return( -1 );
|
|
|
|
/* Loop over output!
|
|
*/
|
|
for( y = to; y < bo; y++ ) {
|
|
PEL *qb = (PEL *) IM_REGION_ADDR( or, le, y );
|
|
|
|
/* Loop for each input image.
|
|
*/
|
|
for( i = 0; i < jn->nim; i++ ) {
|
|
PEL *p = (PEL *) IM_REGION_ADDR( ir[i], le, y );
|
|
PEL *q = qb;
|
|
int k = jn->is[i];
|
|
|
|
/* Copy all PELs from this line of this input image
|
|
* into the correct place in the output line.
|
|
*/
|
|
for( x = le; x < ri; x++ ) {
|
|
PEL *qn = q;
|
|
|
|
/* Copy one PEL.
|
|
*/
|
|
for( z = 0; z < k; z++ )
|
|
*q++ = *p++;
|
|
|
|
/* Skip to the point at which the next PEL
|
|
* from this input should go.
|
|
*/
|
|
q = qn + ps;
|
|
}
|
|
|
|
/* Move on to the line start for the next PEL.
|
|
*/
|
|
qb += k;
|
|
}
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
/* Band-wise join of a vector of image descriptors.
|
|
*/
|
|
int
|
|
im_gbandjoin( IMAGE **in, IMAGE *out, int nim )
|
|
{
|
|
int i;
|
|
Join *jn;
|
|
|
|
/* Check it out!
|
|
*/
|
|
if( nim < 1 ) {
|
|
im_error( "im_gbandjoin", "%s", _( "zero input images!" ) );
|
|
return( -1 );
|
|
}
|
|
if( nim == 1 )
|
|
return( im_copy( in[0], out ) );
|
|
|
|
/* Check our args.
|
|
*/
|
|
if( im_poutcheck( out ) )
|
|
return( -1 );
|
|
for( i = 0; i < nim; i++ ) {
|
|
if( im_pincheck( in[i] ) )
|
|
return( -1 );
|
|
|
|
if( in[i]->Coding != IM_CODING_NONE ) {
|
|
im_error( "im_gbandjoin",
|
|
"%s", _( "uncoded input only" ) );
|
|
return( -1 );
|
|
}
|
|
|
|
if( in[0]->BandFmt != in[i]->BandFmt ) {
|
|
im_error( "im_gbandjoin",
|
|
"%s", _( "input images differ in format" ) );
|
|
return( -1 );
|
|
}
|
|
if( in[0]->Xsize != in[i]->Xsize ||
|
|
in[0]->Ysize != in[i]->Ysize ) {
|
|
im_error( "im_gbandjoin",
|
|
"%s", _( "input images differ in size" ) );
|
|
return( -1 );
|
|
}
|
|
}
|
|
|
|
/* Build a data area.
|
|
*/
|
|
if( !(jn = make_join( out, in, nim )) )
|
|
return( -1 );
|
|
|
|
/* Prepare the output header.
|
|
*/
|
|
if( im_cp_desc_array( out, jn->in ) )
|
|
return( -1 );
|
|
out->Bands = 0;
|
|
for( i = 0; i < nim; i++ )
|
|
out->Bands += in[i]->Bands;
|
|
|
|
/* Set demand hints.
|
|
*/
|
|
if( im_demand_hint_array( out, IM_THINSTRIP, jn->in ) )
|
|
return( -1 );
|
|
|
|
if( im_generate( out,
|
|
im_start_many, join_bands, im_stop_many, jn->in, jn ) )
|
|
return( -1 );
|
|
|
|
return( 0 );
|
|
}
|