From 1fc10d56a8ec16ad94e5a80ef69e3b67ed836d52 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 17 Dec 2012 09:59:04 +0000 Subject: [PATCH] half-way through expanding transform started putting in input displacement --- TODO | 1 + libvips/deprecated/vips7compat.c | 16 ++++++------- libvips/include/vips/transform.h | 3 ++- libvips/resample/affine.c | 22 ++++++++++------- libvips/resample/transform.c | 41 +++++++++++++++++++------------- 5 files changed, 49 insertions(+), 34 deletions(-) diff --git a/TODO b/TODO index 4a4432be..253e4985 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,4 @@ +- test affine labq processing - now we've removed round-to-nearest from NN, we need something extra in the affine transform to displace the input cods diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index c708a1e2..f490a0bf 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2901,8 +2901,8 @@ im__affinei( VipsImage *in, VipsImage *out, trn->a, trn->b, trn->c, trn->d, "interpolate", interpolate, "oarea", oarea, - "odx", trn->dx, - "ody", trn->dy, + "odx", trn->odx, + "ody", trn->ody, NULL ) ) { vips_area_unref( oarea ); return( -1 ); @@ -2922,7 +2922,7 @@ im__affinei( VipsImage *in, VipsImage *out, int im_affinei( VipsImage *in, VipsImage *out, VipsInterpolate *interpolate, - double a, double b, double c, double d, double dx, double dy, + double a, double b, double c, double d, double odx, double ody, int ox, int oy, int ow, int oh ) { VipsTransformation trn; @@ -2941,15 +2941,15 @@ im_affinei( VipsImage *in, VipsImage *out, VipsInterpolate *interpolate, trn.b = b; trn.c = c; trn.d = d; - trn.dx = dx; - trn.dy = dy; + trn.odx = odx; + trn.ody = ody; return( im__affinei( in, out, interpolate, &trn ) ); } int im_affinei_all( VipsImage *in, VipsImage *out, VipsInterpolate *interpolate, - double a, double b, double c, double d, double dx, double dy ) + double a, double b, double c, double d, double odx, double ody ) { VipsTransformation trn; @@ -2961,8 +2961,8 @@ im_affinei_all( VipsImage *in, VipsImage *out, VipsInterpolate *interpolate, trn.b = b; trn.c = c; trn.d = d; - trn.dx = dx; - trn.dy = dy; + trn.odx = odx; + trn.ody = ody; vips__transform_set_area( &trn ); diff --git a/libvips/include/vips/transform.h b/libvips/include/vips/transform.h index 478fb73c..6b414d30 100644 --- a/libvips/include/vips/transform.h +++ b/libvips/include/vips/transform.h @@ -50,7 +50,8 @@ typedef struct { /* The transform. */ double a, b, c, d; - double dx, dy; + double idx, idy; + double odx, ody; double ia, ib, ic, id; /* Inverse of matrix abcd */ } VipsTransformation; diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index 39813ea3..ffc388ee 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -315,8 +315,8 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) /* Continuous cods in transformed space. */ - const double ox = le + oarea->left - affine->trn.dx; - const double oy = y + oarea->top - affine->trn.dy; + const double ox = le + oarea->left - affine->trn.odx; + const double oy = y + oarea->top - affine->trn.ody; /* Continuous cods in input space. */ @@ -411,8 +411,10 @@ vips_affine_build( VipsObject *object ) affine->trn.b = ((double *) affine->matrix->data)[1]; affine->trn.c = ((double *) affine->matrix->data)[2]; affine->trn.d = ((double *) affine->matrix->data)[3]; - affine->trn.dx = 0; - affine->trn.dy = 0; + affine->trn.idx = 0; + affine->trn.idy = 0; + affine->trn.odx = 0; + affine->trn.ody = 0; vips__transform_set_area( &affine->trn ); if( vips_object_argument_isset( object, "oarea" ) ) { @@ -423,12 +425,15 @@ vips_affine_build( VipsObject *object ) } if( vips_object_argument_isset( object, "odx" ) ) - affine->trn.dx = affine->odx; + affine->trn.odx = affine->odx; if( vips_object_argument_isset( object, "ody" ) ) - affine->trn.dx = affine->ody; + affine->trn.ody = affine->ody; if( vips__transform_calc_inverse( &affine->trn ) ) return( -1 ); + + if( vips__transform_isidentity( &affine->trn ) ) + return( vips_image_write( in, resample->out ) ); resample->out->Xsize = affine->trn.oarea.width; resample->out->Ysize = affine->trn.oarea.height; @@ -484,8 +489,8 @@ vips_affine_build( VipsObject *object ) /* Finally: can now set Xoffset/Yoffset. */ - resample->out->Xoffset = affine->trn.dx - affine->trn.oarea.left; - resample->out->Yoffset = affine->trn.dy - affine->trn.oarea.top; + resample->out->Xoffset = affine->trn.odx - affine->trn.oarea.left; + resample->out->Yoffset = affine->trn.ody - affine->trn.oarea.top; if( repack ) { if( vips_LabS2LabQ( resample->out, &t[2], NULL ) ) @@ -501,7 +506,6 @@ vips_affine_class_init( VipsAffineClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); - VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); VIPS_DEBUG_MSG( "vips_affine_class_init\n" ); diff --git a/libvips/resample/transform.c b/libvips/resample/transform.c index 9c486416..ebdc6afc 100644 --- a/libvips/resample/transform.c +++ b/libvips/resample/transform.c @@ -87,8 +87,10 @@ vips__transform_init( VipsTransformation *trn ) trn->b = 0.0; trn->c = 0.0; trn->d = 1.0; - trn->dx = 0.0; - trn->dy = 0.0; + trn->idx = 0.0; + trn->idy = 0.0; + trn->odx = 0.0; + trn->ody = 0.0; (void) vips__transform_calc_inverse( trn ); } @@ -98,8 +100,10 @@ vips__transform_init( VipsTransformation *trn ) int vips__transform_isidentity( const VipsTransformation *trn ) { - if( trn->a == 1.0 && trn->b == 0.0 && trn->c == 0.0 && - trn->d == 1.0 && trn->dx == 0.0 && trn->dy == 0.0 ) + if( trn->a == 1.0 && trn->b == 0.0 && + trn->c == 0.0 && trn->d == 1.0 && + trn->idx == 0.0 && trn->idy == 0.0 && + trn->odx == 0.0 && trn->ody == 0.0 ) return( 1 ); else return( 0 ); @@ -116,8 +120,10 @@ vips__transform_add( const VipsTransformation *in1, out->c = in1->a * in2->c + in1->c * in2->d; out->d = in1->b * in2->c + in1->d * in2->d; - out->dx = in1->dx * in2->a + in1->dy * in2->b + in2->dx; - out->dy = in1->dx * in2->c + in1->dy * in2->d + in2->dy; + // fixme: do idx/idy as well + + out->odx = in1->odx * in2->a + in1->ody * in2->b + in2->odx; + out->ody = in1->odx * in2->c + in1->ody * in2->d + in2->ody; if( vips__transform_calc_inverse( out ) ) return( -1 ); @@ -141,33 +147,36 @@ vips__transform_print( const VipsTransformation *trn ) trn->oarea.height ); printf( " mat: a=%g, b=%g, c=%g, d=%g\n", trn->a, trn->b, trn->c, trn->d ); - printf( " off: dx=%g, dy=%g\n", - trn->dx, trn->dy ); + printf( " off: odx=%g, ody=%g, idx=%g, idy=%g\n", + trn->odx, trn->ody, trn->idx, trn->idy ); } /* Map a pixel coordinate through the transform. */ void vips__transform_forward_point( const VipsTransformation *trn, - const double x, const double y, /* In input space */ + double x, double y, /* In input space */ double *ox, double *oy ) /* In output space */ { - *ox = trn->a * x + trn->b * y + trn->dx; - *oy = trn->c * x + trn->d * y + trn->dy; + x += trn->idx; + y += trn->idy; + + *ox = trn->a * x + trn->b * y + trn->odx; + *oy = trn->c * x + trn->d * y + trn->ody; } /* Map a pixel coordinate through the inverse transform. */ void vips__transform_invert_point( const VipsTransformation *trn, - const double x, const double y, /* In output space */ + double x, double y, /* In output space */ double *ox, double *oy ) /* In input space */ { - double mx = x - trn->dx; - double my = y - trn->dy; + x -= trn->odx; + y -= trn->ody; - *ox = trn->ia * mx + trn->ib * my; - *oy = trn->ic * mx + trn->id * my; + *ox = trn->ia * x + trn->ib * y - trn->idx; + *oy = trn->ic * x + trn->id * y - trn->idy; } typedef void (*transform_fn)( const VipsTransformation *,