/* @(#) Function which changes the spatial resolution of an image according to * @(#) step * @(#) * @(#) int im_spatres(in, out, step) * @(#) IMAGE *in, *out; * @(#) int step; * @(#) Returns either 0 (sucess) or -1 (fail) * @(#) * @(#) Picture can have any number of channels (max 64). * * Copyright: 1990, N. Dessipris. * * Author: Nicos Dessipris * Written on: 08/11/1989. * Modified on: 19/01/1990. */ /* 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*/ int im_spatres( IMAGE *in, IMAGE *out, int step ) { int x, y; /* horizontal and vertical direction */ int z; /* 0 <= z < channel */ int i, j; int rounding, step2, sum; unsigned char *values; unsigned char *input, *cpinput, *cp2input, *line, *cpline, *pnt, *cpnt; int os; /* Check args */ if ( step < 1 ) {im_errormsg("im_spatres: Invalid step %d\n", step);return(-1);} if ( (in->Xsize/step == 0)||(in->Ysize/step == 0) ) {im_errormsg("im_spatres: Invalid step %d\n", step);return(-1);} if (im_iocheck(in, out) == -1) { im_errormsg("im_spatres: im_iocheck failed"); return(-1); } if((in->Coding != IM_CODING_NONE)||(in->Bbits != 8)||(in->BandFmt !=IM_BANDFMT_UCHAR)) { im_errormsg("im_spatres: wrong input"); return(-1); } /* Prepare output */ if (im_cp_desc(out, in) == -1) { im_errormsg("im_spatres: im_cp_desc failed"); return(-1); } out->Xsize = in->Xsize - in->Xsize%step; out->Ysize = in->Ysize - in->Ysize%step; if( im_setupout(out) == -1) { im_errormsg("im_spatres: im_setupout failed"); return(-1); } /* Malloc buffer for one 'line' of input data */ os = in->Xsize * in->Bands; line = (unsigned char *)calloc((unsigned)os, sizeof(char)); /* Malloc space for values */ values = (unsigned char *)calloc((unsigned)out->Bands, sizeof(char)); if ( line == NULL || values == NULL ) { im_errormsg("im_spatres: calloc failed"); return(-1); } step2 = step * step; rounding = step2/2; input = (unsigned char *)in->data; for ( y = 0; y < out->Ysize; y += step ) { cpinput = input; input += os * step; /* do the x loop out->Xsize / step times */ cpline = line; for (x = 0; x < out->Xsize; x += step) { cp2input = cpinput; cpinput += step * out->Bands; /* ??? */ for ( z = 0; z < out->Bands; z++ ) { pnt = cp2input + z; sum = 0; for ( j = 0; j < step; j++ ) { cpnt = pnt; pnt += os; for ( i = 0; i < step; i++ ) { sum += (int)*cpnt; cpnt += out->Bands; } } *(values + z) = (PEL)((sum + rounding)/step2); } /* for this x, write step*bands data */ for ( j = 0; j < step; j++ ) for ( z = 0; z < out->Bands; z++ ) *cpline++ = *(values + z); } /* line is now ready. Write now step lines */ for (j = 0; j < step; j++) if ( im_writeline ( y+j, out, (PEL *)line ) == -1 ) { im_errormsg("im_spatres: im_writeline failed"); free ( (char *)line ); free ( (char *)values ); return( -1 ); } } /* end of the for (..y..) loop */ free ( (char *)line ); free ( (char *)values ); return(0); }