/* @(#) Functions to create offsets for rotating square masks. * @(#) Usage * @(#) int *im_offsets45( size ) * @(#) int size; * @(#) * @(#) Returns an int pointer to valid offsets on sucess and -1 on error * @(#) * * @(#) Usage * @(#) int *im_offsets90( size ) * @(#) int size; * @(#) * @(#) Returns an int pointer to valid offsets on sucess and -1 on error * @(#) * * @(#) Functions to rotate square masks * @(#) * @(#) Usage * @(#) INTMASK *im_rotate_imask45( mask, name ) * @(#) INTMASK *mask; * @(#) * @(#) Returns an pointer to INTMASK which keeps the original mask rotated * @(#) by 45 degrees clockwise. * @(#) The filename member of the returned mask is set to name * @(#) * @(#) Usage * @(#) DOUBLEMASK *im_rotate_dmask45( mask, name ) * @(#) DOUBLEMASK *mask; * @(#) * @(#) Returns an pointer to INTMASK which keeps the original mask rotated * @(#) by 45 degrees clockwise. * @(#) The filename member of the returned mask is set to name * @(#) * @(#) Usage * @(#) INTMASK *im_rotate_imask90( mask, name ) * @(#) INTMASK *mask; * @(#) * @(#) Returns an pointer to INTMASK which keeps the original mask rotated * @(#) by 90 degrees clockwise. * @(#) The filename member of the returned mask is set to name * @(#) * @(#) Usage * @(#) DOUBLEMASK *im_rotate_dmask90( mask, name ) * @(#) DOUBLEMASK *mask; * @(#) * @(#) Returns an pointer to DOUBLEMASK which keeps the original mask rotated * @(#) by 90 degrees clockwise. * @(#) The filename member of the returned mask is set to name * @(#) * @(#) Prints a mask. Used mainly for debugging purposes * @(#) * @(#) Usage * @(#) void im_print_dmask( m ) * @(#) DOUBLEMASK *m; * @(#) * @(#) Usage * @(#) void im_print_imask( m ) * @(#) INTMASK *m; * @(#) * * * Author: N. Dessipris (Copyright, N. Dessipris 1991) * Written on: 08/05/1991 * Modified on: 28/05/1991 * 12/10/95 JC * - small revisions, needs rewriting really * 7/8/96 JC * - absolutely foul desp code revised * - many bugs and mem leaks fixed * 1/3/99 JC * - oops, fns were not preserving scale and offset */ /* 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 */ /* #define PIM_RINT 1 */ #ifdef HAVE_CONFIG_H #include #endif /*HAVE_CONFIG_H*/ #include #include #include #include #include #ifdef WITH_DMALLOC #include #endif /*WITH_DMALLOC*/ /* Creates the offsets to rotate by 45 degrees an odd size square mask */ int * im_offsets45( int size ) { int temp; int x, y; int size2 = size * size; int size_2 = size / 2; int *pnt, *cpnt1, *cpnt2; if( size%2 == 0 ) { im_errormsg( "im_offsets45: size not odd" ); return( NULL ); } if( !(pnt = IM_ARRAY( NULL, size2, int )) ) return( NULL ); /* point at the beginning and end of the buffer */ cpnt1 = pnt; cpnt2 = pnt + size2 - 1; for( y = 0; y < size_2; y++ ) { temp = (size_2 + y) * size; *cpnt1++ = temp; *cpnt2-- = size2 - 1 - temp; for( x = 0; x < y; x++ ) { temp -= (size-1); *cpnt1++ = temp; *cpnt2-- = size2 - 1 - temp; } for( x = 0; x < size_2 - y; x++ ) { temp -= size; *cpnt1++ = temp; *cpnt2-- = size2 - 1 - temp; } for( x = 0; x < size_2 - y; x++ ) { temp++; *cpnt1++ = temp; *cpnt2-- = size2 - 1 - temp; } for( x = 0; x < y; x++ ) { temp -= ( size - 1 ); *cpnt1++ = temp; *cpnt2-- = size2 - 1 - temp; } } /* the diagonal now */ temp = size * (size - 1); cpnt1 = pnt + size_2 * size; for( x = 0; x < size; x++ ) { *cpnt1++ = temp; temp -= (size-1); } #ifdef PIM_RINT temp = 0; for( y = 0; y < size; y++ ) { for( x = 0; x < size; x++ ) { fprintf( stderr, "%4d", *(pnt+temp) ); temp++; } fprintf(stderr, "\n"); } fprintf(stderr, "\n"); #endif return( pnt ); } /* Creates the offsets to rotate any mask by 90 degrees. */ int * im_offsets90( int size ) { int temp; int x, y, k; int *offsets; if( !(offsets = IM_ARRAY( NULL, size*size, int )) ) return( NULL ); for( k = 0, y = 0; y < size; y++ ) { temp = size * (size - 1) + y; for( x = 0; x < size; x++, k++ ) { offsets[k] = temp; temp -= size; } } return( offsets ); } /* Tye pf offset-generating function. */ typedef int *(*offset_fn)( int ); /* Rotate a dmask with a set of offsets. */ static DOUBLEMASK * rotdmask( offset_fn fn, DOUBLEMASK *m, const char *name ) { DOUBLEMASK *out; int size = m->xsize * m->ysize; int *offsets; int i; if( m->xsize != m->ysize || (m->xsize % 2) == 0 ) { im_errormsg( "im_rotate_*mask*: mask should " "be square of even size" ); return( NULL ); } if( !(offsets = fn( m->xsize )) ) return( NULL ); if( !(out = im_create_dmask( name, m->xsize, m->ysize )) ) { im_free( offsets ); return( NULL ); } out->scale = m->scale; out->offset = m->offset; for( i = 0; i < size; i++ ) out->coeff[i] = m->coeff[offsets[i]]; im_free( offsets ); return( out ); } /* Rotate an imask with a set of offsets. */ static INTMASK * rotimask( offset_fn fn, INTMASK *m, const char *name ) { INTMASK *out; int size = m->xsize * m->ysize; int *offsets; int i; if( m->xsize != m->ysize || (m->xsize % 2) == 0 ) { im_errormsg( "im_rotate_*mask*: mask should " "be square of even size" ); return( NULL ); } if( !(offsets = fn( m->xsize )) ) return( NULL ); if( !(out = im_create_imask( name, m->xsize, m->ysize )) ) { im_free( offsets ); return( NULL ); } out->scale = m->scale; out->offset = m->offset; for( i = 0; i < size; i++ ) out->coeff[i] = m->coeff[offsets[i]]; im_free( offsets ); return( out ); } /* Returns a mask which is the argument mask rotated by 90 degrees. Filename * of the returned mask is name. */ DOUBLEMASK * im_rotate_dmask90( DOUBLEMASK *m, const char *name ) { return( rotdmask( im_offsets90, m, name ) ); } /* Returns a mask which is the argument mask rotated by 45 degrees. Filename * of the returned mask is name. */ DOUBLEMASK * im_rotate_dmask45( DOUBLEMASK *m, const char *name ) { return( rotdmask( im_offsets45, m, name ) ); } /* Returns a mask which is the argument mask rotated by 90 degrees. Filename * of the returned mask is name. */ INTMASK * im_rotate_imask90( INTMASK *m, const char *name ) { return( rotimask( im_offsets90, m, name ) ); } /* Returns a mask which is the argument mask rotated by 45 degrees. Filename * of the returned mask is name. */ INTMASK * im_rotate_imask45( INTMASK *m, const char *name ) { return( rotimask( im_offsets45, m, name ) ); } void im_print_imask( INTMASK *m ) { int i, j, k; int *pm = m->coeff; fprintf( stderr, " %s: %d %d %d %d\n", m->filename, m->xsize, m->ysize, m->scale, m->offset ); for( k = 0, j = 0; j < m->ysize; j++ ) { for( i = 0; i < m->xsize; i++, k++ ) fprintf( stderr, "%d\t", pm[k] ); fprintf( stderr, "\n" ); } } void im_print_dmask( DOUBLEMASK *m ) { int i, j, k; double *pm = m->coeff; fprintf( stderr, " %s: %d %d %f %f\n", m->filename, m->xsize, m->ysize, m->scale, m->offset ); for( k = 0, j = 0; j < m->ysize; j++ ) { for( i = 0; i < m->xsize; i++, k++ ) fprintf( stderr, "%f\t", pm[k] ); fprintf( stderr, "\n" ); } }