CRIMP
Artifact [aec60a8a4d]
Not logged in

Artifact aec60a8a4de1bea3b3b5431e51300226cb000145:


crimp_image*     result;
crimp_image*     imageA;
crimp_image*     imageB;
int px, py, lx, ly, oxa, oya, oxb, oyb;
int pxa, pya, pxb, pyb;
crimp_geometry bb;

crimp_input (imageAObj, imageA, rgb);
crimp_input (imageBObj, imageB, rgb);

/*
 * Compute union area of the two images to process.
 * Note how the images do not have to match in size.
 */

crimp_rect_union (&imageA->geo, &imageB->geo, &bb);

result = crimp_new_rgb_at (bb.x, bb.y, bb.w, bb.h);
oxa = crimp_x (imageA);
oya = crimp_y (imageA);
oxb = crimp_x (imageB);
oyb = crimp_y (imageB);

/*
 * px, py are physical coordinates in the result, starting from 0.
 * The associated logical coordinates in the 2D plane are
 *  lx = px + x(result)
 *  lx = py + y(result)
 * And when we are inside an input its physical coordinates, from the logical are
 *  px' = lx - x(input)
 *  py' = ly - y(input)
 * Important to note, we can compute all these directly as loop variables, as
 * they are all linearly related to each other.
 */

#ifndef BINOP_POST
#define BINOP_POST(z) z
#endif

for (py = 0, ly = bb.y, pya = bb.y - oya, pyb = bb.y - oyb;
     py < bb.h;
     py++, ly++, pya++, pyb++) {

    for (px = 0, lx = bb.x, pxa = bb.x - oxa, pxb = bb.x - oxb;
	 px < bb.w;
	 px++, lx++, pxa++, pxb++) {

	int ina = crimp_inside (imageA, lx, ly);
	int inb = crimp_inside (imageB, lx, ly);

	/*
	 * The result depends on where we are relative to both input.
	 * Inside of each input we take the respective value of the
	 * pixel. Outside of an input we take BLACK as the value
	 * instead.
	 */

	int    a_r = ina ? R (imageA, pxa, pya) : BLACK;
	int    a_g = ina ? G (imageA, pxa, pya) : BLACK;
	int    a_b = ina ? B (imageA, pxa, pya) : BLACK;
	int    b_r = inb ? R (imageB, pxb, pyb) : BLACK;
	int    b_g = inb ? G (imageB, pxb, pyb) : BLACK;
	int    b_b = inb ? B (imageB, pxb, pyb) : BLACK;
	
	int    z_rr = BINOP (a_r, b_r);
	int    z_gg = BINOP (a_g, b_g);
	int    z_bb = BINOP (a_b, b_b);
	
	R (result, px, py) = BINOP_POST (z_rr);
	G (result, px, py) = BINOP_POST (z_gg);
	B (result, px, py) = BINOP_POST (z_bb);
    }
}

#undef BINOP
#undef BINOP_POST

Tcl_SetObjResult(interp, crimp_new_image_obj (result));
return TCL_OK;

/* vim: set sts=4 sw=4 tw=80 et ft=c: */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */