py3k: Use "y#" code in PyArg_ParseTuple where we expect byte data

This commit also renames some functions from "fromstring" and the like to
"frombytes". I'll probably need to come back later and update any
references to "string," here or in the docs.

I also noticed that encode allocates some data for certain codecs, but
never frees them. That would be a good bug to fix. I fixed the one where it
outright stole a pointer from Python.
This commit is contained in:
Brian Crowell 2012-10-14 11:38:06 -05:00 committed by Brian Crowell
parent 4459715b6e
commit 9631d42b60
6 changed files with 62 additions and 16 deletions

View File

@ -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,7 +1861,8 @@ _getprojection(ImagingObject* self, PyObject* args)
ImagingGetProjection(self->image, (unsigned char *)xprofile, (unsigned char *)yprofile);
result = Py_BuildValue("s#s#", xprofile, self->image->xsize,
result = Py_BuildValue(PY_ARG_BYTES_LENGTH PY_ARG_BYTES_LENGTH,
xprofile, self->image->xsize,
yprofile, self->image->ysize);
free(xprofile);
@ -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);

View File

@ -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},

View File

@ -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);

View File

@ -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;
#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;
#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;

View File

@ -30,6 +30,7 @@
#endif
#include "Imaging.h"
#include "py3.h"
#include "Gif.h"
#ifdef HAVE_UNISTD_H
@ -451,10 +452,22 @@ 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))
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)
return NULL;
@ -513,7 +526,8 @@ 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,
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;

5
py3.h
View File

@ -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 */