half-way through expanding transform

started putting in input displacement
This commit is contained in:
John Cupitt 2012-12-17 09:59:04 +00:00
parent 40bb7a2eb3
commit 1fc10d56a8
5 changed files with 49 additions and 34 deletions

1
TODO
View File

@ -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

View File

@ -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 );

View File

@ -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;

View File

@ -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" );

View File

@ -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 *,