Blob Blame Raw


//#include "trop.h"
#include "tpalette.h"
#include "tropcm.h"

//------------------------------------------------------------------------------

namespace
{

inline double gauss(double x, double y, double x0, double y0, double s)
{
	return exp(-((x - x0) * (x - x0) + (y - y0) * (y - y0)) / s) / (s * M_PI);
}

//------------------------------------------------------------------------------

double integ_gauss(double xmin, double ymin, double xmax, double ymax,
				   double x0, double y0, double s)
{
	int i, j, n;
	double x1, y1, x2, y2, xstep, ystep, area;
	double sum;
	n = 50;
	sum = 0;
	xstep = (xmax - xmin) / n;
	ystep = (ymax - ymin) / n;
	area = xstep * ystep;
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++) {
			x1 = xmin + xstep * i;
			y1 = ymin + ystep * i;
			x2 = x1 + xstep;
			y2 = y1 + ystep;
			sum += area * (gauss(x1, y1, x0, y0, s) +
						   gauss(x1, y2, x0, y0, s) +
						   gauss(x2, y2, x0, y0, s) +
						   gauss(x2, y1, x0, y0, s)) /
				   4;
		}
	return sum;
}

//------------------------------------------------------------------------------

void build_filter(double h[], double x0, double y0, double s)
{
	double sum, vv;
	int i, j, k;
	double x1, y1, x2, y2;
	k = 0;
	sum = 0.0;
	for (i = 0; i < 3; i++)
		for (j = 0; j < 3; j++) {
			x1 = -1.5 + j;
			y1 = -1.5 + i;
			x2 = x1 + 1.0;
			y2 = y1 + 1.0;
			h[k++] = vv = integ_gauss(x1, y1, x2, y2, x0, y0, s);
			sum += vv;
		}
	if (sum > 0.0) {
		sum = 1.0 / sum;
		for (k = 0; k < 9; k++)
			h[k] *= sum;
	}
}

} // anonymous namespace

//------------------------------------------------------------------------------

void TRop::fracmove(TRasterP rout, TRasterP rin, double dx, double dy)
{
	//Using a bilinear filter is best - consider that only 4 pixels should contribute
	//to a fractionarily shifted one, with weights proportional to the intersection areas.
	double w[4] = {1, 0, 0, 0};
	double sum = 0;

	int idx = tfloor(dx);
	int idy = tfloor(dy);
	double fracX = dx - idx;
	double fracY = dy - idy;

	int i, j;
	for (i = 0; i < 2; ++i)
		for (j = 0; j < 2; ++j)
			sum += w[j + 2 * i] = fabs(fracX - j) * fabs(fracY - i);

	for (i = 0; i < 4; ++i)
		w[i] /= sum;

	TRop::convolve_i(rout, rin, idx, idy, w, 2);
}

//------------------------------------------------------------------------------

void TRop::fracmove(TRasterP rout, TRasterCM32P rin, const TPaletteP &palette, double dx, double dy)
{
	double w[4] = {1, 0, 0, 0};
	double sum = 0;

	int idx = tfloor(dx);
	int idy = tfloor(dy);
	double fracX = dx - idx;
	double fracY = dy - idy;

	int i, j;
	for (i = 0; i < 2; ++i)
		for (j = 0; j < 2; ++j)
			sum += w[j + 2 * i] = fabs(fracX - j) * fabs(fracY - i);

	for (i = 0; i < 4; ++i)
		w[i] /= sum;

	TRop::convolve_i(rout, rin, idx, idy, w, 2);
}