Ejemplo n.º 1
0
/* Combine two transformations. out can be one of the ins.
 */
int
im__transform_add( const Transformation *in1, const Transformation *in2,
                   Transformation *out )
{
    out->a = in1->a * in2->a + in1->c * in2->b;
    out->b = in1->b * in2->a + in1->d * in2->b;
    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;

    if( im__transform_calc_inverse( out ) )
        return( -1 );

    return( 0 );
}
Ejemplo n.º 2
0
/* Init a Transform.
 */
void
im__transform_init( Transformation *trn )
{
    trn->oarea.left = 0;
    trn->oarea.top = 0;
    trn->oarea.width = -1;
    trn->oarea.height = -1;
    trn->iarea.left = 0;
    trn->iarea.top = 0;
    trn->iarea.width = -1;
    trn->iarea.height = -1;
    trn->a = 1.0;	/* Identity transform */
    trn->b = 0.0;
    trn->c = 0.0;
    trn->d = 1.0;
    trn->dx = 0.0;
    trn->dy = 0.0;

    (void) im__transform_calc_inverse( trn );
}
Ejemplo n.º 3
0
/* Like im_similarity(), but return the transform we generated. 
 */
static int 
apply_similarity( Transformation *trn, IMAGE *in, IMAGE *out, 
	double a, double b, double dx, double dy )
{
	trn->iarea.left = 0;
	trn->iarea.top = 0;
	trn->iarea.width = in->Xsize;
	trn->iarea.height = in->Ysize;
	trn->a = a;
	trn->b = -b;
	trn->c = b;
	trn->d = a;
	trn->dx = dx;
	trn->dy = dy;
	im__transform_set_area( trn );
	if( im__transform_calc_inverse( trn ) )
		return( -1 );

	if( im__affine( in, out, trn ) )
		return( -1 );

	return( 0 );
}
Ejemplo n.º 4
0
static int 
affinei( IMAGE *in, IMAGE *out, 
	VipsInterpolate *interpolate, Transformation *trn )
{
	Affine *affine;
	double edge;

	/* Make output image.
	 */
	if( im_piocheck( in, out ) ) 
		return( -1 );
	if( im_cp_desc( out, in ) ) 
		return( -1 );

	/* Need a copy of the params for the lifetime of out.
	 */
	if( !(affine = IM_NEW( out, Affine )) )
		return( -1 );
	affine->interpolate = NULL;
	if( im_add_close_callback( out, 
		(im_callback_fn) affine_free, affine, NULL ) )
		return( -1 );
	affine->in = in;
	affine->out = out;
	affine->interpolate = interpolate;
	g_object_ref( interpolate );
	affine->trn = *trn;

	if( im__transform_calc_inverse( &affine->trn ) )
		return( -1 );

	out->Xsize = affine->trn.oarea.width;
	out->Ysize = affine->trn.oarea.height;

	/* Normally SMALLTILE ... except if this is a size up/down affine.
	 */
	if( affine->trn.b == 0.0 && affine->trn.c == 0.0 ) {
		if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
			return( -1 );
	}
	else {
		if( im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
			return( -1 );
	}

	/* Check for coordinate overflow ... we want to be able to hold the
	 * output space inside INT_MAX / TRANSFORM_SCALE.
	 */
	edge = INT_MAX / VIPS_TRANSFORM_SCALE;
	if( affine->trn.oarea.left < -edge || affine->trn.oarea.top < -edge ||
		IM_RECT_RIGHT( &affine->trn.oarea ) > edge || 
		IM_RECT_BOTTOM( &affine->trn.oarea ) > edge ) {
		im_error( "im_affinei", 
			"%s", _( "output coordinates out of range" ) );
		return( -1 );
	}

	/* Generate!
	 */
	if( im_generate( out, 
		im_start_one, affinei_gen, im_stop_one, in, affine ) )
		return( -1 );

	return( 0 );
}