more stuff
This commit is contained in:
parent
af3489558e
commit
0660bd1400
|
@ -21,13 +21,15 @@
|
|||
- add and use im_check_uncoded() and friends
|
||||
- matlab load handles column-major and plane-separated images (thanks Mikhail)
|
||||
- JPEG save allows "none" for profile, meaning don't attach a profile
|
||||
- saner, simpler, faster typecasting for im_add(), im_subtract()
|
||||
- im_measure() allows sel == NULL, meaning all patches
|
||||
|
||||
25/3/09 started 7.18.0
|
||||
- revised version numbers
|
||||
- updated vipsmanual
|
||||
- revised manpages
|
||||
- removed name and "changed" from vipsobject since we don't use them yet
|
||||
- explicitly link with stdc++ for nohalo etc stuff
|
||||
- explicitly link with stdc++ for nohalo etc. stuff
|
||||
- wrap im_gauss_imask_sep in C++/Python
|
||||
|
||||
6/3/09 started 7.17.3
|
||||
|
|
|
@ -1127,9 +1127,7 @@ static int
|
|||
measure_vec( im_object *argv )
|
||||
{
|
||||
IMAGE_BOX box;
|
||||
int h, v, i;
|
||||
int *sel;
|
||||
int nsel;
|
||||
int h, v;
|
||||
im_mask_object *mo = argv[1];
|
||||
|
||||
box.xstart = *((int *) argv[2]);
|
||||
|
@ -1141,18 +1139,10 @@ measure_vec( im_object *argv )
|
|||
h = *((int *) argv[6]);
|
||||
v = *((int *) argv[7]);
|
||||
|
||||
nsel = h * v;
|
||||
if( !(sel = IM_ARRAY( NULL, nsel, int )) )
|
||||
return( -1 );
|
||||
for( i = 0; i < nsel; i++ )
|
||||
sel[i] = i + 1;
|
||||
|
||||
if( !(mo->mask =
|
||||
im_measure( argv[0], &box, h, v, sel, nsel, mo->name )) ) {
|
||||
im_free( sel );
|
||||
im_measure( argv[0], &box, h, v, NULL, 0, mo->name )) ) {
|
||||
return( -1 );
|
||||
}
|
||||
im_free( sel );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ add_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
|||
case IM_BANDFMT_INT: LOOP( signed int, signed int ); break;
|
||||
|
||||
case IM_BANDFMT_FLOAT:
|
||||
case IM_BANDFMT_COMPLEX:
|
||||
#ifdef HAVE_LIBOIL
|
||||
oil_add_f32( (float *) out,
|
||||
(float *) in[0], (float *) in[1], sz );
|
||||
|
@ -112,9 +113,10 @@ add_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
|||
#endif /*HAVE_LIBOIL*/
|
||||
break;
|
||||
|
||||
case IM_BANDFMT_DOUBLE: LOOP( double, double ); break;
|
||||
case IM_BANDFMT_COMPLEX:LOOP( float, float ); break;
|
||||
case IM_BANDFMT_DPCOMPLEX:LOOP( double, double ); break;
|
||||
case IM_BANDFMT_DOUBLE:
|
||||
case IM_BANDFMT_DPCOMPLEX:
|
||||
LOOP( double, double );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
/* @(#) Find the average of an image. Takes any non-complex image format,
|
||||
* @(#) returns a double. Finds the average of all bands.
|
||||
* @(#)
|
||||
* @(#) int
|
||||
* @(#) im_avg( im, out )
|
||||
* @(#) IMAGE *im;
|
||||
* @(#) double *out;
|
||||
* @(#)
|
||||
* @(#) Returns 0 on success and -1 on error.
|
||||
/* im_avg.c
|
||||
*
|
||||
* Copyright: 1990, J. Cupitt
|
||||
*
|
||||
|
@ -29,6 +21,8 @@
|
|||
* - use 64 bit arithmetic
|
||||
* 8/12/06
|
||||
* - add liboil support
|
||||
* 18/8/09
|
||||
* - gtkdoc, minor reformatting
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -123,27 +117,27 @@ scan_fn( REGION *reg, void *seq, void *a, void *b )
|
|||
|
||||
/* Sum pels in this section.
|
||||
*/
|
||||
#define loop(TYPE) \
|
||||
{ TYPE *p;\
|
||||
\
|
||||
for( y = to; y < bo; y++ ) { \
|
||||
p = (TYPE *) IM_REGION_ADDR( reg, le, y ); \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
sum += *p++;\
|
||||
}\
|
||||
}
|
||||
#define LOOP( TYPE ) { \
|
||||
TYPE *p; \
|
||||
\
|
||||
for( y = to; y < bo; y++ ) { \
|
||||
p = (TYPE *) IM_REGION_ADDR( reg, le, y ); \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
sum += *p++; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Now generate code for all types.
|
||||
*/
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_UCHAR: loop(unsigned char); break;
|
||||
case IM_BANDFMT_CHAR: loop(signed char); break;
|
||||
case IM_BANDFMT_USHORT: loop(unsigned short); break;
|
||||
case IM_BANDFMT_SHORT: loop(signed short); break;
|
||||
case IM_BANDFMT_UINT: loop(unsigned int); break;
|
||||
case IM_BANDFMT_INT: loop(signed int); break;
|
||||
case IM_BANDFMT_FLOAT: loop(float); break;
|
||||
case IM_BANDFMT_UCHAR: LOOP( unsigned char ); break;
|
||||
case IM_BANDFMT_CHAR: LOOP( signed char ); break;
|
||||
case IM_BANDFMT_USHORT: LOOP( unsigned short ); break;
|
||||
case IM_BANDFMT_SHORT: LOOP( signed short ); break;
|
||||
case IM_BANDFMT_UINT: LOOP( unsigned int ); break;
|
||||
case IM_BANDFMT_INT: LOOP( signed int ); break;
|
||||
case IM_BANDFMT_FLOAT: LOOP( float ); break;
|
||||
|
||||
case IM_BANDFMT_DOUBLE:
|
||||
#ifdef HAVE_LIBOIL
|
||||
|
@ -156,7 +150,7 @@ scan_fn( REGION *reg, void *seq, void *a, void *b )
|
|||
sum += t;
|
||||
}
|
||||
#else /*!HAVE_LIBOIL*/
|
||||
loop(double);
|
||||
LOOP( double );
|
||||
#endif /*HAVE_LIBOIL*/
|
||||
break;
|
||||
|
||||
|
@ -171,11 +165,24 @@ scan_fn( REGION *reg, void *seq, void *a, void *b )
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
/* Find the average of an image.
|
||||
/**
|
||||
* im_avg:
|
||||
* @in: input #IMAGE
|
||||
* @out: output pixel average
|
||||
*
|
||||
* This operation finds the average value in an image. It operates on all
|
||||
* bands of the input image: use im_stats() if you need to calculate an
|
||||
* average for each band.
|
||||
*
|
||||
* Non-complex images only.
|
||||
*
|
||||
* See also: im_stats(), im_bandmean(), im_deviate(), im_rank()
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_avg( IMAGE *in, double *out )
|
||||
{
|
||||
{
|
||||
double sum = 0.0;
|
||||
gint64 vals, pels;
|
||||
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
/* @(#) Average the bands in an image.
|
||||
* @(#)
|
||||
* @(#) int
|
||||
* @(#) im_bandmean(in, out)
|
||||
* @(#) IMAGE *in, *out;
|
||||
* @(#)
|
||||
* @(#) Returns 0 on success and -1 on error
|
||||
/* im_bandmean.c
|
||||
*
|
||||
* Author: Simon Goodall
|
||||
* Written on: 17/7/07
|
||||
* 17/7/07 JC
|
||||
* - hacked about a bit
|
||||
* 18/8/09
|
||||
* - gtkdoc
|
||||
* - get rid of the complex case, just double the width
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -58,13 +55,13 @@
|
|||
TYPE *p1 = (TYPE *) p; \
|
||||
TYPE *q1 = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < n; i++ ) { \
|
||||
for( i = 0; i < sz; i++ ) { \
|
||||
STYPE sum; \
|
||||
\
|
||||
sum = 0; \
|
||||
for( j = 0; j < b; j++ ) \
|
||||
sum += p1[j]; \
|
||||
*q1++ = sum > 0 ? (sum + b / 2) / b : (sum - b / 2) / b; \
|
||||
q1[i] = sum > 0 ? (sum + b / 2) / b : (sum - b / 2) / b; \
|
||||
p1 += b; \
|
||||
} \
|
||||
}
|
||||
|
@ -75,45 +72,27 @@
|
|||
TYPE *p1 = (TYPE *) p; \
|
||||
TYPE *q1 = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < n; i++ ) { \
|
||||
for( i = 0; i < sz; i++ ) { \
|
||||
TYPE sum; \
|
||||
\
|
||||
sum = 0; \
|
||||
for( j = 0; j < b; j++ ) \
|
||||
sum += p1[j]; \
|
||||
*q1++ = sum / b; \
|
||||
q1[i] = sum / b; \
|
||||
p1 += b; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Complex loop. Mean reals and imaginaries separately.
|
||||
*/
|
||||
#define CLOOP( TYPE ) { \
|
||||
TYPE *p1 = (TYPE *) p; \
|
||||
TYPE *q1 = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < n * 2; i += 2 ) { \
|
||||
TYPE sum; \
|
||||
\
|
||||
sum = 0; \
|
||||
for( j = 0; j < b; j++ ) \
|
||||
sum += p1[j * 2]; \
|
||||
q1[0] = sum / b; \
|
||||
sum = 0; \
|
||||
for( j = 0; j < b; j++ ) \
|
||||
sum += p1[j * 2 + 1]; \
|
||||
q1[1] = sum / b; \
|
||||
p1 += b; \
|
||||
q1 += 2; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
bandmean_buffer( PEL *p, PEL *q, int n, IMAGE *in )
|
||||
{
|
||||
int i, j;
|
||||
/* Complex just doubles the size.
|
||||
*/
|
||||
const int sz = n * (im_iscomplex( in ) ? 2 : 1);
|
||||
const int b = in->Bands;
|
||||
|
||||
int i, j;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: ILOOP( signed char, int ); break;
|
||||
case IM_BANDFMT_UCHAR: ILOOP( unsigned char, unsigned int ); break;
|
||||
|
@ -123,14 +102,28 @@ bandmean_buffer( PEL *p, PEL *q, int n, IMAGE *in )
|
|||
case IM_BANDFMT_UINT: ILOOP( unsigned int, unsigned int ); break;
|
||||
case IM_BANDFMT_FLOAT: FLOOP( float ); break;
|
||||
case IM_BANDFMT_DOUBLE: FLOOP( double ); break;
|
||||
case IM_BANDFMT_COMPLEX: CLOOP( float ); break;
|
||||
case IM_BANDFMT_DPCOMPLEX: CLOOP( double ); break;
|
||||
case IM_BANDFMT_COMPLEX:FLOOP( float ); break;
|
||||
case IM_BANDFMT_DPCOMPLEX:FLOOP( double ); break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* im_bandmean:
|
||||
* @in: input #IMAGE
|
||||
* @out: output #IMAGE
|
||||
*
|
||||
* im_bandmean() writes a one-band image where each pixel is the average of
|
||||
* the bands for that pixel in the input image. The output band format is
|
||||
* the same as the input band format. Integer types use round-to-nearest
|
||||
* averaging.
|
||||
*
|
||||
* See also: im_add(), im_avg(), im_recomb()
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_bandmean( IMAGE *in, IMAGE *out )
|
||||
{
|
||||
|
|
|
@ -152,25 +152,38 @@ measure_patches( IMAGE *im, double *coeff, IMAGE_BOX *box,
|
|||
* @name: name to give to returned @DOUBLEMASK
|
||||
*
|
||||
* Analyse a grid of colour patches, producing a #DOUBLEMASK of patch averages.
|
||||
* The operations issues a warning if any patch has a deviation more than 20% of
|
||||
* the mean. Only the central 50% of each patch is averaged.
|
||||
* The mask has a row for each measured patch, and a column for each image
|
||||
* band. The operations issues a warning if any patch has a deviation more
|
||||
* than 20% of
|
||||
* the mean. Only the central 50% of each patch is averaged. If @sel is %NULL
|
||||
* then all patches are measured.
|
||||
*
|
||||
* Example: 6 band image of 4x2 block of colour patches.
|
||||
*
|
||||
* +---+---+---+---+
|
||||
* | 1 | 2 | 3 | 4 |
|
||||
* +---+---+---+---+
|
||||
* | 5 | 6 | 7 | 8 |
|
||||
* +---+---+---+---+
|
||||
*
|
||||
* <tgroup cols='4' align='left' colsep='1' rowsep='1'>
|
||||
* <tbody>
|
||||
* <row>
|
||||
* <entry>1</entry>
|
||||
* <entry>2</entry>
|
||||
* <entry>3</entry>
|
||||
* <entry>4</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>5</entry>
|
||||
* <entry>6</entry>
|
||||
* <entry>7</entry>
|
||||
* <entry>8</entry>
|
||||
* </row>
|
||||
* </tbody>
|
||||
* </tgroup>
|
||||
*
|
||||
* Then call im_measure( im, box, 4, 2, { 2, 4 }, 2, "fred" ) makes a mask
|
||||
* "fred" which has 6 columns, two rows. The first row contains the averages
|
||||
* for patch 2, the second for patch 4.
|
||||
*
|
||||
* Returns: #DOUBLEMASK with a row for each selected patch, a column for each
|
||||
* image band.
|
||||
*
|
||||
* Related: im_avg(), im_deviate(), im_stats().
|
||||
* See also: im_avg(), im_deviate(), im_stats().
|
||||
*
|
||||
* Returns: #DOUBLEMASK of measurements.
|
||||
*/
|
||||
DOUBLEMASK *
|
||||
im_measure( IMAGE *im, IMAGE_BOX *box, int h, int v,
|
||||
|
@ -197,13 +210,20 @@ im_measure( IMAGE *im, IMAGE_BOX *box, int h, int v,
|
|||
return( mask );
|
||||
}
|
||||
|
||||
if( im->Coding != IM_CODING_NONE ) {
|
||||
im_error( "im_measure", "%s", _( "not uncoded" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( im_iscomplex( im ) ) {
|
||||
im_error( "im_measure", "%s", _( "bad input type" ) );
|
||||
if( im_check_uncoded( "im_measure", im ) ||
|
||||
im_check_noncomplex( "im_measure", im ) )
|
||||
return( NULL );
|
||||
|
||||
/* Default to all patches if sel == NULL.
|
||||
*/
|
||||
if( sel == NULL ) {
|
||||
int i;
|
||||
|
||||
nsel = h * v;
|
||||
if( !(sel = IM_ARRAY( im, nsel, int )) )
|
||||
return( NULL );
|
||||
for( i = 0; i < nsel; i++ )
|
||||
sel[i] = i + 1;
|
||||
}
|
||||
|
||||
/* What size mask do we need?
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
* - updated for 1 band $op n band image -> n band image case
|
||||
* 8/12/06
|
||||
* - add liboil support
|
||||
* 18/8/08
|
||||
* - revise upcasting system
|
||||
* - add gtkdoc comments
|
||||
* - remove separate complex case, just double size
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -78,77 +82,49 @@
|
|||
#include <dmalloc.h>
|
||||
#endif /*WITH_DMALLOC*/
|
||||
|
||||
/* Swap two IMAGE pointers.
|
||||
*/
|
||||
#define SWAP(A,B) { \
|
||||
IMAGE *t; \
|
||||
t = (A); (A) = (B); (B) = t; \
|
||||
}
|
||||
|
||||
/* Complex multiply.
|
||||
*/
|
||||
#define cloop(TYPE) \
|
||||
{\
|
||||
TYPE *p1 = (TYPE *) in[0];\
|
||||
TYPE *p2 = (TYPE *) in[1];\
|
||||
TYPE *q = (TYPE *) out;\
|
||||
#define LOOP( IN, OUT ) { \
|
||||
IN *p1 = (IN *) in[0]; \
|
||||
IN *p2 = (IN *) in[1]; \
|
||||
OUT *q = (OUT *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) {\
|
||||
double x1 = p1[0];\
|
||||
double y1 = p1[1];\
|
||||
double x2 = p2[0];\
|
||||
double y2 = p2[1];\
|
||||
\
|
||||
p1 += 2;\
|
||||
p2 += 2;\
|
||||
\
|
||||
q[0] = x1 * x2 - y1 * y2;\
|
||||
q[1] = x1 * y2 + x2 * y1;\
|
||||
\
|
||||
q += 2;\
|
||||
}\
|
||||
}
|
||||
|
||||
/* Real multiply.
|
||||
*/
|
||||
#define rloop(TYPE) \
|
||||
{\
|
||||
TYPE *p1 = (TYPE *) in[0];\
|
||||
TYPE *p2 = (TYPE *) in[1];\
|
||||
TYPE *q = (TYPE *) out;\
|
||||
\
|
||||
for( x = 0; x < sz; x++ )\
|
||||
q[x] = p1[x] * p2[x];\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
q[x] = p1[x] * p2[x]; \
|
||||
}
|
||||
|
||||
static void
|
||||
multiply_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
||||
{
|
||||
int x;
|
||||
int sz = width * im->Bands;
|
||||
/* Complex just doubles the size.
|
||||
*/
|
||||
const int sz = width * im->Bands * (im_iscomplex( im ) ? 2 : 1);
|
||||
|
||||
/* Multiply all input types.
|
||||
int x;
|
||||
|
||||
/* Multiply all input types. Keep types here in sync with
|
||||
* bandfmt_multiply[] below.
|
||||
*/
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: rloop( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: rloop( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: rloop( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: rloop( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: rloop( signed int ); break;
|
||||
case IM_BANDFMT_UINT: rloop( unsigned int ); break;
|
||||
case IM_BANDFMT_CHAR: LOOP( signed char, signed short ); break;
|
||||
case IM_BANDFMT_UCHAR: LOOP( unsigned char, unsigned short ); break;
|
||||
case IM_BANDFMT_SHORT: LOOP( signed short, signed int ); break;
|
||||
case IM_BANDFMT_USHORT: LOOP( unsigned short, unsigned int ); break;
|
||||
case IM_BANDFMT_INT: LOOP( signed int, signed int ); break;
|
||||
case IM_BANDFMT_UINT: LOOP( unsigned int, unsigned int ); break;
|
||||
|
||||
case IM_BANDFMT_FLOAT:
|
||||
case IM_BANDFMT_COMPLEX:
|
||||
#ifdef HAVE_LIBOIL
|
||||
oil_multiply_f32( (float *) out,
|
||||
(float *) in[0], (float *) in[1], sz );
|
||||
#else /*!HAVE_LIBOIL*/
|
||||
rloop( float );
|
||||
LOOP( float, float );
|
||||
#endif /*HAVE_LIBOIL*/
|
||||
break;
|
||||
|
||||
case IM_BANDFMT_DOUBLE: rloop( double ); break;
|
||||
case IM_BANDFMT_COMPLEX: cloop( float ); break;
|
||||
case IM_BANDFMT_DPCOMPLEX: cloop( double ); break;
|
||||
case IM_BANDFMT_DOUBLE:
|
||||
case IM_BANDFMT_DPCOMPLEX:
|
||||
LOOP( double, double );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
|
@ -164,45 +140,108 @@ multiply_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
|||
#define UI IM_BANDFMT_UINT
|
||||
#define I IM_BANDFMT_INT
|
||||
#define F IM_BANDFMT_FLOAT
|
||||
#define M IM_BANDFMT_COMPLEX
|
||||
#define X IM_BANDFMT_COMPLEX
|
||||
#define D IM_BANDFMT_DOUBLE
|
||||
#define DM IM_BANDFMT_DPCOMPLEX
|
||||
#define DX IM_BANDFMT_DPCOMPLEX
|
||||
|
||||
/* Type conversions for two integer inputs. Rules for float and complex
|
||||
* encoded with ifs. We are sign and value preserving.
|
||||
/* Type promotion for multiplication. Sign and value preserving. Make sure
|
||||
* these match the case statement in multiply_buffer() above.
|
||||
*/
|
||||
static int iformat[6][6] = {
|
||||
/* UC C US S UI I */
|
||||
/* UC */ { US, S, UI, I, UI, I },
|
||||
/* C */ { S, S, I, I, I, I },
|
||||
/* US */ { UI, I, UI, I, UI, I },
|
||||
/* S */ { I, I, I, I, I, I },
|
||||
/* UI */ { UI, I, UI, I, UI, I },
|
||||
/* I */ { I, I, I, I, I, I }
|
||||
static int bandfmt_multiply[10] = {
|
||||
/* UC C US S UI I F X D DX */
|
||||
US, S, UI, I, UI, I, F, X, D, DX
|
||||
};
|
||||
|
||||
/**
|
||||
* im_multiply:
|
||||
* @in1: input #IMAGE 1
|
||||
* @in2: input #IMAGE 2
|
||||
* @out: output #IMAGE
|
||||
*
|
||||
* This operation calculates @in1 * @in2 and writes the result to @out.
|
||||
* The images must be the same size. They may have any format.
|
||||
*
|
||||
* 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
|
||||
* <link linkend="VIPS-arithmetic">arithmetic</link>), then the
|
||||
* following table is used to determine the output type:
|
||||
*
|
||||
* <table>
|
||||
* <title>im_add() type promotion</title>
|
||||
* <tgroup cols='2' align='left' colsep='1' rowsep='1'>
|
||||
* <thead>
|
||||
* <row>
|
||||
* <entry>input type</entry>
|
||||
* <entry>output type</entry>
|
||||
* </row>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <row>
|
||||
* <entry>uchar</entry>
|
||||
* <entry>ushort</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>char</entry>
|
||||
* <entry>short</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>ushort</entry>
|
||||
* <entry>uint</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>short</entry>
|
||||
* <entry>int</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>uint</entry>
|
||||
* <entry>uint</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>int</entry>
|
||||
* <entry>int</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>float</entry>
|
||||
* <entry>float</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>double</entry>
|
||||
* <entry>double</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>complex</entry>
|
||||
* <entry>complex</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>double complex</entry>
|
||||
* <entry>double complex</entry>
|
||||
* </row>
|
||||
* </tbody>
|
||||
* </tgroup>
|
||||
* </table>
|
||||
*
|
||||
* In other words, the output type is just large enough to hold the whole
|
||||
* range of possible values.
|
||||
*
|
||||
* See also: im_divide(), im_lintra().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_multiply( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
/* Basic checks.
|
||||
*/
|
||||
if( im_piocheck( in1, out ) || im_pincheck( in2 ) )
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( "im_multiply", in1, in2 ) ||
|
||||
im_check_uncoded( "im_multiply", in1 ) ||
|
||||
im_check_uncoded( "im_multiply", in2 ) )
|
||||
return( -1 );
|
||||
|
||||
if( in1->Xsize != in2->Xsize || in1->Ysize != in2->Ysize ) {
|
||||
im_error( "im_multiply", "%s", _( "not same size" ) );
|
||||
return( -1 );
|
||||
}
|
||||
if( in1->Bands != in2->Bands &&
|
||||
(in1->Bands != 1 && in2->Bands != 1) ) {
|
||||
im_error( "im_multiply",
|
||||
"%s", _( "not same number of bands" ) );
|
||||
return( -1 );
|
||||
}
|
||||
if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) {
|
||||
im_error( "im_multiply", "%s", _( "not uncoded" ) );
|
||||
return( -1 );
|
||||
}
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -210,45 +249,10 @@ im_multiply( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
|||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* Swap arguments to get the largest on the left.
|
||||
*/
|
||||
if( in1->Bbits < in2->Bbits )
|
||||
SWAP( in1, in2 );
|
||||
|
||||
/* What output type will we write? int, float or complex.
|
||||
*/
|
||||
if( im_iscomplex( in1 ) || im_iscomplex( in2 ) ) {
|
||||
/* Make sure we have complex on the left.
|
||||
*/
|
||||
if( !im_iscomplex( in1 ) )
|
||||
SWAP( in1, in2 );
|
||||
|
||||
/* What kind of complex?
|
||||
*/
|
||||
if( in1->BandFmt == IM_BANDFMT_DPCOMPLEX )
|
||||
/* Output will be DPCOMPLEX.
|
||||
*/
|
||||
out->BandFmt = IM_BANDFMT_DPCOMPLEX;
|
||||
else
|
||||
out->BandFmt = IM_BANDFMT_COMPLEX;
|
||||
}
|
||||
else if( im_isfloat( in1 ) || im_isfloat( in2 ) ) {
|
||||
/* Make sure we have float on the left.
|
||||
*/
|
||||
if( !im_isfloat( in1 ) )
|
||||
SWAP( in1, in2 );
|
||||
|
||||
/* What kind of float?
|
||||
*/
|
||||
if( in1->BandFmt == IM_BANDFMT_DOUBLE )
|
||||
out->BandFmt = IM_BANDFMT_DOUBLE;
|
||||
else
|
||||
out->BandFmt = IM_BANDFMT_FLOAT;
|
||||
}
|
||||
else
|
||||
/* Must be int+int = int.
|
||||
*/
|
||||
out->BandFmt = iformat[in2->BandFmt][in1->BandFmt];
|
||||
out->BandFmt = bandfmt_multiply[im__format_common( in1, in2 )];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
/* And process!
|
||||
*/
|
||||
|
|
|
@ -113,7 +113,9 @@ subtract_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
|||
case IM_BANDFMT_USHORT: LOOP( unsigned short, signed int ); break;
|
||||
case IM_BANDFMT_INT: LOOP( signed int, signed int ); break;
|
||||
case IM_BANDFMT_UINT: LOOP( unsigned int, signed int ); break;
|
||||
|
||||
case IM_BANDFMT_FLOAT:
|
||||
case IM_BANDFMT_COMPLEX:
|
||||
#ifdef HAVE_LIBOIL
|
||||
oil_subtract_f32( (float *) out,
|
||||
(float *) in[0], (float *) in[1], sz );
|
||||
|
@ -122,9 +124,10 @@ subtract_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
|||
#endif /*HAVE_LIBOIL*/
|
||||
break;
|
||||
|
||||
case IM_BANDFMT_DOUBLE: LOOP( double, double ); break;
|
||||
case IM_BANDFMT_COMPLEX:LOOP( float, float ); break;
|
||||
case IM_BANDFMT_DPCOMPLEX:LOOP( double, double ); break;
|
||||
case IM_BANDFMT_DOUBLE:
|
||||
case IM_BANDFMT_DPCOMPLEX:
|
||||
LOOP( double, double );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
|
|
Loading…
Reference in New Issue