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 )