This commit is contained in:
John Cupitt 2009-08-01 09:54:45 +00:00
parent 350b0f92b4
commit 856b272259
15 changed files with 248 additions and 200 deletions

View File

@ -11,6 +11,7 @@
(thank you Ole)
- im_buildlut() could segv for non-zero based tables (thanks Jack)
- VIPS_BUF_STATIC() does not take length arg
- add and use im_check_uncoded() and friends
25/3/09 started 7.18.0
- revised version numbers

25
TODO
View File

@ -1,3 +1,28 @@
- make some check functions like
int
im_check_isuncoded( IMAGE *im )
{
if( im->Coding != IM_CODING_NONE ) {
im_error( "im_check_isuncoded", "%s",
_( "image should be uncoded" ) );
return( -1 )
}
return( 0 );
}
then operations can start with
if( im_check_isuncoded( in ) ||
im_check_isuchar( in ) ||
im_check_ismono( in ) )
return( -1 );
reached im_expntra() in arith
- 1-bit PNG readis broken?
> The bug is that 1bit depth PNG addresses are incorrectly interpreted. At

View File

@ -138,6 +138,15 @@ int im_amiMSBfirst( void );
int im_ispoweroftwo( int );
int im_check_uncoded( const char *domain, IMAGE *im );
int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_noncomplex( const char *domain, IMAGE *im );
int im_check_complex( const char *domain, IMAGE *im );
int im_check_size( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_bands( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_format( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_vector( const char *domain, int n, IMAGE *im );
int im_existsf( const char *name, ... )
__attribute__((format(printf, 1, 2)));
int im_isvips( const char * );

View File

@ -26,6 +26,8 @@
* - tiny speed up
* 8/12/06
* - add liboil support
* 29/7/09
* - small cleanups and speedups
*/
/*
@ -77,73 +79,77 @@
/* Integer abs operation: just test and negate.
*/
#define intabs(TYPE) \
{ \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
int x; \
#define intabs( TYPE ) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
int x; \
\
for( x = 0; x < sz; x++ ) { \
TYPE v = p[x]; \
\
for( x = 0; x < sz; x++ ) { \
TYPE v = p[x]; \
\
if( v < 0 ) \
q[x] = 0 - v; \
else \
q[x] = v; \
} \
}
if( v < 0 ) \
q[x] = 0 - v; \
else \
q[x] = v; \
} \
}
/* Float abs operation: call fabs().
*/
#define floatabs(TYPE)\
{\
TYPE *p = (TYPE *) in;\
TYPE *q = (TYPE *) out;\
int x; \
\
for( x = 0; x < sz; x++ )\
q[x] = fabs( p[x] );\
}
#define floatabs( TYPE ) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
int x; \
\
for( x = 0; x < sz; x++ ) \
q[x] = fabs( p[x] ); \
}
/* Complex abs operation: calculate modulus.
*/
#ifdef HAVE_HYPOT
#define complexabs(TYPE) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
int i; \
\
for( i = 0; i < sz; i++ ) { \
q[i] = hypot( p[0], p[1] ); \
p += 2; \
} \
}
#define complexabs( TYPE ) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
int i; \
\
for( i = 0; i < sz; i++ ) { \
q[i] = hypot( p[0], p[1] ); \
p += 2; \
} \
}
#else /*HAVE_HYPOT*/
#define complexabs(TYPE) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
TYPE *q_stop = q + sz; \
\
while( q < q_stop ){ \
double rp = *p++; \
double ip = *p++; \
double abs_rp= fabs( rp ); \
double abs_ip= fabs( ip ); \
\
if( abs_rp > abs_ip ){ \
double temp= ip / rp; \
*q++= abs_rp * sqrt( 1.0 + temp * temp ); \
} \
else { \
double temp= rp / ip; \
*q++= abs_ip * sqrt( 1.0 + temp * temp ); \
} \
} \
}
#define complexabs( TYPE ) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
int i; \
\
for( i = 0; i < sz; i++ ) { \
double rp = p[0]; \
double ip = p[1]; \
double abs_rp = fabs( rp ); \
double abs_ip = fabs( ip ); \
double result;
\
if( abs_rp > abs_ip ) { \
double temp = ip / rp; \
\
result = abs_rp * sqrt( 1.0 + temp * temp ); \
} \
else { \
double temp = rp / ip; \
\
result = abs_ip * sqrt( 1.0 + temp * temp ); \
} \
\
p += 2; \
q[i] = result; \
} \
}
#endif /*HAVE_HYPOT*/
@ -154,8 +160,6 @@ abs_gen( PEL *in, PEL *out, int width, IMAGE *im )
{
int sz = width * im->Bands;
/* Abs all input types.
*/
switch( im->BandFmt ) {
case IM_BANDFMT_CHAR:
#ifdef HAVE_LIBOIL
@ -214,13 +218,9 @@ abs_gen( PEL *in, PEL *out, int width, IMAGE *im )
*/
int
im_abs( IMAGE *in, IMAGE *out )
{
/* Check args.
*/
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_abs", "%s", _( "not uncoded" ) );
{
if( im_check_uncoded( "im_abs", in ) )
return( -1 );
}
/* Is this one of the unsigned types? Degenerate to im_copy() if it
* is.
@ -233,16 +233,8 @@ im_abs( IMAGE *in, IMAGE *out )
*/
if( im_cp_desc( out, in ) )
return( -1 );
switch( in->BandFmt ) {
case IM_BANDFMT_CHAR:
case IM_BANDFMT_SHORT:
case IM_BANDFMT_INT:
case IM_BANDFMT_FLOAT:
case IM_BANDFMT_DOUBLE:
/* No action.
*/
break;
switch( in->BandFmt ) {
case IM_BANDFMT_COMPLEX:
out->Bbits = IM_BBITS_FLOAT;
out->BandFmt = IM_BANDFMT_FLOAT;
@ -254,14 +246,10 @@ im_abs( IMAGE *in, IMAGE *out )
break;
default:
im_error( "im_abs", "%s", _( "unknown input type" ) );
return( -1 );
break;
}
/* Generate!
*/
if( im_wrapone( in, out,
(im_wrapone_fn) abs_gen, in, NULL ) )
if( im_wrapone( in, out, (im_wrapone_fn) abs_gen, in, NULL ) )
return( -1 );
return( 0 );

View File

@ -241,20 +241,14 @@ im__cast_and_call( IMAGE *in1, IMAGE *in2, IMAGE *out,
int
im_add( 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_add", in1, in2 ) ||
im_check_uncoded( "im_add", in1 ) ||
im_check_uncoded( "im_add", in2 ) )
return( -1 );
if( in1->Bands != in2->Bands &&
(in1->Bands != 1 && in2->Bands != 1) ) {
im_error( "im_add", "%s", _( "not same number of bands" ) );
return( -1 );
}
if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) {
im_error( "im_add", "%s", _( "not uncoded" ) );
return( -1 );
}
if( im_cp_descv( out, in1, in2, NULL ) )
return( -1 );

View File

@ -181,16 +181,10 @@ im_avg( IMAGE *in, double *out )
/* Check our args.
*/
if( im_pincheck( in ) )
if( im_pincheck( in ) ||
im_check_noncomplex( "im_avg", in ) ||
im_check_uncoded( "im_avg", in ) )
return( -1 );
if( im_iscomplex( in ) ) {
im_error( "im_avg", "%s", _( "bad input type" ) );
return( -1 );
}
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_avg", "%s", _( "not uncoded" ) );
return( -1 );
}
/* Loop over input, summing pixels.
*/

View File

@ -123,8 +123,8 @@ 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:CLOOP( float ); break;
case IM_BANDFMT_DPCOMPLEX:CLOOP( double ); break;
default:
assert( 0 );
@ -134,24 +134,16 @@ bandmean_buffer( PEL *p, PEL *q, int n, IMAGE *in )
int
im_bandmean( IMAGE *in, IMAGE *out )
{
/* Check input params
*/
if( in->Bands == 1 )
return( im_copy( in, out ) );
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_bandmean", "%s", _( "uncoded multiband only" ) );
if( im_check_uncoded( "im_bandmean", in ) )
return( -1 );
}
/* Prepare output image.
*/
if( im_cp_desc( out, in ) )
return( -1 );
out->Bands = 1;
out->Type = IM_TYPE_B_W;
/* And process!
*/
if( im_wrapone( in, out,
(im_wrapone_fn) bandmean_buffer, in, NULL ) )
return( -1 );

View File

@ -53,14 +53,13 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
#define ceil_loop(TYPE)\
{\
TYPE *p = (TYPE *) in;\
TYPE *q = (TYPE *) out;\
\
for( x = 0; x < sz; x++ )\
q[x] = ceil( p[x] );\
}
#define ceil_loop( TYPE ) { \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
\
for( x = 0; x < sz; x++ ) \
q[x] = ceil( p[x] ); \
}
/* Ceil a buffer of PELs.
*/
@ -85,13 +84,9 @@ ceil_gen( PEL *in, PEL *out, int width, IMAGE *im )
*/
int
im_ceil( IMAGE *in, IMAGE *out )
{
/* Check args.
*/
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_ceil", "%s", _( "not uncoded" ) );
{
if( im_check_uncoded( "im_ceil", in ) )
return( -1 );
}
/* Is this one of the int types? Degenerate to im_copy() if it
* is.
@ -106,8 +101,7 @@ im_ceil( IMAGE *in, IMAGE *out )
/* Generate!
*/
if( im_wrapone( in, out,
(im_wrapone_fn) ceil_gen, in, NULL ) )
if( im_wrapone( in, out, (im_wrapone_fn) ceil_gen, in, NULL ) )
return( -1 );
return( 0 );

View File

@ -111,16 +111,10 @@ im_costra( IMAGE *in, IMAGE *out )
{
/* Check args.
*/
if( im_piocheck( in, out ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_costra", in ) ||
im_check_noncomplex( "im_costra", in ) )
return( -1 );
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_costra", "%s", _( "not uncoded" ) );
return( -1 );
}
if( im_iscomplex( in ) ) {
im_error( "im_costra", "%s", _( "bad input type" ) );
return( -1 );
}
/* Prepare output header.
*/
@ -196,16 +190,10 @@ im_acostra( IMAGE *in, IMAGE *out )
{
/* Check args.
*/
if( im_piocheck( in, out ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_acostra", in ) ||
im_check_noncomplex( "im_acostra", in ) )
return( -1 );
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_acostra", "%s", _( "not uncoded" ) );
return( -1 );
}
if( im_iscomplex( in ) ) {
im_error( "im_acostra", "%s", _( "bad input type" ) );
return( -1 );
}
/* Prepare output header.
*/

View File

@ -133,26 +133,15 @@ int im_cross_phase( IMAGE *a, IMAGE *b, IMAGE *out ){
if( im_pincheck( a ) || im_pincheck( b ) || im_poutcheck( out ))
return -1;
if( a-> Xsize != b-> Xsize || a-> Ysize != b-> Ysize ){
im_error( FUNCTION_NAME, "not same size" );
if( im_check_size( FUNCTION_NAME, a, b ) ||
im_check_bands( FUNCTION_NAME, a, b ) ||
im_check_uncoded( FUNCTION_NAME, a ) ||
im_check_uncoded( FUNCTION_NAME, b ) ||
im_check_format( FUNCTION_NAME, a, b ) ||
im_check_complex( FUNCTION_NAME, a ) ||
im_check_complex( FUNCTION_NAME, b ) )
return -1;
}
if( a-> Bands != b-> Bands ){
im_error( FUNCTION_NAME, "numbers of bands differ" );
return -1;
}
if( a-> Coding || b-> Coding ){
im_error( FUNCTION_NAME, "not uncoded" );
return -1;
}
if( a-> BandFmt != b-> BandFmt ){
im_error( FUNCTION_NAME, "formats differ" );
return -1;
}
if( IM_BANDFMT_COMPLEX != a-> BandFmt && IM_BANDFMT_DPCOMPLEX != a-> BandFmt ){
im_error( FUNCTION_NAME, "not complex format" );
return -1;
}
return im_cp_descv( out, a, b, NULL ) || im_wraptwo( a, b, out,
IM_BANDFMT_COMPLEX == a-> BandFmt ? complex_phase_float : complex_phase_double, a, NULL );
}

View File

@ -193,16 +193,10 @@ im_deviate( IMAGE *in, double *out )
/* Check our args.
*/
if( im_pincheck( in ) )
if( im_pincheck( in ) ||
im_check_uncoded( "im_deviate", in ) ||
im_check_noncomplex( "im_deviate", in ) )
return( -1 );
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_deviate", "%s", _( "not uncoded" ) );
return( -1 );
}
if( im_iscomplex( in ) ) {
im_error( "im_deviate", "%s", _( "bad input type" ) );
return( -1 );
}
/* Loop over input, summing pixels.
*/
@ -211,9 +205,9 @@ im_deviate( IMAGE *in, double *out )
/*
NOTE: NR suggests a two-pass algorithm to minimise roundoff.
But that's too expensive for us :-( so do it the old one-pass
way.
NOTE: NR suggests a two-pass algorithm to minimise roundoff.
But that's too expensive for us :-( so do it the old one-pass
way.
*/

View File

@ -173,19 +173,12 @@ divide_buffer( PEL **in, PEL *out, int width, IMAGE *im )
int
im_divide( 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_divide", in1, in2 ) ||
im_check_uncoded( "im_divide", in1 ) ||
im_check_uncoded( "im_divide", in2 ) )
return( -1 );
if( in1->Bands != in2->Bands &&
(in1->Bands != 1 && in2->Bands != 1) ) {
im_error( "im_divide", "%s", _( "not same number of bands" ) );
return( -1 );
}
if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) {
im_error( "im_divide", "%s", _( "not uncoded" ) );
return( -1 );
}
if( im_cp_descv( out, in1, in2, NULL ) )
return( -1 );

View File

@ -180,19 +180,10 @@ im_expntra_vec( IMAGE *in, IMAGE *out, int n, double *e )
/* Check args.
*/
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_expntra_vec", "%s", _( "not uncoded" ) );
if( im_check_uncoded( "im_expntra_vec", in ) ||
im_check_noncomplex( "im_expntra_vec", in ) ||
im_check_vector( "im_expntra_vec", n, in ) )
return( -1 );
}
if( im_iscomplex( in ) ) {
im_error( "im_expntra_vec", "%s", _( "not non-complex" ) );
return( -1 );
}
if( n != 1 && n != in->Bands ) {
im_error( "im_expntra_vec",
_( "not 1 or %d elements in vector" ), in->Bands );
return( -1 );
}
/* Prepare output header.
*/

View File

@ -26,6 +26,8 @@
* - cleanups
* 22/5/08
* - image format stuff broken out
* 29/7/09
* - check funcs added
*/
/*
@ -356,3 +358,97 @@ im_isvips( const char *filename )
return( 0 );
}
int
im_check_uncoded( const char *domain, IMAGE *im )
{
if( im->Coding != IM_CODING_NONE ) {
im_error( domain, "%s", _( "image must be uncoded" ) );
return( -1 );
}
return( 0 );
}
int
im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 )
{
if( im1->Bands != im2->Bands &&
(im1->Bands != 1 && im2->Bands != 1) ) {
im_error( domain, "%s",
_( "images must have the same number of bands, "
"or one muct be single-band" ) );
return( -1 );
}
return( 0 );
}
int
im_check_noncomplex( const char *domain, IMAGE *im )
{
if( im_iscomplex( im ) ) {
im_error( domain, "%s", _( "image must be non-complex" ) );
return( -1 );
}
return( 0 );
}
int
im_check_complex( const char *domain, IMAGE *im )
{
if( !im_iscomplex( im ) ) {
im_error( domain, "%s", _( "image must be complex" ) );
return( -1 );
}
return( 0 );
}
int
im_check_size( const char *domain, IMAGE *im1, IMAGE *im2 )
{
if( im1->Xsize != im2->Xsize || im1->Ysize != im2->Ysize ) {
im_error( domain, "%s", _( "images must match in size" ) );
return( -1 );
}
return( 0 );
}
int
im_check_bands( const char *domain, IMAGE *im1, IMAGE *im2 )
{
if( im1->Bands != im2->Bands ) {
im_error( domain, "%s",
_( "images must have the same number of bands" ) );
return( -1 );
}
return( 0 );
}
int
im_check_format( const char *domain, IMAGE *im1, IMAGE *im2 )
{
if( im1->BandFmt != im2->BandFmt ) {
im_error( domain, "%s",
_( "images must have the same band format" ) );
return( -1 );
}
return( 0 );
}
int
im_check_vector( const char *domain, int n, IMAGE *im )
{
if( n != 1 && n != im->Bands ) {
im_error( domain,
_( "vector must have 1 or %d elements" ), im->Bands );
return( -1 );
}
return( 0 );
}

View File

@ -315,7 +315,7 @@ nohalo1( const double uno_two,
* absolute value) is taken to be the corresponding slope; if the
* two consecutive pixel value differences don't have the same sign,
* the corresponding slope is set to 0. In other words, apply minmod
* to comsecutive differences.
* to consecutive differences.
*/
/*
* Dos(s) horizontal differences: