mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-12 18:26:17 +03:00
Merge pull request #221 from wiredfool/jpeg_memoryleak
Jpeg Decode memory leak fix.
This commit is contained in:
commit
aea9570a2c
|
@ -209,6 +209,10 @@ class ImageFile(Image.Image):
|
||||||
if not s: # truncated jpeg
|
if not s: # truncated jpeg
|
||||||
self.tile = []
|
self.tile = []
|
||||||
|
|
||||||
|
# JpegDecode needs to clean things up here either way
|
||||||
|
# If we don't destroy the decompressor, we have a memory leak.
|
||||||
|
d.cleanup()
|
||||||
|
|
||||||
if LOAD_TRUNCATED_IMAGES:
|
if LOAD_TRUNCATED_IMAGES:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
20
decode.c
20
decode.c
|
@ -48,6 +48,7 @@ typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
int (*decode)(Imaging im, ImagingCodecState state,
|
int (*decode)(Imaging im, ImagingCodecState state,
|
||||||
UINT8* buffer, int bytes);
|
UINT8* buffer, int bytes);
|
||||||
|
int (*cleanup)(ImagingCodecState state);
|
||||||
struct ImagingCodecStateInstance state;
|
struct ImagingCodecStateInstance state;
|
||||||
Imaging im;
|
Imaging im;
|
||||||
PyObject* lock;
|
PyObject* lock;
|
||||||
|
@ -89,6 +90,9 @@ PyImaging_DecoderNew(int contextsize)
|
||||||
decoder->lock = NULL;
|
decoder->lock = NULL;
|
||||||
decoder->im = NULL;
|
decoder->im = NULL;
|
||||||
|
|
||||||
|
/* Initialize the cleanup function pointer */
|
||||||
|
decoder->cleanup = NULL;
|
||||||
|
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +119,20 @@ _decode(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
return Py_BuildValue("ii", status, decoder->state.errcode);
|
return Py_BuildValue("ii", status, decoder->state.errcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
_decode_cleanup(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
if (decoder->cleanup){
|
||||||
|
status = decoder->cleanup(&decoder->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Py_BuildValue("i", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern Imaging PyImaging_AsImaging(PyObject *op);
|
extern Imaging PyImaging_AsImaging(PyObject *op);
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
@ -178,6 +196,7 @@ _setimage(ImagingDecoderObject* decoder, PyObject* args)
|
||||||
|
|
||||||
static struct PyMethodDef methods[] = {
|
static struct PyMethodDef methods[] = {
|
||||||
{"decode", (PyCFunction)_decode, 1},
|
{"decode", (PyCFunction)_decode, 1},
|
||||||
|
{"cleanup", (PyCFunction)_decode_cleanup, 1},
|
||||||
{"setimage", (PyCFunction)_setimage, 1},
|
{"setimage", (PyCFunction)_setimage, 1},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
@ -755,6 +774,7 @@ PyImaging_JpegDecoderNew(PyObject* self, PyObject* args)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
decoder->decode = ImagingJpegDecode;
|
decoder->decode = ImagingJpegDecode;
|
||||||
|
decoder->cleanup = ImagingJpegDecodeCleanup;
|
||||||
|
|
||||||
strncpy(((JPEGSTATE*)decoder->state.context)->rawmode, rawmode, 8);
|
strncpy(((JPEGSTATE*)decoder->state.context)->rawmode, rawmode, 8);
|
||||||
strncpy(((JPEGSTATE*)decoder->state.context)->jpegmode, jpegmode, 8);
|
strncpy(((JPEGSTATE*)decoder->state.context)->jpegmode, jpegmode, 8);
|
||||||
|
|
|
@ -417,6 +417,8 @@ extern int ImagingHexDecode(Imaging im, ImagingCodecState state,
|
||||||
#ifdef HAVE_LIBJPEG
|
#ifdef HAVE_LIBJPEG
|
||||||
extern int ImagingJpegDecode(Imaging im, ImagingCodecState state,
|
extern int ImagingJpegDecode(Imaging im, ImagingCodecState state,
|
||||||
UINT8* buffer, int bytes);
|
UINT8* buffer, int bytes);
|
||||||
|
extern int ImagingJpegDecodeCleanup(ImagingCodecState state);
|
||||||
|
|
||||||
extern int ImagingJpegEncode(Imaging im, ImagingCodecState state,
|
extern int ImagingJpegEncode(Imaging im, ImagingCodecState state,
|
||||||
UINT8* buffer, int bytes);
|
UINT8* buffer, int bytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -263,5 +263,20 @@ ImagingJpegDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/* Cleanup */
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int ImagingJpegDecodeCleanup(ImagingCodecState state){
|
||||||
|
/* called to fee the decompression engine when the decode terminates
|
||||||
|
due to a corrupt or truncated image
|
||||||
|
*/
|
||||||
|
JPEGSTATE* context = (JPEGSTATE*) state->context;
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
jpeg_destroy_decompress(&context->cinfo);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user