Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImageToolkit/BSplineRotate.cpp  view on Meta::CPAN

		}
		// anticausal initialization 
		c[DataLength - 1L] = InitialAntiCausalCoefficient(c, DataLength, z[k]);
		// anticausal recursion 
		for (n = DataLength - 2L; 0 <= n; n--) {
			c[n] = z[k] * (c[n + 1L] - c[n]);
		}
	}
} 

/**
 InitialCausalCoefficient

 @param c Coefficients
 @param DataLength Number of coefficients
 @param z Actual pole
 @param Tolerance Admissible relative error
 @return
*/
static double 
InitialCausalCoefficient(double	*c, long DataLength, double	z, double Tolerance) {
	double	Sum, zn, z2n, iz;
	long	n, Horizon;

	// this initialization corresponds to mirror boundaries 
	Horizon = DataLength;
	if(Tolerance > 0) {
		Horizon = (long)ceil(log(Tolerance) / log(fabs(z)));
	}
	if(Horizon < DataLength) {
		// accelerated loop
		zn = z;
		Sum = c[0];
		for (n = 1L; n < Horizon; n++) {
			Sum += zn * c[n];
			zn *= z;
		}
		return(Sum);
	}
	else {
		// full loop 
		zn = z;
		iz = 1.0 / z;
		z2n = pow(z, (double)(DataLength - 1L));
		Sum = c[0] + z2n * c[DataLength - 1L];
		z2n *= z2n * iz;
		for (n = 1L; n <= DataLength - 2L; n++) {
			Sum += (zn + z2n) * c[n];
			zn *= z;
			z2n *= iz;
		}
		return(Sum / (1.0 - zn * zn));
	}
}

/**
 GetColumn

 @param Image Input image array
 @param Width Width of the image
 @param x x coordinate of the selected line
 @param Line Output linear array
 @param Height Length of the line
*/
static void 
GetColumn(double *Image, long Width, long x, double *Line, long Height) {
	long y;

	Image = Image + x;
	for(y = 0L; y < Height; y++) {
		Line[y] = (double)*Image;
		Image += Width;
	}
}

/**
 GetRow

 @param Image Input image array
 @param y y coordinate of the selected line
 @param Line Output linear array
 @param Width Length of the line
*/
static void	
GetRow(double *Image, long y, double *Line, long Width) {
	long	x;

	Image = Image + (y * Width);
	for(x = 0L; x < Width; x++) {
		Line[x] = (double)*Image++;
	}
}

/**
 InitialAntiCausalCoefficient

 @param c Coefficients
 @param DataLength Number of samples or coefficients
 @param z Actual pole
 @return
*/
static double 
InitialAntiCausalCoefficient(double	*c, long DataLength, double	z) {
	// this initialization corresponds to mirror boundaries
	return((z / (z * z - 1.0)) * (z * c[DataLength - 2L] + c[DataLength - 1L]));
}

/**
 PutColumn

 @param Image Output image array
 @param Width Width of the image
 @param x x coordinate of the selected line
 @param Line Input linear array
 @param Height Length of the line and height of the image
*/
static void	
PutColumn(double *Image, long Width, long x, double *Line, long Height) {
	long	y;

	Image = Image + x;
	for(y = 0L; y < Height; y++) {
		*Image = (double)Line[y];
		Image += Width;
	}
}

/**
 PutRow

 @param Image Output image array
 @param y y coordinate of the selected line
 @param Line Input linear array
 @param Width length of the line and width of the image
*/
static void	
PutRow(double *Image, long y, double *Line, long Width) {
	long	x;

	Image = Image + (y * Width);
	for(x = 0L; x < Width; x++) {
		*Image++ = (double)Line[x];
	}
}

/**
 SamplesToCoefficients.<br>
 Implement the algorithm that converts the image samples into B-spline coefficients. 
 This efficient procedure essentially relies on the three papers cited above; 
 data are processed in-place. 
 Even though this algorithm is robust with respect to quantization, 
 we advocate the use of a floating-point format for the data. 

 @param Image Input / Output image (in-place processing)
 @param Width Width of the image
 @param Height Height of the image
 @param spline_degree Degree of the spline model
 @return Returns true if success, false otherwise
*/
static bool	
SamplesToCoefficients(double *Image, long Width, long Height, long spline_degree) {
	double	*Line;
	double	Pole[2];
	long	NbPoles;
	long	x, y;

	// recover the poles from a lookup table
	switch (spline_degree) {
		case 2L:
			NbPoles = 1L;
			Pole[0] = sqrt(8.0) - 3.0;
			break;
		case 3L:
			NbPoles = 1L;
			Pole[0] = sqrt(3.0) - 2.0;
			break;
		case 4L:
			NbPoles = 2L;
			Pole[0] = sqrt(664.0 - sqrt(438976.0)) + sqrt(304.0) - 19.0;
			Pole[1] = sqrt(664.0 + sqrt(438976.0)) - sqrt(304.0) - 19.0;
			break;
		case 5L:
			NbPoles = 2L;
			Pole[0] = sqrt(135.0 / 2.0 - sqrt(17745.0 / 4.0)) + sqrt(105.0 / 4.0)
				- 13.0 / 2.0;
			Pole[1] = sqrt(135.0 / 2.0 + sqrt(17745.0 / 4.0)) - sqrt(105.0 / 4.0)
				- 13.0 / 2.0;
			break;
		default:
			// Invalid spline degree
			return false;
	}



( run in 0.839 second using v1.01-cache-2.11-cpan-d7f47b0818f )