/* im_lowpass() * History: * 27/10/94 JC * - IM_ARRAY modified to use local allocation * - im_iscomplex() call added * 17/2/95 JC * - modernised a little * 18/8/95 JC * - name changed to reflect function more closely * 2/6/04 * - was detecting edges incorrectly, segv for some images (thanks Javi) */ /* This file is part of VIPS. VIPS is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk */ #ifdef HAVE_CONFIG_H #include #endif /*HAVE_CONFIG_H*/ #include #include #include #include #include #ifdef WITH_DMALLOC #include #endif /*WITH_DMALLOC*/ /* What we do for each pel. */ #define LOOP( TYPE ) \ if( Xint >= 0 && Yint >=0 && \ Xint < in->Xsize-1 && Yint < in->Ysize-1 ) \ for( bb = 0; bb < in->Bands; bb++ ) { \ TYPE s1 = *((TYPE *) p); \ TYPE s2 = *((TYPE *) (p + ips)); \ TYPE s3 = *((TYPE *) (p + ils)); \ TYPE s4 = *((TYPE *) (p + ips + ils)); \ TYPE *t = (TYPE *) q; \ \ *t = (1-dx)*(1-dy)*s1 + dx*(1-dy)*s2 + \ dy*(1-dx)*s3 + dx*dy*s4; \ \ p += ies; \ q += oes; \ } \ else if( Xint == in->Xsize-1 && Yint >= 0 && Yint < in->Ysize - 1 ) \ for( bb = 0; bb < in->Bands; bb++ ) { \ TYPE s1 = *((TYPE *) p); \ TYPE s3 = *((TYPE *) (p + ils)); \ TYPE *t = (TYPE *) q; \ \ *t = (1-dy)*s1 + dy*s3; \ \ p += ies; \ q += oes; \ } \ else if( Yint == in->Ysize-1 && Xint >= 0 && Xint < in->Xsize - 1 ) \ for( bb = 0; bb < in->Bands; bb++ ) { \ TYPE s1 = *((TYPE *) p); \ TYPE s2 = *((TYPE *) (p + ips)); \ TYPE *t = (TYPE *) q; \ \ *t = (1-dx)*s1 + dx*s2; \ \ p += ies; \ q += oes; \ } \ else \ for( bb = 0; bb < in->Bands; bb++ ) { \ unsigned char s1 = *((unsigned char *) p); \ TYPE *t = (TYPE *) q; \ \ *t = s1; \ \ p += ies; \ q += oes; \ } int im_resize_linear( IMAGE *in, IMAGE *out, int X, int Y ) { double dx, dy, xscale, yscale; double Xnew, Ynew; /* inv. coord. of the interpolated pt */ int x, y; int Xint, Yint; int bb; PEL *input, *opline; PEL *q, *p; int ils, ips, ies; /* Input and output line, pel and */ int ols, ops, oes; /* element sizes */ if( im_iocheck( in, out ) ) return( -1 ); if( im_iscomplex( in ) ) { im_errormsg( "im_lowpass: non-complex input only" ); return( -1 ); } if( in->Coding != IM_CODING_NONE ) { im_errormsg("im_lowpass: input should be uncoded"); return( -1 ); } if( im_cp_desc( out, in ) ) return( -1 ); out->Xsize = X; out->Ysize = Y; if( im_setupout( out ) ) return( -1 ); ils = IM_IMAGE_SIZEOF_LINE( in ); ips = IM_IMAGE_SIZEOF_PEL( in ); ies = IM_IMAGE_SIZEOF_ELEMENT( in ); ols = IM_IMAGE_SIZEOF_LINE( out ); ops = IM_IMAGE_SIZEOF_PEL( out ); oes = IM_IMAGE_SIZEOF_ELEMENT( out ); /* buffer lines ***************/ if( !(opline = IM_ARRAY( out, ols, PEL )) ) return( -1 ); /* Resampling *************/ input = (PEL*) in->data; xscale = ((double)in->Xsize-1)/(X-1); yscale = ((double)in->Ysize-1)/(Y-1); for (y=0; yBandFmt ) { case IM_BANDFMT_UCHAR: LOOP( unsigned char); break; case IM_BANDFMT_USHORT: LOOP( unsigned short ); break; case IM_BANDFMT_UINT: LOOP( unsigned int ); break; case IM_BANDFMT_CHAR: LOOP( signed char ); break; case IM_BANDFMT_SHORT: LOOP( signed short ); break; case IM_BANDFMT_INT: LOOP( signed int ); break; case IM_BANDFMT_FLOAT: LOOP( float ); break; case IM_BANDFMT_DOUBLE: LOOP( double ); break; default: im_errormsg( "im_lowpass: unsupported image type" ); return( -1 ); /*NOTREACHED*/ } } if (im_writeline(y, out, opline) ) return(-1); } return(0); }