boolean revised
This commit is contained in:
parent
c6418893eb
commit
4e2cb87524
@ -38,6 +38,7 @@
|
||||
- close callbacks now happen *after* images have closed resources (such as
|
||||
open files) ... this lets them delete temps and stuff. Expect breakage :(
|
||||
- added vips_interpolate_get_window_offset()
|
||||
- boolean revised: smaller, more general, faster
|
||||
|
||||
25/3/09 started 7.18.0
|
||||
- revised version numbers
|
||||
|
@ -186,7 +186,7 @@ im__format_common( IMAGE *in1, IMAGE *in2 )
|
||||
|
||||
/* Make an n-band image. Input 1 or n bands.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
im__bandup( IMAGE *in, IMAGE *out, int n )
|
||||
{
|
||||
IMAGE *bands[256];
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
@ -61,26 +60,26 @@
|
||||
|
||||
/* Integer remainder-after-division.
|
||||
*/
|
||||
#define ILOOP( IN, OUT ) { \
|
||||
IN *p1 = (IN *) in[0]; \
|
||||
IN *p2 = (IN *) in[1]; \
|
||||
OUT *q = (OUT *) out; \
|
||||
#define IREMAINDER( TYPE ) { \
|
||||
TYPE *p1 = (TYPE *) in[0]; \
|
||||
TYPE *p2 = (TYPE *) in[1]; \
|
||||
TYPE *q = (TYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
if( p2[x] ) \
|
||||
q[x] = (int) p1[x] % (int) p2[x]; \
|
||||
q[x] = p1[x] % p2[x]; \
|
||||
else \
|
||||
q[x] = -1; \
|
||||
}
|
||||
|
||||
/* Float remainder-after-division.
|
||||
*/
|
||||
#define FLOOP( IN, OUT ) { \
|
||||
IN *p1 = (IN *) in[0]; \
|
||||
IN *p2 = (IN *) in[1]; \
|
||||
OUT *q = (OUT *) out; \
|
||||
#define FREMAINDER( TYPE ) { \
|
||||
TYPE *p1 = (TYPE *) in[0]; \
|
||||
TYPE *p2 = (TYPE *) in[1]; \
|
||||
TYPE *q = (TYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
for( x = 0; x < ne; x++ ) { \
|
||||
double a = p1[x]; \
|
||||
double b = p2[x]; \
|
||||
\
|
||||
@ -94,21 +93,22 @@
|
||||
static void
|
||||
remainder_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
||||
{
|
||||
const int ne = width * im->Bands;
|
||||
|
||||
int x;
|
||||
int sz = width * im->Bands;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: ILOOP( signed char, signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: ILOOP( unsigned char, unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: ILOOP( signed short, signed short ); break;
|
||||
case IM_BANDFMT_USHORT: ILOOP( unsigned short, unsigned short ); break;
|
||||
case IM_BANDFMT_INT: ILOOP( signed int, signed int ); break;
|
||||
case IM_BANDFMT_UINT: ILOOP( unsigned int, unsigned int ); break;
|
||||
case IM_BANDFMT_FLOAT: FLOOP( float, float ); break;
|
||||
case IM_BANDFMT_DOUBLE: FLOOP( double, double ); break;
|
||||
case IM_BANDFMT_CHAR: IREMAINDER( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: IREMAINDER( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: IREMAINDER( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: IREMAINDER( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: IREMAINDER( signed int ); break;
|
||||
case IM_BANDFMT_UINT: IREMAINDER( unsigned int ); break;
|
||||
case IM_BANDFMT_FLOAT: FREMAINDER( float ); break;
|
||||
case IM_BANDFMT_DOUBLE: FREMAINDER( double ); break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +125,7 @@ remainder_buffer( PEL **in, PEL *out, int width, IMAGE *im )
|
||||
#define D IM_BANDFMT_DOUBLE
|
||||
#define DX IM_BANDFMT_DPCOMPLEX
|
||||
|
||||
/* Type promotion for remainder. Same as input, except float/complex which are
|
||||
* signed int. Keep in sync with remainder_buffer() above.
|
||||
/* Type promotion for remainder. Keep in sync with remainder_buffer() above.
|
||||
*/
|
||||
static int bandfmt_remainder[10] = {
|
||||
/* UC C US S UI I F X D DX */
|
||||
@ -141,8 +140,8 @@ static int bandfmt_remainder[10] = {
|
||||
*
|
||||
* This operation calculates @in1 % @in2 (remainder after division) and writes
|
||||
* the result to @out. The images must be the same size. They may have any
|
||||
* non-complex format. For float types, im_remainder() calculates a - b *
|
||||
* floor (a / b).
|
||||
* non-complex format. For float formats, im_remainder() calculates @in1 -
|
||||
* @in2 * floor (@in1 / @in2).
|
||||
*
|
||||
* 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
|
||||
@ -161,6 +160,10 @@ static int bandfmt_remainder[10] = {
|
||||
int
|
||||
im_remainder( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
if( im_check_noncomplex( "im_remainder", in1 ) ||
|
||||
im_check_noncomplex( "im_remainder", in2 ) )
|
||||
return( -1 );
|
||||
|
||||
return( im__arith_binary( "im_remainder",
|
||||
in1, in2, out,
|
||||
bandfmt_remainder,
|
||||
@ -176,7 +179,19 @@ im_remainder( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
tq[i] = (TYPE) p[i]; \
|
||||
}
|
||||
|
||||
/* Make a pixel of output type from a realvec.
|
||||
/* Cast a vector of double to a complex vector of TYPE.
|
||||
*/
|
||||
#define CASTC( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < n; i++ ) { \
|
||||
tq[0] = (TYPE) p[i]; \
|
||||
tq[1] = 0; \
|
||||
tq += 2; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Cast a vector of double to the type of IMAGE.
|
||||
*/
|
||||
static PEL *
|
||||
make_pixel( IMAGE *out, int n, double *p )
|
||||
@ -184,9 +199,7 @@ make_pixel( IMAGE *out, int n, double *p )
|
||||
PEL *q;
|
||||
int i;
|
||||
|
||||
g_assert( n == out->Bands );
|
||||
|
||||
if( !(q = IM_ARRAY( out, IM_IMAGE_SIZEOF_PEL( out ), PEL )) )
|
||||
if( !(q = IM_ARRAY( out, n * IM_IMAGE_SIZEOF_ELEMENT( out ), PEL )) )
|
||||
return( NULL );
|
||||
|
||||
switch( out->BandFmt ) {
|
||||
@ -196,6 +209,10 @@ make_pixel( IMAGE *out, int n, double *p )
|
||||
case IM_BANDFMT_USHORT: CAST( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: CAST( signed int ); break;
|
||||
case IM_BANDFMT_UINT: CAST( unsigned int ); break;
|
||||
case IM_BANDFMT_FLOAT: CAST( float ); break;
|
||||
case IM_BANDFMT_DOUBLE: CAST( double ); break;
|
||||
case IM_BANDFMT_COMPLEX: CASTC( float ); break;
|
||||
case IM_BANDFMT_DPCOMPLEX: CASTC( double ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
@ -208,10 +225,10 @@ int
|
||||
im__arith_binary_const( const char *name,
|
||||
IMAGE *in, IMAGE *out, int n, double *c,
|
||||
int format_table[10],
|
||||
im_wrapone_fn fn, void *a )
|
||||
im_wrapone_fn fn1, im_wrapone_fn fnn )
|
||||
{
|
||||
int i;
|
||||
PEL *vector;
|
||||
IMAGE *t;
|
||||
|
||||
if( im_piocheck( in, out ) ||
|
||||
im_check_vector( name, n, in ) ||
|
||||
@ -224,88 +241,127 @@ im__arith_binary_const( const char *name,
|
||||
|
||||
/* Cast vector to output type.
|
||||
*/
|
||||
|
||||
/*
|
||||
need to handle case where vector == 1 but bands == (eg.) 3
|
||||
*/
|
||||
|
||||
if( !(vector = make_pixel( out, n, c )) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapone( in, out, fn, a, vector ) )
|
||||
/* Band-up the input image for the case where we have a >1 vector and
|
||||
* a 1-band image.
|
||||
*/
|
||||
if( !(t = im_open_local( out, "im__arith_binary_const", "p" )) ||
|
||||
im__bandup( in, t, n ) )
|
||||
return( -1 );
|
||||
|
||||
if( n == 1 ) {
|
||||
if( im_wrapone( t, out, fn1, vector, t ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( im_wrapone( t, out, fnn, vector, t ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/* Parameters saved here.
|
||||
/* Integer remainder-after-divide, single constant.
|
||||
*/
|
||||
typedef struct _Remainderconst {
|
||||
IMAGE *in;
|
||||
IMAGE *out;
|
||||
int n;
|
||||
int *c;
|
||||
} Remainderconst;
|
||||
|
||||
/* Integer remainder-after-divide.
|
||||
*/
|
||||
#define ICONST1LOOP( TYPE ) { \
|
||||
#define IREMAINDERCONST1( TYPE ) { \
|
||||
TYPE *p = (TYPE *) in; \
|
||||
TYPE *q = (TYPE *) out; \
|
||||
TYPE c = *((TYPE *) vector); \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
q[x] = p[x] % c; \
|
||||
}
|
||||
|
||||
/* Float remainder-after-divide, single constant.
|
||||
*/
|
||||
#define FREMAINDERCONST1( TYPE ) { \
|
||||
TYPE *p = (TYPE *) in; \
|
||||
TYPE *q = (TYPE *) out; \
|
||||
TYPE c = *((TYPE *) vector); \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) { \
|
||||
double a = p[x]; \
|
||||
\
|
||||
if( c ) \
|
||||
q[x] = a - c * floor (a / c); \
|
||||
else \
|
||||
q[x] = -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
remainderconst1_buffer( PEL *in, PEL *out, int width, Remainderconst *rc )
|
||||
remainderconst1_buffer( PEL *in, PEL *out, int width, PEL *vector, IMAGE *im )
|
||||
{
|
||||
IMAGE *im = rc->in;
|
||||
int sz = width * im->Bands;
|
||||
int c = rc->c[0];
|
||||
const int ne = width * im->Bands;
|
||||
|
||||
int x;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: ICONST1LOOP( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: ICONST1LOOP( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: ICONST1LOOP( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: ICONST1LOOP( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: ICONST1LOOP( signed int ); break;
|
||||
case IM_BANDFMT_UINT: ICONST1LOOP( unsigned int ); break;
|
||||
case IM_BANDFMT_CHAR: IREMAINDERCONST1( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: IREMAINDERCONST1( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: IREMAINDERCONST1( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: IREMAINDERCONST1( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: IREMAINDERCONST1( signed int ); break;
|
||||
case IM_BANDFMT_UINT: IREMAINDERCONST1( unsigned int ); break;
|
||||
case IM_BANDFMT_FLOAT: FREMAINDERCONST1( float ); break;
|
||||
case IM_BANDFMT_DOUBLE: FREMAINDERCONST1( double ); break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
#define ICONSTLOOP( TYPE ) { \
|
||||
/* Integer remainder-after-divide, per-band constant.
|
||||
*/
|
||||
#define IREMAINDERCONSTN( TYPE ) { \
|
||||
TYPE *p = (TYPE *) in; \
|
||||
TYPE *q = (TYPE *) out; \
|
||||
TYPE *c = (TYPE *) vector; \
|
||||
\
|
||||
for( i = 0, x = 0; x < width; x++ ) \
|
||||
for( k = 0; k < b; k++, i++ ) \
|
||||
q[i] = p[i] % c[k]; \
|
||||
}
|
||||
|
||||
/* Float remainder-after-divide, per-band constant.
|
||||
*/
|
||||
#define FREMAINDERCONSTN( TYPE ) { \
|
||||
TYPE *p = (TYPE *) in; \
|
||||
TYPE *q = (TYPE *) out; \
|
||||
TYPE *c = (TYPE *) vector; \
|
||||
\
|
||||
for( i = 0, x = 0; x < width; x++ ) \
|
||||
for( k = 0; k < b; k++, i++ ) { \
|
||||
double a = p[i]; \
|
||||
double b = c[k]; \
|
||||
\
|
||||
if( b ) \
|
||||
q[i] = a - b * floor (a / b); \
|
||||
else \
|
||||
q[i] = -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
remainderconst_buffer( PEL *in, PEL *out, int width, Remainderconst *rc )
|
||||
remainderconst_buffer( PEL *in, PEL *out, int width, PEL *vector, IMAGE *im )
|
||||
{
|
||||
IMAGE *im = rc->in;
|
||||
int b = im->Bands;
|
||||
int *c = rc->c;
|
||||
int i, x, k;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: ICONSTLOOP( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: ICONSTLOOP( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: ICONSTLOOP( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: ICONSTLOOP( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: ICONSTLOOP( signed int ); break;
|
||||
case IM_BANDFMT_UINT: ICONSTLOOP( unsigned int ); break;
|
||||
case IM_BANDFMT_CHAR: IREMAINDERCONSTN( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: IREMAINDERCONSTN( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: IREMAINDERCONSTN( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: IREMAINDERCONSTN( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: IREMAINDERCONSTN( signed int ); break;
|
||||
case IM_BANDFMT_UINT: IREMAINDERCONSTN( unsigned int ); break;
|
||||
case IM_BANDFMT_FLOAT: FREMAINDERCONSTN( float ); break;
|
||||
case IM_BANDFMT_DOUBLE: FREMAINDERCONSTN( double ); break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,70 +373,31 @@ remainderconst_buffer( PEL *in, PEL *out, int width, Remainderconst *rc )
|
||||
* @c: array of constants
|
||||
*
|
||||
* This operation calculates @in % @c (remainder after division by constant)
|
||||
* and writes the result to @out. The image must be one of the integer types.
|
||||
* and writes the result to @out.
|
||||
* The image may have any
|
||||
* non-complex format. For float formats, im_remainder() calculates @in -
|
||||
* @c * floor (@in / @c).
|
||||
*
|
||||
* If the array of constants has one element, that constant is used for each
|
||||
* image band. If the array has more than one element, it must have the same
|
||||
* number of elements as there are bands in the image, and one array element
|
||||
* is used for each band.
|
||||
* If the number of image bands end array elements differs, one of them
|
||||
* must have one band. Either the image is up-banded by joining n copies of
|
||||
* the one-band image together, or the array is upbanded by copying the single
|
||||
* element n times.
|
||||
*
|
||||
* See also: im_remainder(), im_divide().
|
||||
* See also: im_remainder(), im_remainderconst(), im_divide().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_remainderconst_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
Remainderconst *rc;
|
||||
int i;
|
||||
|
||||
/* Basic checks.
|
||||
*/
|
||||
if( im_piocheck( in, out ) ||
|
||||
im_check_vector( "im_remainder", n, in ) ||
|
||||
im_check_uncoded( "im_remainder", in ) ||
|
||||
im_check_int( "im_remainder", in ) )
|
||||
return( -1 );
|
||||
if( im_cp_desc( out, in ) )
|
||||
if( im_check_noncomplex( "im_remainder", in ) )
|
||||
return( -1 );
|
||||
|
||||
/* Take a copy of the parameters.
|
||||
*/
|
||||
if( !(rc = IM_NEW( out, Remainderconst )) ||
|
||||
!(rc->c = IM_ARRAY( out, n, int )) )
|
||||
return( -1 );
|
||||
rc->in = in;
|
||||
rc->out = out;
|
||||
rc->n = n;
|
||||
for( i = 0; i < n; i++ ) {
|
||||
/* Cast down to int ... we pass in double for consistency with
|
||||
* the other _vec functions.
|
||||
*/
|
||||
if( c[i] != (int) c[i] )
|
||||
im_warn( "im_remainderconst_vec",
|
||||
_( "float constant %g truncated to integer" ),
|
||||
c[i] );
|
||||
rc->c[i] = c[i];
|
||||
|
||||
if( rc->c[i] == 0 ) {
|
||||
im_error( "im_remainderconst_vec",
|
||||
"%s", _( "division by zero" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( n == 1 ) {
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) remainderconst1_buffer, rc, NULL ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) remainderconst_buffer, rc, NULL ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
return( im__arith_binary_const( "im_remainder",
|
||||
in, out, n, c,
|
||||
bandfmt_remainder,
|
||||
(im_wrapone_fn) remainderconst1_buffer,
|
||||
(im_wrapone_fn) remainderconst_buffer ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,6 +43,9 @@
|
||||
* 11/9/09
|
||||
* - use new im__cast_and__call()
|
||||
* - therefore now supports 1-band $op n-band
|
||||
* 17/9/09
|
||||
* - moved to im__arith_binary*()
|
||||
* - renamed im_eor_vec() as im_eorimage_vec() for C++ sanity
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -80,190 +83,12 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef WITH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif /*WITH_DMALLOC*/
|
||||
|
||||
/* A selection of main loops. Only implement monotype operations, ie. input
|
||||
* type == output type. Float types are cast to int before we come here.
|
||||
*/
|
||||
#define AND2( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp1 = (TYPE *) p[0]; \
|
||||
TYPE *tp2 = (TYPE *) p[1]; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
tq[x] = tp1[x] & tp2[x]; \
|
||||
}
|
||||
|
||||
#define OR2( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp1 = (TYPE *) p[0]; \
|
||||
TYPE *tp2 = (TYPE *) p[1]; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
tq[x] = tp1[x] | tp2[x]; \
|
||||
}
|
||||
|
||||
#define EOR2( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp1 = (TYPE *) p[0]; \
|
||||
TYPE *tp2 = (TYPE *) p[1]; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
tq[x] = tp1[x] ^ tp2[x]; \
|
||||
}
|
||||
|
||||
#define ANDCONST( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp = (TYPE *) p; \
|
||||
TYPE *tc = (TYPE *) c; \
|
||||
\
|
||||
for( i = 0, x = 0; x < n; x++ ) \
|
||||
for( b = 0; b < bands; b++, i++ ) \
|
||||
tq[i] = tp[i] & tc[b]; \
|
||||
}
|
||||
|
||||
#define ORCONST( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp = (TYPE *) p; \
|
||||
TYPE *tc = (TYPE *) c; \
|
||||
\
|
||||
for( i = 0, x = 0; x < n; x++ ) \
|
||||
for( b = 0; b < bands; b++, i++ ) \
|
||||
tq[i] = tp[i] | tc[b]; \
|
||||
}
|
||||
|
||||
#define EORCONST( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp = (TYPE *) p; \
|
||||
TYPE *tc = (TYPE *) c; \
|
||||
\
|
||||
for( i = 0, x = 0; x < n; x++ ) \
|
||||
for( b = 0; b < bands; b++, i++ ) \
|
||||
tq[i] = tp[i] ^ tc[b]; \
|
||||
}
|
||||
|
||||
/* The above, wrapped up as buffer processing functions.
|
||||
*/
|
||||
static void
|
||||
and_buffer( PEL **p, PEL *q, int n, IMAGE *im )
|
||||
{
|
||||
const int ne = n * im->Bands;
|
||||
|
||||
int x;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: AND2( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: AND2( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: AND2( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: AND2( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: AND2( signed int ); break;
|
||||
case IM_BANDFMT_UINT: AND2( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
or_buffer( PEL **p, PEL *q, int n, IMAGE *im )
|
||||
{
|
||||
const int ne = n * im->Bands;
|
||||
|
||||
int x;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: OR2( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: OR2( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: OR2( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: OR2( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: OR2( signed int ); break;
|
||||
case IM_BANDFMT_UINT: OR2( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eor_buffer( PEL **p, PEL *q, int n, IMAGE *in1 )
|
||||
{
|
||||
const int ne = n * im->Bands;
|
||||
|
||||
int x;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: EOR2( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: EOR2( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: EOR2( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: EOR2( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: EOR2( signed int ); break;
|
||||
case IM_BANDFMT_UINT: EOR2( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
andconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
{
|
||||
int x, i, b;
|
||||
int bands = in->Bands;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: ANDCONST( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: ANDCONST( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: ANDCONST( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: ANDCONST( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: ANDCONST( signed int ); break;
|
||||
case IM_BANDFMT_UINT: ANDCONST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
orconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
{
|
||||
int x, i, b;
|
||||
int bands = in->Bands;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: ORCONST( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: ORCONST( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: ORCONST( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: ORCONST( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: ORCONST( signed int ); break;
|
||||
case IM_BANDFMT_UINT: ORCONST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eorconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
{
|
||||
int x, i, b;
|
||||
int bands = in->Bands;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: EORCONST( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: EORCONST( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: EORCONST( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: EORCONST( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: EORCONST( signed int ); break;
|
||||
case IM_BANDFMT_UINT: EORCONST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Save a bit of typing.
|
||||
*/
|
||||
#define UC IM_BANDFMT_UCHAR
|
||||
@ -277,252 +102,298 @@ eorconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
*/
|
||||
static int bandfmt_bool[10] = {
|
||||
/* UC C US S UI I F X D DX */
|
||||
UC, C, US, S, UI, I, I, I, I, I },
|
||||
UC, C, US, S, UI, I, I, I, I, I,
|
||||
};
|
||||
|
||||
/* The above, wrapped up as im_*() functions.
|
||||
*/
|
||||
#define BINARY( IN, OUT, OP ) { \
|
||||
OUT *tq = (OUT *) q; \
|
||||
IN *tp1 = (IN *) p[0]; \
|
||||
IN *tp2 = (IN *) p[1]; \
|
||||
\
|
||||
for( i = 0; i < ne; i++ ) \
|
||||
tq[i] = (OUT) tp1[i] OP (OUT) tp2[i]; \
|
||||
}
|
||||
|
||||
#define BINARY_BUFFER( NAME, OP ) \
|
||||
static void \
|
||||
NAME ## _buffer( PEL **p, PEL *q, int n, IMAGE *im ) \
|
||||
{ \
|
||||
/* Complex just doubles the size. \
|
||||
*/ \
|
||||
const int ne = n * im->Bands * (im_iscomplex( im ) ? 2 : 1); \
|
||||
\
|
||||
int i; \
|
||||
\
|
||||
switch( im->BandFmt ) { \
|
||||
case IM_BANDFMT_CHAR: \
|
||||
BINARY( signed char, signed char, OP ); break; \
|
||||
case IM_BANDFMT_UCHAR: \
|
||||
BINARY( unsigned char, unsigned char, OP ); break; \
|
||||
case IM_BANDFMT_SHORT: \
|
||||
BINARY( signed short, signed short, OP ); break; \
|
||||
case IM_BANDFMT_USHORT: \
|
||||
BINARY( unsigned short, unsigned short, OP ); break; \
|
||||
case IM_BANDFMT_INT: \
|
||||
BINARY( signed int, signed int, OP ); break; \
|
||||
case IM_BANDFMT_UINT: \
|
||||
BINARY( unsigned int, unsigned int, OP ); break; \
|
||||
case IM_BANDFMT_FLOAT: \
|
||||
BINARY( float, signed int, OP ); break; \
|
||||
case IM_BANDFMT_COMPLEX: \
|
||||
BINARY( float, signed int, OP ); break; \
|
||||
case IM_BANDFMT_DOUBLE: \
|
||||
BINARY( double, signed int, OP ); break; \
|
||||
case IM_BANDFMT_DPCOMPLEX: \
|
||||
BINARY( double, signed int, OP ); break; \
|
||||
\
|
||||
default: \
|
||||
g_assert( 0 ); \
|
||||
} \
|
||||
}
|
||||
|
||||
BINARY_BUFFER( AND, & )
|
||||
|
||||
int
|
||||
im_andimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
return( im__arith_binary( "im_andimage",
|
||||
in1, in2, out,
|
||||
bandfmt_bool,
|
||||
(im_wrapmany_fn) and_buffer, NULL ) );
|
||||
(im_wrapmany_fn) AND_buffer, NULL ) );
|
||||
}
|
||||
|
||||
BINARY_BUFFER( OR, | )
|
||||
|
||||
int
|
||||
im_orimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
return( im__arith_binary( "im_orimage",
|
||||
in1, in2, out,
|
||||
bandfmt_bool,
|
||||
(im_wrapmany_fn) or_buffer, NULL ) );
|
||||
(im_wrapmany_fn) OR_buffer, NULL ) );
|
||||
}
|
||||
|
||||
BINARY_BUFFER( EOR, ^ )
|
||||
|
||||
int
|
||||
im_eorimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
return( im__arith_binary( "im_eorimage",
|
||||
in1, in2, out,
|
||||
bandfmt_bool,
|
||||
(im_wrapmany_fn) eor_buffer, NULL ) );
|
||||
(im_wrapmany_fn) EOR_buffer, NULL ) );
|
||||
}
|
||||
|
||||
#define CONST1( IN, OUT, OP ) { \
|
||||
OUT *tq = (OUT *) q; \
|
||||
IN *tp = (IN *) p; \
|
||||
IN tc = *((IN *) vector); \
|
||||
\
|
||||
for( i = 0; i < ne; i++ ) \
|
||||
tq[i] = (OUT) tp[i] OP (OUT) tc; \
|
||||
}
|
||||
|
||||
#define CONST1_BUFFER( NAME, OP ) \
|
||||
static void \
|
||||
NAME ## 1_buffer( PEL *p, PEL *q, int n, PEL *vector, IMAGE *im ) \
|
||||
{ \
|
||||
/* Complex just doubles the size. \
|
||||
*/ \
|
||||
const int ne = n * im->Bands * (im_iscomplex( im ) ? 2 : 1); \
|
||||
\
|
||||
int i; \
|
||||
\
|
||||
switch( im->BandFmt ) { \
|
||||
case IM_BANDFMT_CHAR: \
|
||||
CONST1( signed char, signed char, OP ); break; \
|
||||
case IM_BANDFMT_UCHAR: \
|
||||
CONST1( unsigned char, unsigned char, OP ); break; \
|
||||
case IM_BANDFMT_SHORT: \
|
||||
CONST1( signed short, signed short, OP ); break; \
|
||||
case IM_BANDFMT_USHORT: \
|
||||
CONST1( unsigned short, unsigned short, OP ); break; \
|
||||
case IM_BANDFMT_INT: \
|
||||
CONST1( signed int, signed int, OP ); break; \
|
||||
case IM_BANDFMT_UINT: \
|
||||
CONST1( unsigned int, unsigned int, OP ); break; \
|
||||
case IM_BANDFMT_FLOAT: \
|
||||
CONST1( float, signed int, OP ); break; \
|
||||
case IM_BANDFMT_COMPLEX: \
|
||||
CONST1( float, signed int, OP ); break; \
|
||||
case IM_BANDFMT_DOUBLE: \
|
||||
CONST1( double, signed int, OP ); break; \
|
||||
case IM_BANDFMT_DPCOMPLEX: \
|
||||
CONST1( double, signed int, OP ); break; \
|
||||
\
|
||||
default: \
|
||||
g_assert( 0 ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CONSTN( IN, OUT, OP ) { \
|
||||
OUT *tq = (OUT *) q; \
|
||||
IN *tp = (IN *) p; \
|
||||
IN *tc = (IN *) vector; \
|
||||
\
|
||||
for( i = 0, x = 0; x < n; x++ ) \
|
||||
for( b = 0; b < bands; b++, i++ ) \
|
||||
tq[i] = (OUT) tp[i] OP (OUT) tc[b]; \
|
||||
}
|
||||
|
||||
#define CONSTN_BUFFER( NAME, OP ) \
|
||||
static void \
|
||||
NAME ## n_buffer( PEL *p, PEL *q, int n, PEL *vector, IMAGE *im ) \
|
||||
{ \
|
||||
const int bands = im->Bands; \
|
||||
\
|
||||
int i, x, b; \
|
||||
\
|
||||
switch( im->BandFmt ) { \
|
||||
case IM_BANDFMT_CHAR: \
|
||||
CONSTN( signed char, signed char, OP ); break; \
|
||||
case IM_BANDFMT_UCHAR: \
|
||||
CONSTN( unsigned char, unsigned char, OP ); break; \
|
||||
case IM_BANDFMT_SHORT: \
|
||||
CONSTN( signed short, signed short, OP ); break; \
|
||||
case IM_BANDFMT_USHORT: \
|
||||
CONSTN( unsigned short, unsigned short, OP ); break; \
|
||||
case IM_BANDFMT_INT: \
|
||||
CONSTN( signed int, signed int, OP ); break; \
|
||||
case IM_BANDFMT_UINT: \
|
||||
CONSTN( unsigned int, unsigned int, OP ); break; \
|
||||
case IM_BANDFMT_FLOAT: \
|
||||
CONSTN( float, signed int, OP ); break; \
|
||||
case IM_BANDFMT_COMPLEX: \
|
||||
CONSTN( float, signed int, OP ); break; \
|
||||
case IM_BANDFMT_DOUBLE: \
|
||||
CONSTN( double, signed int, OP ); break; \
|
||||
case IM_BANDFMT_DPCOMPLEX: \
|
||||
CONSTN( double, signed int, OP ); break; \
|
||||
\
|
||||
default: \
|
||||
g_assert( 0 ); \
|
||||
} \
|
||||
}
|
||||
|
||||
CONST1_BUFFER( AND, & )
|
||||
|
||||
CONSTN_BUFFER( AND, & )
|
||||
|
||||
int
|
||||
im_andimage_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
return( im__arith_binary_const( "im_andimage",
|
||||
in, out, n, c,
|
||||
bandfmt_bool,
|
||||
(im_wrapone_fn) AND1_buffer,
|
||||
(im_wrapone_fn) ANDn_buffer ) );
|
||||
}
|
||||
|
||||
CONST1_BUFFER( OR, | )
|
||||
|
||||
CONSTN_BUFFER( OR, | )
|
||||
|
||||
int
|
||||
im_orimage_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
return( im__arith_binary_const( "im_orimage",
|
||||
in, out, n, c,
|
||||
bandfmt_bool,
|
||||
(im_wrapone_fn) OR1_buffer,
|
||||
(im_wrapone_fn) ORn_buffer ) );
|
||||
}
|
||||
|
||||
CONST1_BUFFER( EOR, ^ )
|
||||
|
||||
CONSTN_BUFFER( EOR, ^ )
|
||||
|
||||
int
|
||||
im_eorimage_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
return( im__arith_binary_const( "im_eorimage",
|
||||
in, out, n, c,
|
||||
bandfmt_bool,
|
||||
(im_wrapone_fn) EOR1_buffer,
|
||||
(im_wrapone_fn) EORn_buffer ) );
|
||||
}
|
||||
|
||||
CONST1_BUFFER( SHIFTL, << )
|
||||
|
||||
CONSTN_BUFFER( SHIFTL, << )
|
||||
|
||||
int
|
||||
im_shiftleft_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
return( im__arith_binary_const( "im_shiftleft",
|
||||
in, out, n, c,
|
||||
bandfmt_bool,
|
||||
(im_wrapone_fn) SHIFTL1_buffer,
|
||||
(im_wrapone_fn) SHIFTLn_buffer ) );
|
||||
}
|
||||
|
||||
CONST1_BUFFER( SHIFTR, >> )
|
||||
|
||||
CONSTN_BUFFER( SHIFTR, >> )
|
||||
|
||||
int
|
||||
im_shiftright_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
return( im__arith_binary_const( "im_shiftright",
|
||||
in, out, n, c,
|
||||
bandfmt_bool,
|
||||
(im_wrapone_fn) SHIFTR1_buffer,
|
||||
(im_wrapone_fn) SHIFTRn_buffer ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_and_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
IMAGE *invec[2];
|
||||
PEL *cb;
|
||||
|
||||
invec[0] = in; invec[1] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
in = invec[0];
|
||||
if( n != in->Bands ) {
|
||||
im_error( "im_and_vec",
|
||||
"%s", _( "vec size does not match bands" ) );
|
||||
return( -1 );
|
||||
}
|
||||
if( !(cb = make_pixel( out, in->BandFmt, c )) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) andconst_buffer, (void *) in, (void *) cb ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
return( im_andimage_vec( in, out, n, c ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_or_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
IMAGE *invec[2];
|
||||
PEL *cb;
|
||||
|
||||
invec[0] = in; invec[1] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
in = invec[0];
|
||||
if( n != in->Bands ) {
|
||||
im_error( "im_or_vec",
|
||||
"%s", _( "vec size does not match bands" ) );
|
||||
return( -1 );
|
||||
}
|
||||
if( !(cb = make_pixel( out, in->BandFmt, c )) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) orconst_buffer, (void *) in, (void *) cb ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
return( im_orimage_vec( in, out, n, c ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_eor_vec( IMAGE *in, IMAGE *out, int n, double *c )
|
||||
{
|
||||
IMAGE *invec[2];
|
||||
PEL *cb;
|
||||
|
||||
invec[0] = in; invec[1] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
in = invec[0];
|
||||
if( n != in->Bands ) {
|
||||
im_error( "im_eor_vec",
|
||||
"%s", _( "vec size does not match bands" ) );
|
||||
return( -1 );
|
||||
}
|
||||
if( !(cb = make_pixel( out, in->BandFmt, c )) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) eorconst_buffer, (void *) in, (void *) cb ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Cast a double to a vector of TYPE.
|
||||
*/
|
||||
#define CCAST( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < in->Bands; i++ ) \
|
||||
tq[i] = (TYPE) p; \
|
||||
}
|
||||
|
||||
/* Make a pixel of output type from a single double.
|
||||
*/
|
||||
static double *
|
||||
make_pixel_const( IMAGE *in, IMAGE *out, double p )
|
||||
{
|
||||
double *q;
|
||||
int i;
|
||||
|
||||
if( !(q = IM_ARRAY( out, in->Bands, double )) )
|
||||
return( NULL );
|
||||
for( i = 0; i < in->Bands; i++ )
|
||||
q[i] = p;
|
||||
|
||||
return( q );
|
||||
return( im_eorimage_vec( in, out, n, c ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_andconst( IMAGE *in, IMAGE *out, double c )
|
||||
{
|
||||
double *v = make_pixel_const( in, out, c );
|
||||
|
||||
return( !v || im_and_vec( in, out, in->Bands, v ) );
|
||||
return( im_andimage_vec( in, out, 1, &c ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_orconst( IMAGE *in, IMAGE *out, double c )
|
||||
{
|
||||
double *v = make_pixel_const( in, out, c );
|
||||
|
||||
return( !v || im_or_vec( in, out, in->Bands, v ) );
|
||||
return( im_orimage_vec( in, out, 1, &c ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_eorconst( IMAGE *in, IMAGE *out, double c )
|
||||
{
|
||||
double *v = make_pixel_const( in, out, c );
|
||||
|
||||
return( !v || im_eor_vec( in, out, in->Bands, v ) );
|
||||
return( im_eorimage_vec( in, out, 1, &c ) );
|
||||
}
|
||||
|
||||
/* Assorted shift operations.
|
||||
*/
|
||||
#define SHIFTL( TYPE ) { \
|
||||
TYPE *pt = (TYPE *) p;\
|
||||
TYPE *qt = (TYPE *) q;\
|
||||
\
|
||||
for( x = 0; x < ne; x++ )\
|
||||
qt[x] = pt[x] << n;\
|
||||
}
|
||||
|
||||
/* The above as buffer ops.
|
||||
*/
|
||||
static void
|
||||
shiftleft_buffer( PEL *p, PEL *q, int len, IMAGE *in, int n )
|
||||
{
|
||||
int x;
|
||||
int ne = len * in->Bands;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_UCHAR: SHIFTL( unsigned char ); break;
|
||||
case IM_BANDFMT_CHAR: SHIFTL( signed char ); break;
|
||||
case IM_BANDFMT_USHORT: SHIFTL( unsigned short ); break;
|
||||
case IM_BANDFMT_SHORT: SHIFTL( signed short ); break;
|
||||
case IM_BANDFMT_UINT: SHIFTL( unsigned int ); break;
|
||||
case IM_BANDFMT_INT: SHIFTL( signed int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* The above as im_*() functions.
|
||||
*/
|
||||
int
|
||||
im_shiftleft( IMAGE *in, IMAGE *out, int n )
|
||||
{
|
||||
IMAGE *invec[2];
|
||||
double c = n;
|
||||
|
||||
invec[0] = in; invec[1] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
in = invec[0];
|
||||
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) shiftleft_buffer, in, GINT_TO_POINTER( n ) ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define SHIFTR( TYPE ) { \
|
||||
TYPE *pt = (TYPE *) p; \
|
||||
TYPE *qt = (TYPE *) q; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
qt[x] = pt[x] >> n; \
|
||||
}
|
||||
|
||||
static void
|
||||
shiftright_buffer( PEL *p, PEL *q, int len, IMAGE *in, int n )
|
||||
{
|
||||
int x;
|
||||
int ne = len * in->Bands;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_UCHAR: SHIFTR( unsigned char ); break;
|
||||
case IM_BANDFMT_CHAR: SHIFTR( signed char ); break;
|
||||
case IM_BANDFMT_USHORT: SHIFTR( unsigned short ); break;
|
||||
case IM_BANDFMT_SHORT: SHIFTR( signed short ); break;
|
||||
case IM_BANDFMT_UINT: SHIFTR( unsigned int ); break;
|
||||
case IM_BANDFMT_INT: SHIFTR( signed int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
return( im_shiftleft_vec( in, out, 1, &c ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_shiftright( IMAGE *in, IMAGE *out, int n )
|
||||
{
|
||||
IMAGE *invec[2];
|
||||
double c = n;
|
||||
|
||||
invec[0] = in; invec[1] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
in = invec[0];
|
||||
|
||||
if( im_wrapone( in, out,
|
||||
(im_wrapone_fn) shiftright_buffer, in, GINT_TO_POINTER( n ) ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
return( im_shiftright_vec( in, out, 1, &c ) );
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ png2vips( Read *read, int header_only )
|
||||
*/
|
||||
if( read->pInfo->bit_depth < 8 ) {
|
||||
png_set_packing( read->pPng );
|
||||
png_set_shift( read->pPng, 2 );
|
||||
png_set_shift( read->pPng, &(read->pInfo->sig_bit) );
|
||||
}
|
||||
|
||||
/* If we're an INTEL byte order machine and this is 16bits, we need
|
||||
|
@ -131,10 +131,15 @@ char *im__gslist_gvalue_get( const GSList *list );
|
||||
|
||||
void im__buffer_init( void );
|
||||
|
||||
int im__bandup( IMAGE *in, IMAGE *out, int n );
|
||||
int im__arith_binary( const char *name,
|
||||
IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
int format_table[10],
|
||||
im_wrapmany_fn fn, void *a );
|
||||
int im__arith_binary_const( const char *name,
|
||||
IMAGE *in, IMAGE *out, int n, double *c,
|
||||
int format_table[10],
|
||||
im_wrapone_fn fn1, im_wrapone_fn fnn );
|
||||
int im__math( const char *name, IMAGE *in, IMAGE *out, im_wrapone_fn gen );
|
||||
int im__value( IMAGE *im, double *value );
|
||||
typedef int (*im__wrapscan_fn)( void *p, int n, void *seq, void *a, void *b );
|
||||
|
Loading…
Reference in New Issue
Block a user