/* Transform a rect using a point transformer. */ static void transform_rect( const Transformation *trn, transform_fn transform, const Rect *in, /* In input space */ Rect *out ) /* In output space */ { double x1, y1; /* Map corners */ double x2, y2; double x3, y3; double x4, y4; double left, right, top, bottom; /* Map input Rect. */ transform( trn, in->left, in->top, &x1, &y1 ); transform( trn, in->left, IM_RECT_BOTTOM( in ), &x3, &y3 ); transform( trn, IM_RECT_RIGHT( in ), in->top, &x2, &y2 ); transform( trn, IM_RECT_RIGHT( in ), IM_RECT_BOTTOM( in ), &x4, &y4 ); /* Find bounding box for these four corners. Round-to-nearest to try * to stop rounding errors growing images. */ left = IM_MIN( x1, IM_MIN( x2, IM_MIN( x3, x4 ) ) ); right = IM_MAX( x1, IM_MAX( x2, IM_MAX( x3, x4 ) ) ); top = IM_MIN( y1, IM_MIN( y2, IM_MIN( y3, y4 ) ) ); bottom = IM_MAX( y1, IM_MAX( y2, IM_MAX( y3, y4 ) ) ); out->left = IM_RINT( left ); out->top = IM_RINT( top ); out->width = IM_RINT( right - left ); out->height = IM_RINT( bottom - top ); }
int im__avgdxdy( TIE_POINTS *points, int *dx, int *dy ) { int sumdx, sumdy; int i; if( points->nopoints == 0 ) { im_error( "im_avgdxdy", "%s", _( "no points to average" ) ); return( -1 ); } /* Lots of points. */ sumdx = 0; sumdy = 0; for( i = 0; i < points->nopoints; i++ ) { sumdx += points->x_secondary[i] - points->x_reference[i]; sumdy += points->y_secondary[i] - points->y_reference[i]; } *dx = IM_RINT( (double) sumdx / (double) points->nopoints ); *dy = IM_RINT( (double) sumdy / (double) points->nopoints ); return( 0 ); }
/** * im_scale_dmask: * @in: mask to scale * @filename: filename for returned mask * * Scale the dmask to make an imask with a maximum value of 20. * * See also: im_norm_dmask(). * * Returns: the converted mask, or NULL on error. */ INTMASK * im_scale_dmask( DOUBLEMASK *in, const char *filename ) { const int size = in->xsize * in->ysize; INTMASK *out; double maxval, dsum; int i; int isum; if( im_check_dmask( "im_scale_dmask", in ) || !(out = im_create_imask( filename, in->xsize, in->ysize )) ) return( NULL ); /* Find mask max. */ maxval = in->coeff[0]; for( i = 0; i < size; i++ ) if( in->coeff[i] > maxval ) maxval = in->coeff[i]; /* Copy and scale, setting max to 20. */ for( i = 0; i < size; i++ ) out->coeff[i] = IM_RINT( in->coeff[i] * 20.0 / maxval ); out->offset = in->offset; /* Set the scale to match the adjustment to max. */ isum = 0; dsum = 0.0; for( i = 0; i < size; i++ ) { isum += out->coeff[i]; dsum += in->coeff[i]; } if( dsum == in->scale ) out->scale = isum; else if( dsum == 0.0 ) out->scale = 1.0; else out->scale = IM_RINT( in->scale * isum / dsum ); return( out ); }
/** * im_dmask2imask: * @in: mask to convert * @filename: filename for returned mask * * Make an imask from the dmask, rounding to nearest. * * See also: im_scale_dmask(). * * Returns: the converted mask, or NULL on error. */ INTMASK * im_dmask2imask( DOUBLEMASK *in, const char *filename ) { const int size = in->xsize * in->ysize; INTMASK *out; int i; if( im_check_dmask( "im_dmask2imask", in ) || !(out = im_create_imask( filename, in->xsize, in->ysize )) ) return( NULL ); for( i = 0; i < size; i++ ) out->coeff[i] = IM_RINT( in->coeff[i] ); out->offset = IM_RINT( in->offset ); out->scale = IM_RINT( in->scale ); return( out ); }
int im_stretch3( IMAGE *in, IMAGE *out, double dx, double dy ) { StretchInfo *sin; int i; /* Check our args. */ if( in->Coding != IM_CODING_NONE || in->BandFmt != IM_BANDFMT_USHORT ) { im_error( "im_stretch3", "%s", _( "not uncoded unsigned short" ) ); return( -1 ); } if( dx < 0 || dx >= 1.0 || dy < 0 || dy >= 1.0 ) { im_error( "im_stretch3", "%s", _( "displacements out of range [0,1)" ) ); return( -1 ); } if( im_piocheck( in, out ) ) return( -1 ); /* Prepare the output image. */ if( im_cp_desc( out, in ) ) return( -1 ); out->Xsize = 34*(in->Xsize / 33) + in->Xsize%33 - 3; out->Ysize = in->Ysize - 3; if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) ) return( -1 ); if( !(sin = IM_NEW( out, StretchInfo )) ) return( -1 ); /* Save parameters. */ sin->in = in; sin->dx = dx; sin->dy = dy; /* Generate masks. */ for( i = 0; i < 34; i++ ) { double d = (34.0 - i)/34.0; double y0 = 2.0*d*d - d - d*d*d; double y1 = 1.0 - 2.0*d*d + d*d*d; double y2 = d + d*d - d*d*d; double y3 = -d*d + d*d*d; sin->mask[i][0] = IM_RINT( y0 * 32768 ); sin->mask[i][1] = IM_RINT( y1 * 32768 ); sin->mask[i][2] = IM_RINT( y2 * 32768 ); sin->mask[i][3] = IM_RINT( y3 * 32768 ); } /* Which mask do we start with to apply these offsets? */ sin->xoff = (dx * 33.0) + 0.5; sin->yoff = (dy * 33.0) + 0.5; if( im_generate( out, stretch_start, stretch_gen, stretch_stop, in, sin ) ) return( -1 ); return( 0 ); }