mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-03 05:04:24 +03:00
optimize memory usage
This commit is contained in:
parent
e9fc720709
commit
c22af89ef0
13
_imaging.c
13
_imaging.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user