im_rint(), im_sign() done

This commit is contained in:
John Cupitt 2009-09-09 09:54:02 +00:00
parent 1c8434e51b
commit f705d28a66
5 changed files with 86 additions and 84 deletions

View File

@ -224,7 +224,8 @@ abs_gen( PEL *in, PEL *out, int width, IMAGE *im )
int
im_abs( IMAGE *in, IMAGE *out )
{
if( im_check_uncoded( "im_abs", in ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_abs", in ) )
return( -1 );
/* Is this one of the unsigned types? Degenerate to im_copy() if it

View File

@ -100,7 +100,8 @@ ceil_gen( PEL *in, PEL *out, int width, IMAGE *im )
int
im_ceil( IMAGE *in, IMAGE *out )
{
if( im_check_uncoded( "im_ceil", in ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_ceil", in ) )
return( -1 );
/* Is this one of the int types? Degenerate to im_copy() if it

View File

@ -111,7 +111,8 @@ floor_gen( PEL *in, PEL *out, int width, IMAGE *im )
int
im_floor( IMAGE *in, IMAGE *out )
{
if( im_check_uncoded( "im_floor", in ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_floor", in ) )
return( -1 );
/* Is this one of the int types? Degenerate to im_copy() if it

View File

@ -1,14 +1,9 @@
/* @(#) rint() an image ... no promotion, so output type == input type
* @(#)
* @(#) int
* @(#) im_rint( in, out )
* @(#) IMAGE *in, *out;
* @(#)
* @(#) Returns 0 on success and -1 on error
* @(#)
/* im_rint.c
*
* 20/6/02 JC
* - adapted from im_floor()
* 9/9/09
* - updated from new im_floor()
*/
/*
@ -53,45 +48,63 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
#define rint_loop(TYPE)\
{\
TYPE *p = (TYPE *) in;\
TYPE *q = (TYPE *) out;\
\
for( x = 0; x < sz; x++ )\
q[x] = IM_RINT( p[x] );\
}
#define RINT( TYPE ) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
\
for( x = 0; x < sz; x++ ) \
q[x] = IM_RINT( p[x] );\
}
/* rint a buffer of PELs.
/* RINT a buffer of PELs.
*/
static void
rint_gen( PEL *in, PEL *out, int width, IMAGE *im )
{
/* Complex just doubles the size.
*/
const int sz = width * im->Bands * (im_iscomplex( im ) ? 2 : 1);
int x;
int sz = width * im->Bands;
switch( im->BandFmt ) {
case IM_BANDFMT_FLOAT: rint_loop(float); break;
case IM_BANDFMT_DOUBLE: rint_loop(double); break;
case IM_BANDFMT_COMPLEX: sz *= 2; rint_loop(float); break;
case IM_BANDFMT_DPCOMPLEX: sz *= 2; rint_loop(double); break;
case IM_BANDFMT_COMPLEX:
case IM_BANDFMT_FLOAT:
RINT( float );
break;
case IM_BANDFMT_DOUBLE:
case IM_BANDFMT_DPCOMPLEX:
RINT( double );
break;
default:
assert( 0 );
g_assert( 0 );
}
}
/* rint of image.
/**
* im_rint:
* @in: input #IMAGE
* @out: output #IMAGE
*
* Finds the nearest integral value. Copy for integer types,
* call IM_RINT() for float and complex types. Output type == input type.
*
* IM_RINT() is a pseudo-round-to-nearest. It is much faster than
* <function>rint</function>(3), but does not give the same result for
* negative integral values.
*
* See also: im_ceil(), im_floor(), im_clip2fmt()
*
* Returns: 0 on success, -1 on error
*/
int
im_rint( IMAGE *in, IMAGE *out )
{
/* Check args.
*/
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_rint", "%s", _( "not uncoded" ) );
{
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_rint", in ) )
return( -1 );
}
/* Is this one of the int types? Degenerate to im_copy() if it
* is.

View File

@ -1,13 +1,9 @@
/* @(#) Find the unit vector in the direction of the pixel.
* @(#)
* @(#) int im_sign(in, out)
* @(#) IMAGE *in, *out;
* @(#)
* @(#) Returns 0 on success and -1 on error
* @(#)
/* im_sign.c
*
* 9/7/02 JC
* - from im_cmulnorm
* 9/9/09
* - gtkdoc, tidies
*/
/*
@ -52,8 +48,7 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
#define sign_complex( IN, OUT ) \
{ \
#define CSIGN( IN, OUT ) { \
IN *p = (IN *) in; \
OUT *q = (OUT *) out; \
int x; \
@ -78,8 +73,7 @@
} \
}
#define sign( IN, OUT ) \
{ \
#define SIGN( IN, OUT ) { \
IN *p = (IN *) in; \
OUT *q = (OUT *) out; \
int x; \
@ -99,63 +93,55 @@
/* sign buffer processor.
*/
static void
buffer_sign( void *in, void *out, int w, IMAGE *im )
sign_gen( void *in, void *out, int w, IMAGE *im )
{
int n = w * im->Bands;
switch( im->BandFmt ) {
case IM_BANDFMT_UCHAR:
sign( unsigned char, signed char );
break;
case IM_BANDFMT_CHAR:
sign( signed char, signed char );
break;
case IM_BANDFMT_USHORT:
sign( unsigned short, signed char );
break;
case IM_BANDFMT_SHORT:
sign( signed short, signed char );
break;
case IM_BANDFMT_UINT:
sign( unsigned int, signed char );
break;
case IM_BANDFMT_INT:
sign( signed int, signed char );
break;
case IM_BANDFMT_FLOAT:
sign( float, signed char );
break;
case IM_BANDFMT_DOUBLE:
sign( double, signed char );
break;
case IM_BANDFMT_COMPLEX:
sign_complex( float, float );
break;
case IM_BANDFMT_DPCOMPLEX:
sign_complex( double, double );
break;
case IM_BANDFMT_UCHAR: SIGN( unsigned char, signed char ); break;
case IM_BANDFMT_CHAR: SIGN( signed char, signed char ); break;
case IM_BANDFMT_USHORT: SIGN( unsigned short, signed char ); break;
case IM_BANDFMT_SHORT: SIGN( signed short, signed char ); break;
case IM_BANDFMT_UINT: SIGN( unsigned int, signed char ); break;
case IM_BANDFMT_INT: SIGN( signed int, signed char ); break;
case IM_BANDFMT_FLOAT: SIGN( float, signed char ); break;
case IM_BANDFMT_DOUBLE: SIGN( double, signed char ); break;
case IM_BANDFMT_COMPLEX: CSIGN( float, float ); break;
case IM_BANDFMT_DPCOMPLEX: CSIGN( double, double ); break;
default:
assert( 0 );
g_assert( 0 );
}
}
/**
* im_sign:
* @in: input image
* @out: output image
*
* Finds the unit vector in the direction of the pixel value. For non-complex
* images, it returns a signed char image with values -1, 0, and 1 for negative,
* zero and positive pixels. For complex images, it returns a
* complex normalised to length 1.
*
* See also: im_abs(), im_cmulnorm(), im_c2amph().
*
* Returns: 0 on success, -1 on error
*/
int
im_sign( IMAGE *in, IMAGE *out )
{
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_sign", "%s", _( "not uncoded" ) );
return( -1 );
}
if( im_cp_desc( out, in ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_sign", in ) ||
im_cp_desc( out, in ) )
return( -1 );
if( !im_iscomplex( in ) ) {
out->Bbits = IM_BBITS_BYTE;
out->BandFmt = IM_BANDFMT_CHAR;
}
/* Do the processing.
*/
if( im_wrapone( in, out, (im_wrapone_fn) buffer_sign, in, NULL ) )
if( im_wrapone( in, out, (im_wrapone_fn) sign_gen, in, NULL ) )
return( -1 );
return( 0 );