optimize memory usage

This commit is contained in:
homm 2014-10-26 00:11:39 +04:00
parent e9fc720709
commit c22af89ef0
3 changed files with 49 additions and 64 deletions

View File

@ -1612,22 +1612,17 @@ im_setmode(ImagingObject* self, PyObject* args)
static PyObject* static PyObject*
_stretch(ImagingObject* self, PyObject* args) _stretch(ImagingObject* self, PyObject* args)
{ {
Imaging imIn; Imaging imIn, imOut;
Imaging imOut;
int xsize, ysize; int xsize, ysize;
int filter = IMAGING_TRANSFORM_NEAREST; int filter = IMAGING_TRANSFORM_NEAREST;
if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter))
return NULL; return NULL;
imIn = self->image; imIn = self->image;
imOut = ImagingNew(imIn->mode, xsize, ysize); imOut = ImagingStretch(imIn, xsize, ysize, filter);
if ( ! imOut) if ( ! imOut) {
return NULL;
if (!ImagingStretch(imOut, imIn, filter)) {
ImagingDelete(imOut);
return NULL; return NULL;
} }

View File

@ -91,12 +91,13 @@ static inline UINT8 clip8(float in)
Imaging Imaging
ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter) ImagingStretchHorizaontal(Imaging imIn, int xsize, int filter)
{ {
/* FIXME: this is a quick and straightforward translation from a /* FIXME: this is a quick and straightforward translation from a
python prototype. might need some further C-ification... */ python prototype. might need some further C-ification... */
ImagingSectionCookie cookie; ImagingSectionCookie cookie;
Imaging imOut;
struct filter *filterp; struct filter *filterp;
float support, scale, filterscale; float support, scale, filterscale;
float center, ww, ss; float center, ww, ss;
@ -104,15 +105,6 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
int *xbounds; int *xbounds;
float *k, *kk; float *k, *kk;
/* check modes */
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
return (Imaging) ImagingError_ModeError();
if (imOut->ysize != imIn->ysize)
return (Imaging) ImagingError_ValueError(
"ImagingStretchHorizaontal requires equal heights"
);
/* check filter */ /* check filter */
switch (filter) { switch (filter) {
case IMAGING_TRANSFORM_NEAREST: case IMAGING_TRANSFORM_NEAREST:
@ -134,7 +126,7 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
} }
/* prepare for horizontal stretch */ /* prepare for horizontal stretch */
filterscale = scale = (float) imIn->xsize / imOut->xsize; filterscale = scale = (float) imIn->xsize / xsize;
/* determine support size (length of resampling filter) */ /* determine support size (length of resampling filter) */
support = filterp->support; support = filterp->support;
@ -149,17 +141,17 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
kmax = (int) ceil(support) * 2 + 1; kmax = (int) ceil(support) * 2 + 1;
/* coefficient buffer (with rounding safety margin) */ /* coefficient buffer (with rounding safety margin) */
kk = malloc(imOut->xsize * kmax * sizeof(float)); kk = malloc(xsize * kmax * sizeof(float));
if ( ! kk) if ( ! kk)
return (Imaging) ImagingError_MemoryError(); return (Imaging) ImagingError_MemoryError();
xbounds = malloc(imOut->xsize * 2 * sizeof(int)); xbounds = malloc(xsize * 2 * sizeof(int));
if ( ! xbounds) { if ( ! xbounds) {
free(kk); free(kk);
return (Imaging) ImagingError_MemoryError(); return (Imaging) ImagingError_MemoryError();
} }
for (xx = 0; xx < imOut->xsize; xx++) { for (xx = 0; xx < xsize; xx++) {
k = &kk[xx * kmax]; k = &kk[xx * kmax];
center = (xx + 0.5) * scale; center = (xx + 0.5) * scale;
ww = 0.0; ww = 0.0;
@ -183,12 +175,19 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
xbounds[xx * 2 + 1] = xmax; xbounds[xx * 2 + 1] = xmax;
} }
imOut = ImagingNew(imIn->mode, xsize, imIn->ysize);
if ( ! imOut) {
free(kk);
free(xbounds);
return NULL;
}
ImagingSectionEnter(&cookie); ImagingSectionEnter(&cookie);
/* horizontal stretch */ /* 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 */ /* 8-bit grayscale */
for (xx = 0; xx < imOut->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];
k = &kk[xx * kmax]; k = &kk[xx * kmax];
@ -201,7 +200,7 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
switch(imIn->type) { switch(imIn->type) {
case IMAGING_TYPE_UINT8: case IMAGING_TYPE_UINT8:
/* n-bit grayscale */ /* n-bit grayscale */
for (xx = 0; xx < imOut->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];
k = &kk[xx * kmax]; k = &kk[xx * kmax];
@ -217,7 +216,7 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
break; break;
case IMAGING_TYPE_INT32: case IMAGING_TYPE_INT32:
/* 32-bit integer */ /* 32-bit integer */
for (xx = 0; xx < imOut->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];
k = &kk[xx * kmax]; k = &kk[xx * kmax];
@ -229,7 +228,7 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
break; break;
case IMAGING_TYPE_FLOAT32: case IMAGING_TYPE_FLOAT32:
/* 32-bit float */ /* 32-bit float */
for (xx = 0; xx < imOut->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];
k = &kk[xx * kmax]; k = &kk[xx * kmax];
@ -254,60 +253,51 @@ ImagingStretchHorizaontal(Imaging imOut, Imaging imIn, int filter)
Imaging Imaging
ImagingStretch(Imaging imOut, Imaging imIn, int filter) ImagingTransposeToNew(Imaging imIn)
{
Imaging imTemp = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize);
if ( ! imTemp)
return NULL;
if ( ! ImagingTranspose(imTemp, imIn)) {
ImagingDelete(imTemp);
return NULL;
}
return imTemp;
}
Imaging
ImagingStretch(Imaging imIn, int xsize, int ysize, int filter)
{ {
Imaging imTemp1, imTemp2, imTemp3; Imaging imTemp1, imTemp2, imTemp3;
int xsize = imOut->xsize; Imaging imOut;
int ysize = imOut->ysize;
if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0) if (strcmp(imIn->mode, "P") == 0 || strcmp(imIn->mode, "1") == 0)
return (Imaging) ImagingError_ModeError(); return (Imaging) ImagingError_ModeError();
/* two-pass resize */ /* two-pass resize, first pass */
imTemp1 = ImagingNew(imIn->mode, xsize, imIn->ysize); imTemp1 = ImagingStretchHorizaontal(imIn, xsize, filter);
if ( ! imTemp1) if ( ! imTemp1)
return NULL; return NULL;
/* first pass */
if ( ! ImagingStretchHorizaontal(imTemp1, imIn, filter)) {
ImagingDelete(imTemp1);
return NULL;
}
imTemp2 = ImagingNew(imIn->mode, imIn->ysize, xsize);
if ( ! imTemp2) {
ImagingDelete(imTemp1);
return NULL;
}
/* transpose image once */ /* transpose image once */
if ( ! ImagingTranspose(imTemp2, imTemp1)) { imTemp2 = ImagingTransposeToNew(imTemp1);
ImagingDelete(imTemp1);
ImagingDelete(imTemp2);
return NULL;
}
ImagingDelete(imTemp1); ImagingDelete(imTemp1);
if ( ! imTemp2)
imTemp3 = ImagingNew(imIn->mode, ysize, xsize);
if ( ! imTemp3) {
ImagingDelete(imTemp2);
return NULL; return NULL;
}
/* second pass */ /* second pass */
if ( ! ImagingStretchHorizaontal(imTemp3, imTemp2, filter)) { imTemp3 = ImagingStretchHorizaontal(imTemp2, ysize, filter);
ImagingDelete(imTemp2);
ImagingDelete(imTemp3);
return NULL;
}
ImagingDelete(imTemp2); ImagingDelete(imTemp2);
if ( ! imTemp3)
return NULL;
/* transpose result */ /* transpose result */
if ( ! ImagingTranspose(imOut, imTemp3)) { imOut = ImagingTransposeToNew(imTemp3);
ImagingDelete(imTemp3);
return NULL;
}
ImagingDelete(imTemp3); ImagingDelete(imTemp3);
if ( ! imOut)
return NULL;
return imOut; return imOut;
} }

View File

@ -291,7 +291,7 @@ extern Imaging ImagingRotate(
extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn); extern Imaging ImagingRotate90(Imaging imOut, Imaging imIn);
extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn); extern Imaging ImagingRotate180(Imaging imOut, Imaging imIn);
extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn); extern Imaging ImagingRotate270(Imaging imOut, Imaging imIn);
extern Imaging ImagingStretch(Imaging imOut, Imaging imIn, int filter); extern Imaging ImagingStretch(Imaging imIn, int xsize, int ysize, int filter);
extern Imaging ImagingTranspose(Imaging imOut, Imaging imIn); extern Imaging ImagingTranspose(Imaging imOut, Imaging imIn);
extern Imaging ImagingTransformPerspective( extern Imaging ImagingTransformPerspective(
Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1, Imaging imOut, Imaging imIn, int x0, int y0, int x1, int y1,