bool ops broken for non-int types

This commit is contained in:
John Cupitt 2009-01-26 18:02:11 +00:00
parent b1a150c446
commit 7edc01a449
2 changed files with 79 additions and 82 deletions

View File

@ -31,6 +31,7 @@
- im_buf_t renamed as VipsBuf - im_buf_t renamed as VipsBuf
- added vips_object_to_string() - added vips_object_to_string()
- added "nickname" and "description" properties to VipsObject - added "nickname" and "description" properties to VipsObject
- shift/and/or/eor ops were broken for non-int types
11/9/08 started 7.16.3 11/9/08 started 7.16.3
- oop typo in manpage for im_project() - oop typo in manpage for im_project()

View File

@ -112,18 +112,20 @@ static int iformat[10][10] = {
/* DM */ { I, I, I, I, I, I, I, I, I, I } /* DM */ { I, I, I, I, I, I, I, I, I, I }
}; };
/* Check args. Cast inputs to matching integer format. /* Check args. Cast inputs to matching integer format.
*/ */
static int static int
check( char *name, IMAGE **in, IMAGE *out ) check( IMAGE **in, IMAGE *out )
{ {
int i, n; int i, n;
int fmt;
/* Count args. /* Count args.
*/ */
for( n = 0; in[n]; n++ ) { for( n = 0; in[n]; n++ ) {
if( in[n]->Coding != IM_CODING_NONE ) { if( in[n]->Coding != IM_CODING_NONE ) {
im_errormsg( "%s: uncoded images only", name ); im_error( "boolean",
"%s", _( "uncoded images only" ) );
return( -1 ); return( -1 );
} }
} }
@ -134,24 +136,20 @@ check( char *name, IMAGE **in, IMAGE *out )
if( in[0]->Bands != in[i]->Bands || if( in[0]->Bands != in[i]->Bands ||
in[0]->Xsize != in[i]->Xsize || in[0]->Xsize != in[i]->Xsize ||
in[0]->Ysize != in[i]->Ysize ) { in[0]->Ysize != in[i]->Ysize ) {
im_errormsg( "%s: images differ in size", name ); im_error( "boolean",
"%s", _( "images differ in size" ) );
return( -1 ); return( -1 );
} }
/* Prepare the output image.
*/
if( im_cp_desc_array( out, in ) )
return( -1 );
/* Calculate type conversion ... just 1ary and 2ary. /* Calculate type conversion ... just 1ary and 2ary.
*/ */
switch( n ) { switch( n ) {
case 1: case 1:
out->BandFmt = iformat[0][in[0]->BandFmt]; fmt = iformat[0][in[0]->BandFmt];
break; break;
case 2: case 2:
out->BandFmt = iformat[in[1]->BandFmt][in[0]->BandFmt]; fmt = iformat[in[1]->BandFmt][in[0]->BandFmt];
break; break;
default: default:
@ -159,21 +157,25 @@ check( char *name, IMAGE **in, IMAGE *out )
} }
for( i = 0; i < n; i++ ) { for( i = 0; i < n; i++ ) {
IMAGE *t = im_open_local( out, name, "p" ); IMAGE *t = im_open_local( out, "check-1", "p" );
if( !t || im_clip2fmt( in[i], t, out->BandFmt ) ) if( !t || im_clip2fmt( in[i], t, fmt ) )
return( -1 ); return( -1 );
in[i] = t; in[i] = t;
} }
/* Prepare the output image.
*/
if( im_cp_desc_array( out, in ) )
return( -1 );
return( 0 ); return( 0 );
} }
/* A selection of main loops. As with im_add(), only implement monotype /* A selection of main loops. As with im_add(), only implement monotype
* operations. TYPE is some integer type, signed or unsigned. * operations. TYPE is some integer type, signed or unsigned.
*/ */
#define AND2( TYPE ) \ #define AND2( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
TYPE *tp1 = (TYPE *) p1; \ TYPE *tp1 = (TYPE *) p1; \
TYPE *tp2 = (TYPE *) p2; \ TYPE *tp2 = (TYPE *) p2; \
@ -182,8 +184,7 @@ check( char *name, IMAGE **in, IMAGE *out )
tq[x] = tp1[x] & tp2[x]; \ tq[x] = tp1[x] & tp2[x]; \
} }
#define OR2( TYPE ) \ #define OR2( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
TYPE *tp1 = (TYPE *) p1; \ TYPE *tp1 = (TYPE *) p1; \
TYPE *tp2 = (TYPE *) p2; \ TYPE *tp2 = (TYPE *) p2; \
@ -192,8 +193,7 @@ check( char *name, IMAGE **in, IMAGE *out )
tq[x] = tp1[x] | tp2[x]; \ tq[x] = tp1[x] | tp2[x]; \
} }
#define EOR2( TYPE ) \ #define EOR2( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
TYPE *tp1 = (TYPE *) p1; \ TYPE *tp1 = (TYPE *) p1; \
TYPE *tp2 = (TYPE *) p2; \ TYPE *tp2 = (TYPE *) p2; \
@ -202,8 +202,7 @@ check( char *name, IMAGE **in, IMAGE *out )
tq[x] = tp1[x] ^ tp2[x]; \ tq[x] = tp1[x] ^ tp2[x]; \
} }
#define ANDCONST( TYPE ) \ #define ANDCONST( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
TYPE *tp = (TYPE *) p; \ TYPE *tp = (TYPE *) p; \
TYPE *tc = (TYPE *) c; \ TYPE *tc = (TYPE *) c; \
@ -213,8 +212,7 @@ check( char *name, IMAGE **in, IMAGE *out )
tq[i] = tp[i] & tc[b]; \ tq[i] = tp[i] & tc[b]; \
} }
#define ORCONST( TYPE ) \ #define ORCONST( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
TYPE *tp = (TYPE *) p; \ TYPE *tp = (TYPE *) p; \
TYPE *tc = (TYPE *) c; \ TYPE *tc = (TYPE *) c; \
@ -224,8 +222,7 @@ check( char *name, IMAGE **in, IMAGE *out )
tq[i] = tp[i] | tc[b]; \ tq[i] = tp[i] | tc[b]; \
} }
#define EORCONST( TYPE ) \ #define EORCONST( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
TYPE *tp = (TYPE *) p; \ TYPE *tp = (TYPE *) p; \
TYPE *tc = (TYPE *) c; \ TYPE *tc = (TYPE *) c; \
@ -370,7 +367,7 @@ im_andimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
/* Check images. /* Check images.
*/ */
invec[0] = in1; invec[1] = in2; invec[2] = NULL; invec[0] = in1; invec[1] = in2; invec[2] = NULL;
if( check( "im_andimage", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
/* Process! /* Process!
@ -387,7 +384,7 @@ im_orimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
IMAGE *invec[3]; IMAGE *invec[3];
invec[0] = in1; invec[1] = in2; invec[2] = NULL; invec[0] = in1; invec[1] = in2; invec[2] = NULL;
if( check( "im_orimage", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
if( im_wrapmany( invec, out, (im_wrapmany_fn) or_buffer, out, NULL ) ) if( im_wrapmany( invec, out, (im_wrapmany_fn) or_buffer, out, NULL ) )
@ -402,7 +399,7 @@ im_eorimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
IMAGE *invec[3]; IMAGE *invec[3];
invec[0] = in1; invec[1] = in2; invec[2] = NULL; invec[0] = in1; invec[1] = in2; invec[2] = NULL;
if( check( "im_eorimage", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
if( im_wrapmany( invec, out, (im_wrapmany_fn) eor_buffer, out, NULL ) ) if( im_wrapmany( invec, out, (im_wrapmany_fn) eor_buffer, out, NULL ) )
@ -413,8 +410,7 @@ im_eorimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
/* Cast a vector of double to a vector of TYPE. /* Cast a vector of double to a vector of TYPE.
*/ */
#define CAST( TYPE ) \ #define CAST( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
\ \
for( i = 0; i < out->Bands; i++ ) \ for( i = 0; i < out->Bands; i++ ) \
@ -424,7 +420,7 @@ im_eorimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
/* Make a pixel of output type from a realvec. /* Make a pixel of output type from a realvec.
*/ */
static PEL * static PEL *
make_pixel( IMAGE *out, double *p ) make_pixel( IMAGE *out, int fmt, double *p )
{ {
PEL *q; PEL *q;
int i; int i;
@ -432,7 +428,7 @@ make_pixel( IMAGE *out, double *p )
if( !(q = IM_ARRAY( out, IM_IMAGE_SIZEOF_PEL( out ), PEL )) ) if( !(q = IM_ARRAY( out, IM_IMAGE_SIZEOF_PEL( out ), PEL )) )
return( NULL ); return( NULL );
switch( out->BandFmt ) { switch( fmt ) {
case IM_BANDFMT_CHAR: CAST( signed char ); break; case IM_BANDFMT_CHAR: CAST( signed char ); break;
case IM_BANDFMT_UCHAR: CAST( unsigned char ); break; case IM_BANDFMT_UCHAR: CAST( unsigned char ); break;
case IM_BANDFMT_SHORT: CAST( signed short ); break; case IM_BANDFMT_SHORT: CAST( signed short ); break;
@ -454,14 +450,15 @@ im_and_vec( IMAGE *in, IMAGE *out, int n, double *c )
PEL *cb; PEL *cb;
invec[0] = in; invec[1] = NULL; invec[0] = in; invec[1] = NULL;
if( check( "im_andconst", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
in = invec[0]; in = invec[0];
if( n != in->Bands ) { if( n != in->Bands ) {
im_errormsg( "im_and_vec: vec size does not match bands" ); im_error( "im_and_vec",
"%s", _( "vec size does not match bands" ) );
return( -1 ); return( -1 );
} }
if( !(cb = make_pixel( out, c )) ) if( !(cb = make_pixel( out, in->BandFmt, c )) )
return( -1 ); return( -1 );
if( im_wrapone( in, out, if( im_wrapone( in, out,
@ -478,14 +475,15 @@ im_or_vec( IMAGE *in, IMAGE *out, int n, double *c )
PEL *cb; PEL *cb;
invec[0] = in; invec[1] = NULL; invec[0] = in; invec[1] = NULL;
if( check( "im_orconst", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
in = invec[0]; in = invec[0];
if( n != in->Bands ) { if( n != in->Bands ) {
im_errormsg( "im_or_vec: vec size does not match bands" ); im_error( "im_or_vec",
"%s", _( "vec size does not match bands" ) );
return( -1 ); return( -1 );
} }
if( !(cb = make_pixel( out, c )) ) if( !(cb = make_pixel( out, in->BandFmt, c )) )
return( -1 ); return( -1 );
if( im_wrapone( in, out, if( im_wrapone( in, out,
@ -502,14 +500,15 @@ im_eor_vec( IMAGE *in, IMAGE *out, int n, double *c )
PEL *cb; PEL *cb;
invec[0] = in; invec[1] = NULL; invec[0] = in; invec[1] = NULL;
if( check( "im_eorconst", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
in = invec[0]; in = invec[0];
if( n != in->Bands ) { if( n != in->Bands ) {
im_errormsg( "im_eor_vec: vec size does not match bands" ); im_error( "im_eor_vec",
"%s", _( "vec size does not match bands" ) );
return( -1 ); return( -1 );
} }
if( !(cb = make_pixel( out, c )) ) if( !(cb = make_pixel( out, in->BandFmt, c )) )
return( -1 ); return( -1 );
if( im_wrapone( in, out, if( im_wrapone( in, out,
@ -521,8 +520,7 @@ im_eor_vec( IMAGE *in, IMAGE *out, int n, double *c )
/* Cast a double to a vector of TYPE. /* Cast a double to a vector of TYPE.
*/ */
#define CCAST( TYPE ) \ #define CCAST( TYPE ) { \
{ \
TYPE *tq = (TYPE *) q; \ TYPE *tq = (TYPE *) q; \
\ \
for( i = 0; i < in->Bands; i++ ) \ for( i = 0; i < in->Bands; i++ ) \
@ -571,8 +569,7 @@ im_eorconst( IMAGE *in, IMAGE *out, double c )
/* Assorted shift operations. /* Assorted shift operations.
*/ */
#define SHIFTL( TYPE ) \ #define SHIFTL( TYPE ) { \
{\
TYPE *pt = (TYPE *) p;\ TYPE *pt = (TYPE *) p;\
TYPE *qt = (TYPE *) q;\ TYPE *qt = (TYPE *) q;\
\ \
@ -580,15 +577,6 @@ im_eorconst( IMAGE *in, IMAGE *out, double c )
qt[x] = pt[x] << n;\ qt[x] = pt[x] << n;\
} }
#define SHIFTR( 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. /* The above as buffer ops.
*/ */
static void static void
@ -598,12 +586,12 @@ shiftleft_buffer( PEL *p, PEL *q, int len, IMAGE *in, int n )
int ne = len * in->Bands; int ne = len * in->Bands;
switch( in->BandFmt ) { switch( in->BandFmt ) {
case IM_BANDFMT_UCHAR: SHIFTL(unsigned char); break; case IM_BANDFMT_UCHAR: SHIFTL( unsigned char ); break;
case IM_BANDFMT_CHAR: SHIFTL(signed char); break; case IM_BANDFMT_CHAR: SHIFTL( signed char ); break;
case IM_BANDFMT_USHORT: SHIFTL(unsigned short); break; case IM_BANDFMT_USHORT: SHIFTL( unsigned short ); break;
case IM_BANDFMT_SHORT: SHIFTL(signed short); break; case IM_BANDFMT_SHORT: SHIFTL( signed short ); break;
case IM_BANDFMT_UINT: SHIFTL(unsigned int); break; case IM_BANDFMT_UINT: SHIFTL( unsigned int ); break;
case IM_BANDFMT_INT: SHIFTL(signed int); break; case IM_BANDFMT_INT: SHIFTL( signed int ); break;
default: default:
error_exit( "im_shiftleft: internal error" ); error_exit( "im_shiftleft: internal error" );
@ -611,26 +599,6 @@ shiftleft_buffer( PEL *p, PEL *q, int len, IMAGE *in, int 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:
error_exit( "im_shiftright: internal error" );
/*NOTREACHED*/
}
}
/* The above as im_*() functions. /* The above as im_*() functions.
*/ */
int int
@ -639,7 +607,7 @@ im_shiftleft( IMAGE *in, IMAGE *out, int n )
IMAGE *invec[2]; IMAGE *invec[2];
invec[0] = in; invec[1] = NULL; invec[0] = in; invec[1] = NULL;
if( check( "im_shiftleft", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
in = invec[0]; in = invec[0];
@ -650,13 +618,41 @@ im_shiftleft( IMAGE *in, IMAGE *out, int n )
return( 0 ); 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:
error_exit( "im_shiftright: internal error" );
/*NOTREACHED*/
}
}
int int
im_shiftright( IMAGE *in, IMAGE *out, int n ) im_shiftright( IMAGE *in, IMAGE *out, int n )
{ {
IMAGE *invec[2]; IMAGE *invec[2];
invec[0] = in; invec[1] = NULL; invec[0] = in; invec[1] = NULL;
if( check( "im_shiftleft", invec, out ) ) if( check( invec, out ) )
return( -1 ); return( -1 );
in = invec[0]; in = invec[0];