diff --git a/_imaging.c b/_imaging.c index 610710bd1..6276bc678 100644 --- a/_imaging.c +++ b/_imaging.c @@ -1366,7 +1366,7 @@ _putpalette(ImagingObject* self, PyObject* args) char* rawmode; UINT8* palette; int palettesize; - if (!PyArg_ParseTuple(args, "ss#", &rawmode, &palette, &palettesize)) + if (!PyArg_ParseTuple(args, "s"PY_ARG_BYTES_LENGTH, &rawmode, &palette, &palettesize)) return NULL; if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) { @@ -1861,8 +1861,9 @@ _getprojection(ImagingObject* self, PyObject* args) ImagingGetProjection(self->image, (unsigned char *)xprofile, (unsigned char *)yprofile); - result = Py_BuildValue("s#s#", xprofile, self->image->xsize, - yprofile, self->image->ysize); + result = Py_BuildValue(PY_ARG_BYTES_LENGTH PY_ARG_BYTES_LENGTH, + xprofile, self->image->xsize, + yprofile, self->image->ysize); free(xprofile); free(yprofile); @@ -2089,7 +2090,7 @@ _font_new(PyObject* self_, PyObject* args) ImagingObject* imagep; unsigned char* glyphdata; int glyphdata_length; - if (!PyArg_ParseTuple(args, "O!s#", + if (!PyArg_ParseTuple(args, "O!"PY_ARG_BYTES_LENGTH, &Imaging_Type, &imagep, &glyphdata, &glyphdata_length)) return NULL; @@ -2787,7 +2788,8 @@ _crc32(PyObject* self, PyObject* args) hi = lo = 0; - if (!PyArg_ParseTuple(args, "s#|(ii)", &buffer, &bytes, &hi, &lo)) + if (!PyArg_ParseTuple(args, PY_ARG_BYTES_LENGTH"|(ii)", + &buffer, &bytes, &hi, &lo)) return NULL; crc = ((UINT32) (hi & 0xFFFF) << 16) + (lo & 0xFFFF); diff --git a/_imagingcms.c b/_imagingcms.c index 693de5c3b..910dc6eeb 100644 --- a/_imagingcms.c +++ b/_imagingcms.c @@ -129,8 +129,13 @@ cms_profile_fromstring(PyObject* self, PyObject* args) char* pProfile; int nProfile; +#if PY_VERSION_HEX >= 0x03000000 + if (!PyArg_ParseTuple(args, "y#:profile_frombytes", &pProfile, &nProfile)) + return NULL; +#else if (!PyArg_ParseTuple(args, "s#:profile_fromstring", &pProfile, &nProfile)) return NULL; +#endif cmsErrorAction(LCMS_ERROR_IGNORE); @@ -496,7 +501,11 @@ cms_get_display_profile_win32(PyObject* self, PyObject* args) static PyMethodDef pyCMSdll_methods[] = { {"profile_open", cms_profile_open, 1}, +#if PY_VERSION_HEX >= 0x03000000 + {"profile_frombytes", cms_profile_fromstring, 1}, +#else {"profile_fromstring", cms_profile_fromstring, 1}, +#endif /* profile and transform functions */ {"buildTransform", buildTransform, 1}, diff --git a/decode.c b/decode.c index 6f5fe278f..0b2be8dfd 100644 --- a/decode.c +++ b/decode.c @@ -37,6 +37,7 @@ #endif #include "Imaging.h" +#include "py3.h" #include "Gif.h" #include "Lzw.h" @@ -111,7 +112,7 @@ _decode(ImagingDecoderObject* decoder, PyObject* args) UINT8* buffer; int bufsize, status; - if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize)) + if (!PyArg_ParseTuple(args, PY_ARG_BYTES_LENGTH, &buffer, &bufsize)) return NULL; status = decoder->decode(decoder->im, &decoder->state, buffer, bufsize); diff --git a/display.c b/display.c index b334fbc95..9571b1cbe 100644 --- a/display.c +++ b/display.c @@ -31,6 +31,7 @@ #endif #include "Imaging.h" +#include "py3.h" /* -------------------------------------------------------------------- */ /* Windows DIB support */ @@ -183,8 +184,14 @@ _fromstring(ImagingDisplayObject* display, PyObject* args) { char* ptr; int bytes; + +#if PY_VERSION_HEX >= 0x03000000 + if (!PyArg_ParseTuple(args, "y#:frombytes", &ptr, &bytes)) + return NULL; +#else if (!PyArg_ParseTuple(args, "s#:fromstring", &ptr, &bytes)) - return NULL; + return NULL; +#endif if (display->dib->ysize * display->dib->linesize != bytes) { PyErr_SetString(PyExc_ValueError, "wrong size"); @@ -200,10 +207,15 @@ _fromstring(ImagingDisplayObject* display, PyObject* args) static PyObject* _tostring(ImagingDisplayObject* display, PyObject* args) { +#if PY_VERSION_HEX >= 0x03000000 + if (!PyArg_ParseTuple(args, ":tobytes")) + return NULL; +#else if (!PyArg_ParseTuple(args, ":tostring")) - return NULL; + return NULL; +#endif - return PyString_FromStringAndSize( + return PyBytes_FromStringAndSize( display->dib->bits, display->dib->ysize * display->dib->linesize ); } @@ -215,8 +227,13 @@ static struct PyMethodDef methods[] = { {"query_palette", (PyCFunction)_query_palette, 1}, {"getdc", (PyCFunction)_getdc, 1}, {"releasedc", (PyCFunction)_releasedc, 1}, +#if PY_VERSION_HEX >= 0x03000000 + {"frombytes", (PyCFunction)_fromstring, 1}, + {"tobytes", (PyCFunction)_tostring, 1}, +#else {"fromstring", (PyCFunction)_fromstring, 1}, {"tostring", (PyCFunction)_tostring, 1}, +#endif {NULL, NULL} /* sentinel */ }; @@ -771,7 +788,7 @@ PyImaging_DrawWmf(PyObject* self, PyObject* args) int datasize; int width, height; int x0, y0, x1, y1; - if (!PyArg_ParseTuple(args, "s#(ii)(iiii):_load", &data, &datasize, + if (!PyArg_ParseTuple(args, PY_ARG_BYTES_LENGTH"(ii)(iiii):_load", &data, &datasize, &width, &height, &x0, &x1, &y0, &y1)) return NULL; diff --git a/encode.c b/encode.c index 939fc6b93..670bd7dc9 100644 --- a/encode.c +++ b/encode.c @@ -30,6 +30,7 @@ #endif #include "Imaging.h" +#include "py3.h" #include "Gif.h" #ifdef HAVE_UNISTD_H @@ -451,9 +452,21 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args) int optimize = 0; char* dictionary = NULL; int dictionary_size = 0; - if (!PyArg_ParseTuple(args, "ss|is#", &mode, &rawmode, &optimize, - &dictionary, &dictionary_size)) - return NULL; + if (!PyArg_ParseTuple(args, "ss|i"PY_ARG_BYTES_LENGTH, &mode, &rawmode, + &optimize, &dictionary, &dictionary_size)) + return NULL; + + /* Copy to avoid referencing Python's memory, but there's no mechanism to + free this memory later, so this function (and several others here) + leaks. */ + if (dictionary && dictionary_size > 0) { + char* p = malloc(dictionary_size); + if (!p) + return PyErr_NoMemory(); + memcpy(p, dictionary, dictionary_size); + dictionary = p; + } else + dictionary = NULL; encoder = PyImaging_EncoderNew(sizeof(ZIPSTATE)); if (encoder == NULL) @@ -513,8 +526,9 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args) int xdpi = 0, ydpi = 0; int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */ char* extra = NULL; int extra_size; - if (!PyArg_ParseTuple(args, "ss|iiiiiiiis#", &mode, &rawmode, &quality, - &progressive, &smooth, &optimize, &streamtype, + if (!PyArg_ParseTuple(args, "ss|iiiiiiii"PY_ARG_BYTES_LENGTH, + &mode, &rawmode, &quality, + &progressive, &smooth, &optimize, &streamtype, &xdpi, &ydpi, &subsampling, &extra, &extra_size)) return NULL; diff --git a/py3.h b/py3.h index a0054bb46..e0658b0bb 100644 --- a/py3.h +++ b/py3.h @@ -11,13 +11,16 @@ */ #if PY_VERSION_HEX >= 0x03000000 +#define PY_ARG_BYTES_LENGTH "y#" + /* Map PyInt -> PyLong */ #define PyInt_AsLong PyLong_AsLong #define PyInt_Check PyLong_Check #define PyInt_FromLong PyLong_FromLong #define PyInt_AS_LONG PyLong_AS_LONG -#else +#else /* PY_VERSION_HEX < 0x03000000 */ +#define PY_ARG_BYTES_LENGTH "s#" #if !defined(KEEP_PY_UNICODE) /* Map PyUnicode -> PyString */