| /* @(#) 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 <config.h> |
| #endif /*HAVE_CONFIG_H*/ |
| #include <vips/intl.h> |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <math.h> |
| |
| #include <vips/vips.h> |
| |
| #ifdef WITH_DMALLOC |
| #include <dmalloc.h> |
| #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_error( "im_spatres", _( "Invalid step %d" ), step ); |
| return(-1);} |
| |
| if ( (in->Xsize/step == 0)||(in->Ysize/step == 0) ) |
| {im_error("im_spatres", _( "Invalid step %d" ), step);return(-1);} |
| |
| if (im_iocheck(in, out) == -1) |
| return( -1 ); |
| |
| if((in->Coding != IM_CODING_NONE)||(in->BandFmt !=IM_BANDFMT_UCHAR)) { |
| im_error( "im_spatres", "%s", _( "wrong input") ); |
| return(-1); } |
| |
| /* Prepare output */ |
| if (im_cp_desc(out, in) == -1) |
| return( -1 ); |
| out->Xsize = in->Xsize - in->Xsize%step; |
| out->Ysize = in->Ysize - in->Ysize%step; |
| |
| if( im_setupout(out) == -1) |
| 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_error( "im_spatres", "%s", _( "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 ) |
| { |
| free ( (char *)line ); free ( (char *)values ); |
| return( -1 ); |
| } |
| } /* end of the for (..y..) loop */ |
| |
| free ( (char *)line ); free ( (char *)values ); |
| return(0); |
| } |