use ImagingPrecompute in ImagingResampleHorizontal_8bpc

This commit is contained in:
homm 2016-05-05 18:25:42 +03:00
parent f3f03bcd67
commit 126c3151b5

View File

@ -143,78 +143,35 @@ ImagingResampleHorizontal_8bpc(Imaging imIn, int xsize, struct filter *filterp)
{ {
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
Imaging imOut; Imaging imOut;
float support, scale, filterscale;
float center, ww, ss;
int ss0, ss1, ss2, ss3; int ss0, ss1, ss2, ss3;
int xx, yy, x, kmax, xmin, xmax; int xx, yy, x, kmax, xmin, xmax;
int *xbounds; int *xbounds;
int *k, *kk; int *k, *kk;
float *kw; double *prekk;
/* prepare for horizontal stretch */
filterscale = scale = (float) imIn->xsize / xsize; kmax = ImagingPrecompute(imIn->xsize, xsize, filterp, &xbounds, &prekk);
if (filterscale < 1.0) { if ( ! kmax) {
filterscale = 1.0; return (Imaging) ImagingError_MemoryError();
} }
/* determine support size (length of resampling filter) */
support = filterp->support * filterscale;
/* maximum number of coofs */
kmax = (int) ceil(support) * 2 + 1;
// check for overflow
if (xsize > SIZE_MAX / (kmax * sizeof(int)))
return (Imaging) ImagingError_MemoryError();
// sizeof(int) should be greater than 0 as well
if (xsize > SIZE_MAX / (2 * sizeof(int)))
return (Imaging) ImagingError_MemoryError();
/* coefficient buffer */
kk = malloc(xsize * kmax * sizeof(int)); kk = malloc(xsize * kmax * sizeof(int));
if ( ! kk) if ( ! kk) {
return (Imaging) ImagingError_MemoryError(); free(xbounds);
free(prekk);
/* intermediate not normalized buffer for coefficients */
kw = malloc(kmax * sizeof(float));
if ( ! kw) {
free(kk);
return (Imaging) ImagingError_MemoryError();
}
xbounds = malloc(xsize * 2 * sizeof(int));
if ( ! xbounds) {
free(kk);
free(kw);
return (Imaging) ImagingError_MemoryError(); return (Imaging) ImagingError_MemoryError();
} }
for (xx = 0; xx < xsize; xx++) { for (xx = 0; xx < xsize; xx++) {
center = (xx + 0.5) * scale; xmin = xbounds[xx * 2 + 0];
ww = 0.0; xmax = xbounds[xx * 2 + 1];
ss = 1.0 / filterscale;
xmin = (int) floor(center - support);
if (xmin < 0)
xmin = 0;
xmax = (int) ceil(center + support);
if (xmax > imIn->xsize)
xmax = imIn->xsize;
for (x = xmin; x < xmax; x++) {
float w = filterp->filter((x - center + 0.5) * ss);
kw[x - xmin] = w;
ww += w;
}
k = &kk[xx * kmax]; k = &kk[xx * kmax];
for (x = 0; x < xmax - xmin; x++) { for (x = 0; x < xmax - xmin; x++) {
if (ww != 0.0) k[x] = (int) floor(0.5 + prekk[xx * kmax + x] * (1 << PRECISION_BITS));
k[x] = (int) floor(0.5 + kw[x] / ww * (1 << PRECISION_BITS));
} }
xbounds[xx * 2 + 0] = xmin;
xbounds[xx * 2 + 1] = xmax;
} }
free(kw); free(prekk);
imOut = ImagingNew(imIn->mode, xsize, imIn->ysize); imOut = ImagingNew(imIn->mode, xsize, imIn->ysize);
if ( ! imOut) { if ( ! imOut) {
@ -224,10 +181,8 @@ ImagingResampleHorizontal_8bpc(Imaging imIn, int xsize, struct filter *filterp)
} }
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
/* horizontal stretch */
for (yy = 0; yy < imOut->ysize; yy++) { for (yy = 0; yy < imOut->ysize; yy++) {
if (imIn->image8) { if (imIn->image8) {
/* 8-bit grayscale */
for (xx = 0; xx < xsize; xx++) { for (xx = 0; xx < xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = xbounds[xx * 2 + 0];
xmax = xbounds[xx * 2 + 1]; xmax = xbounds[xx * 2 + 1];
@ -238,7 +193,6 @@ ImagingResampleHorizontal_8bpc(Imaging imIn, int xsize, struct filter *filterp)
imOut->image8[yy][xx] = clip8(ss0); imOut->image8[yy][xx] = clip8(ss0);
} }
} else if (imIn->type == IMAGING_TYPE_UINT8) { } else if (imIn->type == IMAGING_TYPE_UINT8) {
/* n-bit grayscale */
if (imIn->bands == 2) { if (imIn->bands == 2) {
for (xx = 0; xx < xsize; xx++) { for (xx = 0; xx < xsize; xx++) {
xmin = xbounds[xx * 2 + 0]; xmin = xbounds[xx * 2 + 0];
@ -287,6 +241,7 @@ ImagingResampleHorizontal_8bpc(Imaging imIn, int xsize, struct filter *filterp)
} }
} }
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
free(kk); free(kk);
free(xbounds); free(xbounds);
@ -317,8 +272,6 @@ ImagingResampleHorizontal_32bpc(Imaging imIn, int xsize, struct filter *filterp)
} }
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
/* horizontal stretch */
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++) {
@ -348,6 +301,7 @@ ImagingResampleHorizontal_32bpc(Imaging imIn, int xsize, struct filter *filterp)
} }
break; break;
} }
ImagingSectionLeave(&cookie); ImagingSectionLeave(&cookie);
free(kk); free(kk);
free(xbounds); free(xbounds);