xbounds → bounds

kmax → ksize
This commit is contained in:
homm 2016-12-01 13:46:12 +03:00
parent c7161af924
commit 4ff7afbe16

View File

@ -126,11 +126,11 @@ static inline UINT8 clip8(int in)
int int
precompute_coeffs(int inSize, float in0, float in1, int outSize, precompute_coeffs(int inSize, float in0, float in1, int outSize,
struct filter *filterp, int **xboundsp, double **kkp) { struct filter *filterp, int **boundsp, double **kkp) {
double support, scale, filterscale; double support, scale, filterscale;
double center, ww, ss; double center, ww, ss;
int xx, x, kmax, xmin, xmax; int xx, x, ksize, xmin, xmax;
int *xbounds; int *bounds;
double *kk, *k; double *kk, *k;
/* prepare for horizontal stretch */ /* prepare for horizontal stretch */
@ -143,25 +143,25 @@ precompute_coeffs(int inSize, float in0, float in1, int outSize,
support = filterp->support * filterscale; support = filterp->support * filterscale;
/* maximum number of coeffs */ /* maximum number of coeffs */
kmax = (int) ceil(support) * 2 + 1; ksize = (int) ceil(support) * 2 + 1;
// check for overflow // check for overflow
if (outSize > INT_MAX / (kmax * sizeof(double))) { if (outSize > INT_MAX / (ksize * sizeof(double))) {
ImagingError_MemoryError(); ImagingError_MemoryError();
return 0; return 0;
} }
/* coefficient buffer */ /* coefficient buffer */
/* malloc check ok, overflow checked above */ /* malloc check ok, overflow checked above */
kk = malloc(outSize * kmax * sizeof(double)); kk = malloc(outSize * ksize * sizeof(double));
if ( ! kk) { if ( ! kk) {
ImagingError_MemoryError(); ImagingError_MemoryError();
return 0; return 0;
} }
/* malloc check ok, kmax*sizeof(double) > 2*sizeof(int) */ /* malloc check ok, ksize*sizeof(double) > 2*sizeof(int) */
xbounds = malloc(outSize * 2 * sizeof(int)); bounds = malloc(outSize * 2 * sizeof(int));
if ( ! xbounds) { if ( ! bounds) {
free(kk); free(kk);
ImagingError_MemoryError(); ImagingError_MemoryError();
return 0; return 0;
@ -178,7 +178,7 @@ precompute_coeffs(int inSize, float in0, float in1, int outSize,
if (xmax > inSize) if (xmax > inSize)
xmax = inSize; xmax = inSize;
xmax -= xmin; xmax -= xmin;
k = &kk[xx * kmax]; k = &kk[xx * ksize];
for (x = 0; x < xmax; x++) { for (x = 0; x < xmax; x++) {
double w = filterp->filter((x + xmin - center + 0.5) * ss); double w = filterp->filter((x + xmin - center + 0.5) * ss);
k[x] = w; k[x] = w;
@ -204,28 +204,28 @@ precompute_coeffs(int inSize, float in0, float in1, int outSize,
k[x] /= ww; k[x] /= ww;
} }
// Remaining values should stay empty if they are used despite of xmax. // Remaining values should stay empty if they are used despite of xmax.
for (; x < kmax; x++) { for (; x < ksize; x++) {
k[x] = 0; k[x] = 0;
} }
xbounds[xx * 2 + 0] = xmin; bounds[xx * 2 + 0] = xmin;
xbounds[xx * 2 + 1] = xmax; bounds[xx * 2 + 1] = xmax;
} }
*xboundsp = xbounds; *boundsp = bounds;
*kkp = kk; *kkp = kk;
return kmax; return ksize;
} }
void void
normalize_coeffs_8bpc(int outSize, int kmax, double *prekk) normalize_coeffs_8bpc(int outSize, int ksize, double *prekk)
{ {
int x; int x;
INT32 *kk; INT32 *kk;
// We are using the same buffer for normalized coefficients // use the same buffer for normalized coefficients
kk = (INT32 *)prekk; kk = (INT32 *) prekk;
for (x = 0; x < outSize * kmax; x++) { for (x = 0; x < outSize * ksize; x++) {
if (prekk[x] < 0) { if (prekk[x] < 0) {
kk[x] = (int) (-0.5 + prekk[x] * (1 << PRECISION_BITS)); kk[x] = (int) (-0.5 + prekk[x] * (1 << PRECISION_BITS));
} else { } else {
@ -238,23 +238,24 @@ normalize_coeffs_8bpc(int outSize, int kmax, double *prekk)
void void
ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn, ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn,
int kmax, int *xbounds, double *prekk) int ksize, int *bounds, double *prekk)
{ {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int ss0, ss1, ss2, ss3; int ss0, ss1, ss2, ss3;
int xx, yy, x, xmin, xmax; int xx, yy, x, xmin, xmax;
INT32 *k, *kk; INT32 *k, *kk;
// use the same buffer for normalized coefficients
kk = (INT32 *) prekk; kk = (INT32 *) prekk;
normalize_coeffs_8bpc(imOut->xsize, kmax, prekk); normalize_coeffs_8bpc(imOut->xsize, ksize, prekk);
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (imIn->image8) { if (imIn->image8) {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = bounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * kmax]; k = &kk[xx * ksize];
ss0 = 1 << (PRECISION_BITS -1); ss0 = 1 << (PRECISION_BITS -1);
for (x = 0; x < xmax; x++) for (x = 0; x < xmax; x++)
ss0 += ((UINT8) imIn->image8[yy][x + xmin]) * k[x]; ss0 += ((UINT8) imIn->image8[yy][x + xmin]) * k[x];
@ -265,9 +266,9 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn,
if (imIn->bands == 2) { if (imIn->bands == 2) {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = bounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * kmax]; k = &kk[xx * ksize];
ss0 = ss3 = 1 << (PRECISION_BITS -1); ss0 = ss3 = 1 << (PRECISION_BITS -1);
for (x = 0; x < xmax; x++) { for (x = 0; x < xmax; x++) {
ss0 += ((UINT8) imIn->image[yy][(x + xmin)*4 + 0]) * k[x]; ss0 += ((UINT8) imIn->image[yy][(x + xmin)*4 + 0]) * k[x];
@ -280,9 +281,9 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn,
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = bounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * kmax]; k = &kk[xx * ksize];
ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1); ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1);
for (x = 0; x < xmax; x++) { for (x = 0; x < xmax; x++) {
ss0 += ((UINT8) imIn->image[yy][(x + xmin)*4 + 0]) * k[x]; ss0 += ((UINT8) imIn->image[yy][(x + xmin)*4 + 0]) * k[x];
@ -297,9 +298,9 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn,
} else { } else {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = bounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * kmax]; k = &kk[xx * ksize];
ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS -1); ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS -1);
for (x = 0; x < xmax; x++) { for (x = 0; x < xmax; x++) {
ss0 += ((UINT8) imIn->image[yy][(x + xmin)*4 + 0]) * k[x]; ss0 += ((UINT8) imIn->image[yy][(x + xmin)*4 + 0]) * k[x];
@ -321,22 +322,23 @@ ImagingResampleHorizontal_8bpc(Imaging imOut, Imaging imIn,
void void
ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn, ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn,
int kmax, int *xbounds, double *prekk) int ksize, int *bounds, double *prekk)
{ {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
int ss0, ss1, ss2, ss3; int ss0, ss1, ss2, ss3;
int xx, yy, y, ymin, ymax; int xx, yy, y, ymin, ymax;
INT32 *k, *kk; INT32 *k, *kk;
// use the same buffer for normalized coefficients
kk = (INT32 *) prekk; kk = (INT32 *) prekk;
normalize_coeffs_8bpc(imOut->ysize, kmax, prekk); normalize_coeffs_8bpc(imOut->ysize, ksize, prekk);
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
if (imIn->image8) { if (imIn->image8) {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
k = &kk[yy * kmax]; k = &kk[yy * ksize];
ymin = xbounds[yy * 2 + 0]; ymin = bounds[yy * 2 + 0];
ymax = xbounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss0 = 1 << (PRECISION_BITS -1); ss0 = 1 << (PRECISION_BITS -1);
for (y = 0; y < ymax; y++) for (y = 0; y < ymax; y++)
@ -347,9 +349,9 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn,
} else if (imIn->type == IMAGING_TYPE_UINT8) { } else if (imIn->type == IMAGING_TYPE_UINT8) {
if (imIn->bands == 2) { if (imIn->bands == 2) {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
k = &kk[yy * kmax]; k = &kk[yy * ksize];
ymin = xbounds[yy * 2 + 0]; ymin = bounds[yy * 2 + 0];
ymax = xbounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss0 = ss3 = 1 << (PRECISION_BITS -1); ss0 = ss3 = 1 << (PRECISION_BITS -1);
for (y = 0; y < ymax; y++) { for (y = 0; y < ymax; y++) {
@ -362,9 +364,9 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn,
} }
} else if (imIn->bands == 3) { } else if (imIn->bands == 3) {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
k = &kk[yy * kmax]; k = &kk[yy * ksize];
ymin = xbounds[yy * 2 + 0]; ymin = bounds[yy * 2 + 0];
ymax = xbounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1); ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1);
for (y = 0; y < ymax; y++) { for (y = 0; y < ymax; y++) {
@ -379,9 +381,9 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn,
} }
} else { } else {
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
k = &kk[yy * kmax]; k = &kk[yy * ksize];
ymin = xbounds[yy * 2 + 0]; ymin = bounds[yy * 2 + 0];
ymax = xbounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS -1); ss0 = ss1 = ss2 = ss3 = 1 << (PRECISION_BITS -1);
for (y = 0; y < ymax; y++) { for (y = 0; y < ymax; y++) {
@ -404,7 +406,7 @@ ImagingResampleVertical_8bpc(Imaging imOut, Imaging imIn,
void void
ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn, ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn,
int kmax, int *xbounds, double *kk) int ksize, int *bounds, double *kk)
{ {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
double ss; double ss;
@ -416,9 +418,9 @@ ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn,
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = bounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * kmax]; k = &kk[xx * ksize];
ss = 0.0; ss = 0.0;
for (x = 0; x < xmax; x++) for (x = 0; x < xmax; x++)
ss += IMAGING_PIXEL_I(imIn, x + xmin, yy) * k[x]; ss += IMAGING_PIXEL_I(imIn, x + xmin, yy) * k[x];
@ -430,9 +432,9 @@ ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn,
case IMAGING_TYPE_FLOAT32: case IMAGING_TYPE_FLOAT32:
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = bounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = bounds[xx * 2 + 1];
k = &kk[xx * kmax]; k = &kk[xx * ksize];
ss = 0.0; ss = 0.0;
for (x = 0; x < xmax; x++) for (x = 0; x < xmax; x++)
ss += IMAGING_PIXEL_F(imIn, x + xmin, yy) * k[x]; ss += IMAGING_PIXEL_F(imIn, x + xmin, yy) * k[x];
@ -447,7 +449,7 @@ ImagingResampleHorizontal_32bpc(Imaging imOut, Imaging imIn,
void void
ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn, ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn,
int kmax, int *xbounds, double *kk) int ksize, int *bounds, double *kk)
{ {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
double ss; double ss;
@ -458,9 +460,9 @@ ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn,
switch(imIn->type) { switch(imIn->type) {
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
ymin = xbounds[yy * 2 + 0]; ymin = bounds[yy * 2 + 0];
ymax = xbounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
k = &kk[yy * kmax]; k = &kk[yy * ksize];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss = 0.0; ss = 0.0;
for (y = 0; y < ymax; y++) for (y = 0; y < ymax; y++)
@ -472,9 +474,9 @@ ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn,
case IMAGING_TYPE_FLOAT32: case IMAGING_TYPE_FLOAT32:
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
ymin = xbounds[yy * 2 + 0]; ymin = bounds[yy * 2 + 0];
ymax = xbounds[yy * 2 + 1]; ymax = bounds[yy * 2 + 1];
k = &kk[yy * kmax]; k = &kk[yy * ksize];
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < imOut->xsize; xx++) {
ss = 0.0; ss = 0.0;
for (y = 0; y < ymax; y++) for (y = 0; y < ymax; y++)
@ -489,7 +491,7 @@ ImagingResampleVertical_32bpc(Imaging imOut, Imaging imIn,
typedef void (*ResampleFunction)(Imaging imOut, Imaging imIn, typedef void (*ResampleFunction)(Imaging imOut, Imaging imIn,
int kmax, int *xbounds, double *kk); int ksize, int *bounds, double *kk);
Imaging Imaging
@ -567,51 +569,51 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
Imaging imTemp = NULL; Imaging imTemp = NULL;
Imaging imOut = NULL; Imaging imOut = NULL;
int kmax; int ksize;
int *xbounds; int *bounds;
double *kk; double *kk;
/* two-pass resize, first pass */ /* two-pass resize, first pass */
if (box[0] || box[2] != xsize) { if (box[0] || box[2] != xsize) {
kmax = precompute_coeffs(imIn->xsize, box[0], box[2], xsize, filterp, ksize = precompute_coeffs(imIn->xsize, box[0], box[2], xsize, filterp,
&xbounds, &kk); &bounds, &kk);
if ( ! kmax) { if ( ! ksize) {
return NULL; return NULL;
} }
imTemp = ImagingNew(imIn->mode, xsize, imIn->ysize); imTemp = ImagingNew(imIn->mode, xsize, imIn->ysize);
if ( ! imTemp) { if ( ! imTemp) {
free(xbounds); free(bounds);
free(kk); free(kk);
return NULL; return NULL;
} }
ResampleHorizontal(imTemp, imIn, kmax, xbounds, kk); ResampleHorizontal(imTemp, imIn, ksize, bounds, kk);
free(xbounds); free(bounds);
free(kk); free(kk);
imOut = imIn = imTemp; imOut = imIn = imTemp;
} }
/* second pass */ /* second pass */
if (box[1] || box[3] != ysize) { if (box[1] || box[3] != ysize) {
kmax = precompute_coeffs(imIn->ysize, box[1], box[3], ysize, filterp, ksize = precompute_coeffs(imIn->ysize, box[1], box[3], ysize, filterp,
&xbounds, &kk); &bounds, &kk);
if ( ! kmax) { if ( ! ksize) {
ImagingDelete(imTemp); ImagingDelete(imTemp);
return NULL; return NULL;
} }
imOut = ImagingNew(imIn->mode, imIn->xsize, ysize); imOut = ImagingNew(imIn->mode, imIn->xsize, ysize);
if ( ! imOut) { if ( ! imOut) {
free(xbounds); free(bounds);
free(kk); free(kk);
return NULL; return NULL;
} }
/* imIn can be the original image or horizontally resampled one */ /* imIn can be the original image or horizontally resampled one */
ResampleVertical(imOut, imIn, kmax, xbounds, kk); ResampleVertical(imOut, imIn, ksize, bounds, kk);
/* it's safe to call ImagingDelete with empty value /* it's safe to call ImagingDelete with empty value
if previous step was not performed. */ if previous step was not performed. */
ImagingDelete(imTemp); ImagingDelete(imTemp);
free(xbounds); free(bounds);
free(kk); free(kk);
} }