From 103cf49c910b62660b9c9f03b19484462aea4c7d Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 31 Jan 2013 14:52:15 +0900 Subject: [PATCH 01/31] Fix rendered characters have been chipped for some TrueType fonts ImageFont ignores descender value of TrueType fonts (uses ascender only), then some fonts which use descender is chipped on rendering. --- _imagingft.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_imagingft.c b/_imagingft.c index f54e38553..5dcd20e37 100644 --- a/_imagingft.c +++ b/_imagingft.c @@ -282,7 +282,7 @@ font_render(FontObject* self, PyObject* args) { int i, x, y; Imaging im; - int index, error, ascender; + int index, error, ascender, descender; int load_flags; unsigned char *source; FT_ULong ch; @@ -332,6 +332,7 @@ font_render(FontObject* self, PyObject* args) int xx, x0, x1; source = (unsigned char*) glyph->bitmap.buffer; ascender = PIXEL(self->face->size->metrics.ascender); + descender = PIXEL(self->face->size->metrics.descender); xx = x + glyph->bitmap_left; x0 = 0; x1 = glyph->bitmap.width; @@ -340,7 +341,7 @@ font_render(FontObject* self, PyObject* args) if (xx + x1 > im->xsize) x1 = im->xsize - xx; for (y = 0; y < glyph->bitmap.rows; y++) { - int yy = y + ascender - glyph->bitmap_top; + int yy = y + ascender + descender - glyph->bitmap_top; if (yy >= 0 && yy < im->ysize) { /* blend this glyph into the buffer */ unsigned char *target = im->image8[yy] + xx; @@ -361,6 +362,7 @@ font_render(FontObject* self, PyObject* args) int xx, x0, x1; source = (unsigned char*) glyph->bitmap.buffer; ascender = PIXEL(self->face->size->metrics.ascender); + descender = PIXEL(self->face->size->metrics.descender); xx = x + glyph->bitmap_left; x0 = 0; x1 = glyph->bitmap.width; @@ -369,7 +371,7 @@ font_render(FontObject* self, PyObject* args) if (xx + x1 > im->xsize) x1 = im->xsize - xx; for (y = 0; y < glyph->bitmap.rows; y++) { - int yy = y + ascender - glyph->bitmap_top; + int yy = y + ascender + descender - glyph->bitmap_top; if (yy >= 0 && yy < im->ysize) { /* blend this glyph into the buffer */ int i; From 1ff2b6630a3d2e05a1f834b65ce2903689a2992f Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Thu, 21 Mar 2013 16:54:04 +0100 Subject: [PATCH 02/31] fixed bug with png-images with transparency palette --- PIL/PngImagePlugin.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index d556360a9..ace71d21d 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -550,11 +550,11 @@ def _save(im, fp, filename, chunk=putchunk, check=0): if "transparency" in im.encoderinfo: if im.mode == "P": - transparency = max(0, min(255, im.encoderinfo["transparency"])) - alpha = b'\xFF' * transparency + b'\0' - # limit to actual palette size - alpha_bytes = 2**bits - chunk(fp, b"tRNS", alpha[:alpha_bytes]) + if isinstance(im.encoderinfo["transparency"], bytes): + chunk(fp, b"tRNS", b'\xFF' + im.encoderinfo["transparency"] + b'\0') + else: + transparency = max(0, min(255, im.encoderinfo["transparency"])) + chunk(fp, b"tRNS", b'\xFF' + transparency + b'\0') elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, b"tRNS", o16(transparency)) From 09315f263bc69ae76340679c1f34e83591ab28c8 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Thu, 21 Mar 2013 18:16:00 +0100 Subject: [PATCH 03/31] fixing save of transparency palette png-images --- PIL/PngImagePlugin.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index ace71d21d..bc1aff262 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -550,11 +550,14 @@ def _save(im, fp, filename, chunk=putchunk, check=0): if "transparency" in im.encoderinfo: if im.mode == "P": + # limit to actual palette size + alpha_bytes = 2**bits if isinstance(im.encoderinfo["transparency"], bytes): - chunk(fp, b"tRNS", b'\xFF' + im.encoderinfo["transparency"] + b'\0') + chunk(fp, b"tRNS", im.encoderinfo["transparency"][:alpha_bytes]) else: - transparency = max(0, min(255, im.encoderinfo["transparency"])) - chunk(fp, b"tRNS", b'\xFF' + transparency + b'\0') + transparency = max(0, min(255, im.encoderinfo["transparency"])) + alpha = b'\xFF' * transparency + b'\0' + chunk(fp, b"tRNS", alpha[:alpha_bytes]) elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, b"tRNS", o16(transparency)) From 1a40613ca5ad506a32efdb008793eaaca54f8bcb Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Thu, 21 Mar 2013 18:43:22 +0100 Subject: [PATCH 04/31] fix indention --- PIL/PngImagePlugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index bc1aff262..d1f7ac974 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -555,9 +555,9 @@ def _save(im, fp, filename, chunk=putchunk, check=0): if isinstance(im.encoderinfo["transparency"], bytes): chunk(fp, b"tRNS", im.encoderinfo["transparency"][:alpha_bytes]) else: - transparency = max(0, min(255, im.encoderinfo["transparency"])) - alpha = b'\xFF' * transparency + b'\0' - chunk(fp, b"tRNS", alpha[:alpha_bytes]) + transparency = max(0, min(255, im.encoderinfo["transparency"])) + alpha = b'\xFF' * transparency + b'\0' + chunk(fp, b"tRNS", alpha[:alpha_bytes]) elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, b"tRNS", o16(transparency)) From ecd55629bef7234332b9fa6ca93de311819bf7f2 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Thu, 21 Mar 2013 18:47:37 +0100 Subject: [PATCH 05/31] fix indention --- PIL/PngImagePlugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index d1f7ac974..65c0759e5 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -550,7 +550,7 @@ def _save(im, fp, filename, chunk=putchunk, check=0): if "transparency" in im.encoderinfo: if im.mode == "P": - # limit to actual palette size + # limit to actual palette size alpha_bytes = 2**bits if isinstance(im.encoderinfo["transparency"], bytes): chunk(fp, b"tRNS", im.encoderinfo["transparency"][:alpha_bytes]) From ccec2f02a5b7ec80f46fbc2788b84e93927ff55b Mon Sep 17 00:00:00 2001 From: Bouke Haarsma Date: Thu, 21 Mar 2013 19:02:21 +0100 Subject: [PATCH 06/31] Added link to travis-ci page --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index a61e4cb1d..a9679a5c3 100644 --- a/README.rst +++ b/README.rst @@ -4,6 +4,7 @@ Pillow .. Note:: Pillow >= 2.0.0 supports Python versions: 2.6, 2.7, 3.2, 3.3; Pillow < 2.0.0 supports Python versions: 2.4, 2.5, 2.6, 2.7. .. image:: https://travis-ci.org/python-imaging/Pillow.png + :target: https://travis-ci.org/python-imaging/Pillow Pillow is the "friendly" PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors. From 511adfacf7780054c9c31639c527f0c33bf32136 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Thu, 21 Mar 2013 21:00:25 +0100 Subject: [PATCH 07/31] fix png decode tRNS pattern --- PIL/PngImagePlugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index 65c0759e5..7ed018878 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -70,7 +70,7 @@ _MODES = { } -_simple_palette = re.compile(b'^\xff+\x00+$') +_simple_palette = re.compile(b'^\xff+\x00\xff*$') # -------------------------------------------------------------------- # Support classes. Suitable for PNG and related formats like MNG etc. From e3cb3074ce04a800259bd0762aecc47c3491c448 Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Fri, 22 Mar 2013 01:58:19 +0100 Subject: [PATCH 08/31] Add tempfile for test output --- Tests/test_file_tiff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index 1b1e8457b..6db12c4ff 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -126,7 +126,7 @@ def test_g4_write(): file = "Tests/images/lena_g4_500.tif" orig = Image.open(file) - out = "temp.tif" + out = tempfile("temp.tif") rot = orig.transpose(Image.ROTATE_90) assert_equal(rot.size,(500,500)) rot.save(out) From 638889cae0ed5c2f314d812d9148892a8c749a36 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Fri, 22 Mar 2013 15:22:18 +0100 Subject: [PATCH 09/31] replaced tabs with space in _imaging.c --- _imaging.c | 448 ++++++++++++++++++++++++++--------------------------- 1 file changed, 224 insertions(+), 224 deletions(-) diff --git a/_imaging.c b/_imaging.c index b62cd68b3..878e4e362 100644 --- a/_imaging.c +++ b/_imaging.c @@ -100,7 +100,7 @@ /* PIL Plus extensions */ #undef WITH_CRACKCODE /* pil plus */ -#undef VERBOSE +#undef VERBOSE #define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255) @@ -109,7 +109,7 @@ #define S16(v) ((v) < 32768 ? (v) : ((v) - 65536)) /* -------------------------------------------------------------------- */ -/* OBJECT ADMINISTRATION */ +/* OBJECT ADMINISTRATION */ /* -------------------------------------------------------------------- */ typedef struct { @@ -167,12 +167,12 @@ PyImagingNew(Imaging imOut) ImagingObject* imagep; if (!imOut) - return NULL; + return NULL; imagep = PyObject_New(ImagingObject, &Imaging_Type); if (imagep == NULL) { - ImagingDelete(imOut); - return NULL; + ImagingDelete(imOut); + return NULL; } #ifdef VERBOSE @@ -204,8 +204,8 @@ _dealloc(ImagingObject* imagep) Imaging PyImaging_AsImaging(PyObject *op) { if (!PyImaging_Check(op)) { - PyErr_BadInternalCall(); - return NULL; + PyErr_BadInternalCall(); + return NULL; } return ((ImagingObject *)op)->image; @@ -334,7 +334,7 @@ ImagingError_Clear(void) } /* -------------------------------------------------------------------- */ -/* HELPERS */ +/* HELPERS */ /* -------------------------------------------------------------------- */ static int @@ -367,14 +367,14 @@ getlist(PyObject* arg, int* length, const char* wrong_length, int type) void* list; if (!PySequence_Check(arg)) { - PyErr_SetString(PyExc_TypeError, must_be_sequence); - return NULL; + PyErr_SetString(PyExc_TypeError, must_be_sequence); + return NULL; } n = PyObject_Length(arg); if (length && wrong_length && n != *length) { - PyErr_SetString(PyExc_ValueError, wrong_length); - return NULL; + PyErr_SetString(PyExc_ValueError, wrong_length); + return NULL; } list = malloc(n * (type & 0xff)); @@ -467,8 +467,8 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) } pixel; if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return NULL; + PyErr_SetString(PyExc_IndexError, outside_image); + return NULL; } access->get_pixel(im, x, y, &pixel); @@ -585,7 +585,7 @@ getink(PyObject* color, Imaging im, char* ink) } /* -------------------------------------------------------------------- */ -/* FACTORIES */ +/* FACTORIES */ /* -------------------------------------------------------------------- */ static PyObject* @@ -601,7 +601,7 @@ _fill(PyObject* self, PyObject* args) color = NULL; if (!PyArg_ParseTuple(args, "s|(ii)O", &mode, &xsize, &ysize, &color)) - return NULL; + return NULL; im = ImagingNew(mode, xsize, ysize); if (!im) @@ -627,7 +627,7 @@ _new(PyObject* self, PyObject* args) int xsize, ysize; if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; + return NULL; return PyImagingNew(ImagingNew(mode, xsize, ysize)); } @@ -639,7 +639,7 @@ _new_array(PyObject* self, PyObject* args) int xsize, ysize; if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; + return NULL; return PyImagingNew(ImagingNewArray(mode, xsize, ysize)); } @@ -651,7 +651,7 @@ _new_block(PyObject* self, PyObject* args) int xsize, ysize; if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize)) - return NULL; + return NULL; return PyImagingNew(ImagingNewBlock(mode, xsize, ysize)); } @@ -660,7 +660,7 @@ static PyObject* _getcount(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, ":getcount")) - return NULL; + return NULL; return PyInt_FromLong(ImagingNewCount); } @@ -671,7 +671,7 @@ _linear_gradient(PyObject* self, PyObject* args) char* mode; if (!PyArg_ParseTuple(args, "s", &mode)) - return NULL; + return NULL; return PyImagingNew(ImagingFillLinearGradient(mode)); } @@ -682,7 +682,7 @@ _radial_gradient(PyObject* self, PyObject* args) char* mode; if (!PyArg_ParseTuple(args, "s", &mode)) - return NULL; + return NULL; return PyImagingNew(ImagingFillRadialGradient(mode)); } @@ -693,7 +693,7 @@ _open_ppm(PyObject* self, PyObject* args) char* filename; if (!PyArg_ParseTuple(args, "s", &filename)) - return NULL; + return NULL; return PyImagingNew(ImagingOpenPPM(filename)); } @@ -705,9 +705,9 @@ _alpha_composite(ImagingObject* self, PyObject* args) ImagingObject* imagep2; if (!PyArg_ParseTuple(args, "O!O!", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2)) - return NULL; + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2)) + return NULL; return PyImagingNew(ImagingAlphaComposite(imagep1->image, imagep2->image)); } @@ -721,17 +721,17 @@ _blend(ImagingObject* self, PyObject* args) alpha = 0.5; if (!PyArg_ParseTuple(args, "O!O!|d", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2, - &alpha)) - return NULL; + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2, + &alpha)) + return NULL; return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image, - (float) alpha)); + (float) alpha)); } /* -------------------------------------------------------------------- */ -/* METHODS */ +/* METHODS */ /* -------------------------------------------------------------------- */ static PyObject* @@ -742,16 +742,16 @@ _convert(ImagingObject* self, PyObject* args) ImagingObject *paletteimage = NULL; if (!PyArg_ParseTuple(args, "s|iO", &mode, &dither, &paletteimage)) - return NULL; + return NULL; if (paletteimage != NULL) { if (!PyImaging_Check(paletteimage)) { - PyObject_Print((PyObject *)paletteimage, stderr, 0); - PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'"); - return NULL; + PyObject_Print((PyObject *)paletteimage, stderr, 0); + PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'"); + return NULL; } if (paletteimage->image->palette == NULL) { - PyErr_SetString(PyExc_ValueError, "null palette"); - return NULL; + PyErr_SetString(PyExc_ValueError, "null palette"); + return NULL; } } @@ -764,9 +764,9 @@ _convert2(ImagingObject* self, PyObject* args) ImagingObject* imagep1; ImagingObject* imagep2; if (!PyArg_ParseTuple(args, "O!O!", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2)) - return NULL; + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2)) + return NULL; if (!ImagingConvert2(imagep1->image, imagep2->image)) return NULL; @@ -781,12 +781,12 @@ _convert_matrix(ImagingObject* self, PyObject* args) char* mode; float m[12]; if (!PyArg_ParseTuple(args, "s(ffff)", &mode, m+0, m+1, m+2, m+3)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "s(ffffffffffff)", &mode, - m+0, m+1, m+2, m+3, - m+4, m+5, m+6, m+7, - m+8, m+9, m+10, m+11)) - return NULL; + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "s(ffffffffffff)", &mode, + m+0, m+1, m+2, m+3, + m+4, m+5, m+6, m+7, + m+8, m+9, m+10, m+11)) + return NULL; } return PyImagingNew(ImagingConvertMatrix(self->image, mode, m)); @@ -796,7 +796,7 @@ static PyObject* _copy(ImagingObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, "")) - return NULL; + return NULL; return PyImagingNew(ImagingCopy(self->image)); } @@ -807,9 +807,9 @@ _copy2(ImagingObject* self, PyObject* args) ImagingObject* imagep1; ImagingObject* imagep2; if (!PyArg_ParseTuple(args, "O!O!", - &Imaging_Type, &imagep1, - &Imaging_Type, &imagep2)) - return NULL; + &Imaging_Type, &imagep1, + &Imaging_Type, &imagep2)) + return NULL; if (!ImagingCopy2(imagep1->image, imagep2->image)) return NULL; @@ -823,7 +823,7 @@ _crop(ImagingObject* self, PyObject* args) { int x0, y0, x1, y1; if (!PyArg_ParseTuple(args, "(iiii)", &x0, &y0, &x1, &y1)) - return NULL; + return NULL; return PyImagingNew(ImagingCrop(self->image, x0, y0, x1, y1)); } @@ -834,7 +834,7 @@ _expand(ImagingObject* self, PyObject* args) int x, y; int mode = 0; if (!PyArg_ParseTuple(args, "ii|i", &x, &y, &mode)) - return NULL; + return NULL; return PyImagingNew(ImagingExpand(self->image, x, y, mode)); } @@ -905,25 +905,25 @@ _getpalette(ImagingObject* self, PyObject* args) char* mode = "RGB"; char* rawmode = "RGB"; if (!PyArg_ParseTuple(args, "|ss", &mode, &rawmode)) - return NULL; + return NULL; if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; } pack = ImagingFindPacker(mode, rawmode, &bits); if (!pack) { - PyErr_SetString(PyExc_ValueError, wrong_raw_mode); - return NULL; + PyErr_SetString(PyExc_ValueError, wrong_raw_mode); + return NULL; } palette = PyBytes_FromStringAndSize(NULL, palettesize * bits / 8); if (!palette) - return NULL; + return NULL; pack((UINT8*) PyBytes_AsString(palette), - self->image->palette->palette, palettesize); + self->image->palette->palette, palettesize); return palette; } @@ -932,8 +932,8 @@ static PyObject* _getpalettemode(ImagingObject* self, PyObject* args) { if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; } return PyUnicode_FromString(self->image->palette->mode); @@ -1025,7 +1025,7 @@ _histogram(ImagingObject* self, PyObject* args) PyObject* extremap = NULL; ImagingObject* maskp = NULL; if (!PyArg_ParseTuple(args, "|OO!", &extremap, &Imaging_Type, &maskp)) - return NULL; + return NULL; if (extremap) { ep = &extrema; @@ -1059,19 +1059,19 @@ _histogram(ImagingObject* self, PyObject* args) h = ImagingGetHistogram(self->image, (maskp) ? maskp->image : NULL, ep); if (!h) - return NULL; + return NULL; /* Build an integer list containing the histogram */ list = PyList_New(h->bands * 256); for (i = 0; i < h->bands * 256; i++) { - PyObject* item; - item = PyInt_FromLong(h->histogram[i]); - if (item == NULL) { - Py_DECREF(list); - list = NULL; - break; - } - PyList_SetItem(list, i, item); + PyObject* item; + item = PyInt_FromLong(h->histogram[i]); + if (item == NULL) { + Py_DECREF(list); + list = NULL; + break; + } + PyList_SetItem(list, i, item); } ImagingHistogramDelete(h); @@ -1085,7 +1085,7 @@ _modefilter(ImagingObject* self, PyObject* args) { int size; if (!PyArg_ParseTuple(args, "i", &size)) - return NULL; + return NULL; return PyImagingNew(ImagingModeFilter(self->image, size)); } @@ -1096,7 +1096,7 @@ _offset(ImagingObject* self, PyObject* args) { int xoffset, yoffset; if (!PyArg_ParseTuple(args, "ii", &xoffset, &yoffset)) - return NULL; + return NULL; return PyImagingNew(ImagingOffset(self->image, xoffset, yoffset)); } @@ -1111,10 +1111,10 @@ _paste(ImagingObject* self, PyObject* args) int x0, y0, x1, y1; ImagingObject* maskp = NULL; if (!PyArg_ParseTuple(args, "O(iiii)|O!", - &source, - &x0, &y0, &x1, &y1, - &Imaging_Type, &maskp)) - return NULL; + &source, + &x0, &y0, &x1, &y1, + &Imaging_Type, &maskp)) + return NULL; if (PyImaging_Check(source)) status = ImagingPaste( @@ -1152,7 +1152,7 @@ _point(ImagingObject* self, PyObject* args) PyObject* list; char* mode; if (!PyArg_ParseTuple(args, "Oz", &list, &mode)) - return NULL; + return NULL; if (mode && !strcmp(mode, "F")) { FLOAT32* data; @@ -1223,7 +1223,7 @@ _point_transform(ImagingObject* self, PyObject* args) double scale = 1.0; double offset = 0.0; if (!PyArg_ParseTuple(args, "|dd", &scale, &offset)) - return NULL; + return NULL; return PyImagingNew(ImagingPointTransform(self->image, scale, offset)); } @@ -1242,16 +1242,16 @@ _putdata(ImagingObject* self, PyObject* args) return NULL; if (!PySequence_Check(data)) { - PyErr_SetString(PyExc_TypeError, must_be_sequence); - return NULL; + PyErr_SetString(PyExc_TypeError, must_be_sequence); + return NULL; } image = self->image; n = PyObject_Length(data); if (n > (int) (image->xsize * image->ysize)) { - PyErr_SetString(PyExc_TypeError, "too many data entries"); - return NULL; + PyErr_SetString(PyExc_TypeError, "too many data entries"); + return NULL; } if (image->image8) { @@ -1377,7 +1377,7 @@ _quantize(ImagingObject* self, PyObject* args) int method = 0; int kmeans = 0; if (!PyArg_ParseTuple(args, "|iii", &colours, &method, &kmeans)) - return NULL; + return NULL; if (!self->image->xsize || !self->image->ysize) { /* no content; return an empty image */ @@ -1400,17 +1400,17 @@ _putpalette(ImagingObject* self, PyObject* args) UINT8* palette; int palettesize; if (!PyArg_ParseTuple(args, "s"PY_ARG_BYTES_LENGTH, &rawmode, &palette, &palettesize)) - return NULL; + return NULL; if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) { - PyErr_SetString(PyExc_ValueError, wrong_mode); - return NULL; + PyErr_SetString(PyExc_ValueError, wrong_mode); + return NULL; } unpack = ImagingFindUnpacker("RGB", rawmode, &bits); if (!unpack) { - PyErr_SetString(PyExc_ValueError, wrong_raw_mode); - return NULL; + PyErr_SetString(PyExc_ValueError, wrong_raw_mode); + return NULL; } ImagingPaletteDelete(self->image->palette); @@ -1431,16 +1431,16 @@ _putpalettealpha(ImagingObject* self, PyObject* args) int index; int alpha = 0; if (!PyArg_ParseTuple(args, "i|i", &index, &alpha)) - return NULL; + return NULL; if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; } if (index < 0 || index >= 256) { - PyErr_SetString(PyExc_ValueError, outside_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, outside_palette); + return NULL; } strcpy(self->image->palette->mode, "RGBA"); @@ -1457,21 +1457,21 @@ _putpalettealphas(ImagingObject* self, PyObject* args) UINT8 *values; int length; if (!PyArg_ParseTuple(args, "s#", &values, &length)) - return NULL; + return NULL; if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; } if (length > 256) { - PyErr_SetString(PyExc_ValueError, outside_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, outside_palette); + return NULL; } strcpy(self->image->palette->mode, "RGBA"); for (i=0; iimage->palette->palette[i*4+3] = (UINT8) values[i]; + self->image->palette->palette[i*4+3] = (UINT8) values[i]; } Py_INCREF(Py_None); @@ -1487,13 +1487,13 @@ _putpixel(ImagingObject* self, PyObject* args) int x, y; PyObject* color; if (!PyArg_ParseTuple(args, "(ii)O", &x, &y, &color)) - return NULL; + return NULL; im = self->image; if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return NULL; + PyErr_SetString(PyExc_IndexError, outside_image); + return NULL; } if (!getink(color, im, ink)) @@ -1512,7 +1512,7 @@ _rankfilter(ImagingObject* self, PyObject* args) { int size, rank; if (!PyArg_ParseTuple(args, "ii", &size, &rank)) - return NULL; + return NULL; return PyImagingNew(ImagingRankFilter(self->image, size, rank)); } @@ -1527,13 +1527,13 @@ _resize(ImagingObject* self, PyObject* args) int xsize, ysize; int filter = IMAGING_TRANSFORM_NEAREST; if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) - return NULL; + return NULL; imIn = self->image; imOut = ImagingNew(imIn->mode, xsize, ysize); if (imOut) - (void) ImagingResize(imOut, imIn, filter); + (void) ImagingResize(imOut, imIn, filter); return PyImagingNew(imOut); } @@ -1547,18 +1547,18 @@ _rotate(ImagingObject* self, PyObject* args) double theta; int filter = IMAGING_TRANSFORM_NEAREST; if (!PyArg_ParseTuple(args, "d|i", &theta, &filter)) - return NULL; + return NULL; imIn = self->image; theta = fmod(theta, 360.0); if (theta < 0.0) - theta += 360; + theta += 360; if (filter && imIn->type != IMAGING_TYPE_SPECIAL) { /* Rotate with resampling filter */ imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize); - (void) ImagingRotate(imOut, imIn, theta, filter); + (void) ImagingRotate(imOut, imIn, theta, filter); } else if (theta == 90.0 || theta == 270.0) { /* Use fast version */ imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize); @@ -1599,7 +1599,7 @@ im_setmode(ImagingObject* self, PyObject* args) char* mode; int modelen; if (!PyArg_ParseTuple(args, "s#:setmode", &mode, &modelen)) - return NULL; + return NULL; im = self->image; @@ -1637,7 +1637,7 @@ _stretch(ImagingObject* self, PyObject* args) int xsize, ysize; int filter = IMAGING_TRANSFORM_NEAREST; if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter)) - return NULL; + return NULL; imIn = self->image; @@ -1691,10 +1691,10 @@ _transform2(ImagingObject* self, PyObject* args) int fill = 1; if (!PyArg_ParseTuple(args, "(iiii)O!iO|ii", &x0, &y0, &x1, &y1, - &Imaging_Type, &imagep, + &Imaging_Type, &imagep, &method, &data, &filter, &fill)) - return NULL; + return NULL; switch (method) { case IMAGING_TRANSFORM_AFFINE: @@ -1756,7 +1756,7 @@ _transpose(ImagingObject* self, PyObject* args) int op; if (!PyArg_ParseTuple(args, "i", &op)) - return NULL; + return NULL; imIn = self->image; @@ -1835,8 +1835,8 @@ _getbbox(ImagingObject* self, PyObject* args) { int bbox[4]; if (!ImagingGetBBox(self->image, bbox)) { - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } return Py_BuildValue("iiii", bbox[0], bbox[1], bbox[2], bbox[3]); @@ -1851,7 +1851,7 @@ _getcolors(ImagingObject* self, PyObject* args) int maxcolors = 256; if (!PyArg_ParseTuple(args, "i:getcolors", &maxcolors)) - return NULL; + return NULL; items = ImagingGetColors(self->image, maxcolors, &colors); if (!items) @@ -1915,9 +1915,9 @@ _getprojection(ImagingObject* self, PyObject* args) yprofile = malloc(self->image->ysize); if (xprofile == NULL || yprofile == NULL) { - free(xprofile); - free(yprofile); - return PyErr_NoMemory(); + free(xprofile); + free(yprofile); + return PyErr_NoMemory(); } ImagingGetProjection(self->image, (unsigned char *)xprofile, (unsigned char *)yprofile); @@ -1940,7 +1940,7 @@ _getband(ImagingObject* self, PyObject* args) int band; if (!PyArg_ParseTuple(args, "i", &band)) - return NULL; + return NULL; return PyImagingNew(ImagingGetBand(self->image, band)); } @@ -1952,7 +1952,7 @@ _fillband(ImagingObject* self, PyObject* args) int color; if (!PyArg_ParseTuple(args, "ii", &band, &color)) - return NULL; + return NULL; if (!ImagingFillBand(self->image, band, color)) return NULL; @@ -1967,12 +1967,12 @@ _putband(ImagingObject* self, PyObject* args) ImagingObject* imagep; int band; if (!PyArg_ParseTuple(args, "O!i", - &Imaging_Type, &imagep, - &band)) - return NULL; + &Imaging_Type, &imagep, + &band)) + return NULL; if (!ImagingPutBand(self->image, imagep->image, band)) - return NULL; + return NULL; Py_INCREF(Py_None); return Py_None; @@ -1994,7 +1994,7 @@ _chop_lighter(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopLighter(self->image, imagep->image)); } @@ -2005,7 +2005,7 @@ _chop_darker(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopDarker(self->image, imagep->image)); } @@ -2016,7 +2016,7 @@ _chop_difference(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopDifference(self->image, imagep->image)); } @@ -2027,7 +2027,7 @@ _chop_multiply(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopMultiply(self->image, imagep->image)); } @@ -2038,7 +2038,7 @@ _chop_screen(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopScreen(self->image, imagep->image)); } @@ -2054,11 +2054,11 @@ _chop_add(ImagingObject* self, PyObject* args) offset = 0; if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep, - &scale, &offset)) - return NULL; + &scale, &offset)) + return NULL; return PyImagingNew(ImagingChopAdd(self->image, imagep->image, - scale, offset)); + scale, offset)); } static PyObject* @@ -2072,11 +2072,11 @@ _chop_subtract(ImagingObject* self, PyObject* args) offset = 0; if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep, - &scale, &offset)) - return NULL; + &scale, &offset)) + return NULL; return PyImagingNew(ImagingChopSubtract(self->image, imagep->image, - scale, offset)); + scale, offset)); } static PyObject* @@ -2085,7 +2085,7 @@ _chop_and(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopAnd(self->image, imagep->image)); } @@ -2096,7 +2096,7 @@ _chop_or(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopOr(self->image, imagep->image)); } @@ -2107,7 +2107,7 @@ _chop_xor(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopXor(self->image, imagep->image)); } @@ -2118,7 +2118,7 @@ _chop_add_modulo(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopAddModulo(self->image, imagep->image)); } @@ -2129,7 +2129,7 @@ _chop_subtract_modulo(ImagingObject* self, PyObject* args) ImagingObject* imagep; if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep)) - return NULL; + return NULL; return PyImagingNew(ImagingChopSubtractModulo(self->image, imagep->image)); } @@ -2152,18 +2152,18 @@ _font_new(PyObject* self_, PyObject* args) unsigned char* glyphdata; int glyphdata_length; if (!PyArg_ParseTuple(args, "O!"PY_ARG_BYTES_LENGTH, - &Imaging_Type, &imagep, - &glyphdata, &glyphdata_length)) + &Imaging_Type, &imagep, + &glyphdata, &glyphdata_length)) return NULL; if (glyphdata_length != 256 * 20) { - PyErr_SetString(PyExc_ValueError, wrong_length); - return NULL; + PyErr_SetString(PyExc_ValueError, wrong_length); + return NULL; } self = PyObject_New(ImagingFontObject, &ImagingFont_Type); if (self == NULL) - return NULL; + return NULL; /* glyph bitmap */ self->bitmap = imagep->image; @@ -2295,7 +2295,7 @@ _draw_new(PyObject* self_, PyObject* args) self = PyObject_New(ImagingDrawObject, &ImagingDraw_Type); if (self == NULL) - return NULL; + return NULL; /* keep a reference to the image object */ Py_INCREF(imagep); @@ -2342,7 +2342,7 @@ _draw_arc(ImagingDrawObject* self, PyObject* args) if (!PyArg_ParseTuple(args, "(iiii)iii|i", &x0, &y0, &x1, &y1, &start, &end, &ink)) - return NULL; + return NULL; if (ImagingDrawArc(self->image->image, x0, y0, x1, y1, start, end, &ink, op) < 0) @@ -2362,17 +2362,17 @@ _draw_bitmap(ImagingDrawObject* self, PyObject* args) ImagingObject* bitmap; int ink; if (!PyArg_ParseTuple(args, "OO!i", &data, &Imaging_Type, &bitmap, &ink)) - return NULL; + return NULL; n = PyPath_Flatten(data, &xy); if (n < 0) - return NULL; + return NULL; if (n != 1) { - PyErr_SetString( + PyErr_SetString( PyExc_TypeError, "coordinate list must contain exactly 1 coordinate" ); - return NULL; + return NULL; } n = ImagingDrawBitmap( @@ -2397,7 +2397,7 @@ _draw_chord(ImagingDrawObject* self, PyObject* args) int start, end; if (!PyArg_ParseTuple(args, "(iiii)iiii", &x0, &y0, &x1, &y1, &start, &end, &ink, &fill)) - return NULL; + return NULL; if (ImagingDrawChord(self->image->image, x0, y0, x1, y1, start, end, &ink, fill, self->blend) < 0) @@ -2417,17 +2417,17 @@ _draw_ellipse(ImagingDrawObject* self, PyObject* args) int ink; int fill = 0; if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) - return NULL; + return NULL; n = PyPath_Flatten(data, &xy); if (n < 0) - return NULL; + return NULL; if (n != 2) { - PyErr_SetString( + PyErr_SetString( PyExc_TypeError, "coordinate list must contain exactly 2 coordinates" ); - return NULL; + return NULL; } n = ImagingDrawEllipse( @@ -2450,11 +2450,11 @@ _draw_line(ImagingDrawObject* self, PyObject* args) int x0, y0, x1, y1; int ink; if (!PyArg_ParseTuple(args, "(ii)(ii)i", &x0, &y0, &x1, &y1, &ink)) - return NULL; + return NULL; if (ImagingDrawLine(self->image->image, x0, y0, x1, y1, &ink, self->blend) < 0) - return NULL; + return NULL; Py_INCREF(Py_None); return Py_None; @@ -2470,15 +2470,15 @@ _draw_lines(ImagingDrawObject* self, PyObject* args) int ink; int width = 0; if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &width)) - return NULL; + return NULL; n = PyPath_Flatten(data, &xy); if (n < 0) - return NULL; + return NULL; if (width <= 1) { double *p = NULL; - for (i = 0; i < n-1; i++) { + for (i = 0; i < n-1; i++) { p = &xy[i+i]; if (ImagingDrawLine( self->image->image, @@ -2519,10 +2519,10 @@ _draw_point(ImagingDrawObject* self, PyObject* args) int x, y; int ink; if (!PyArg_ParseTuple(args, "(ii)i", &x, &y, &ink)) - return NULL; + return NULL; if (ImagingDrawPoint(self->image->image, x, y, &ink, self->blend) < 0) - return NULL; + return NULL; Py_INCREF(Py_None); return Py_None; @@ -2537,19 +2537,19 @@ _draw_points(ImagingDrawObject* self, PyObject* args) PyObject *data; int ink; if (!PyArg_ParseTuple(args, "Oi", &data, &ink)) - return NULL; + return NULL; n = PyPath_Flatten(data, &xy); if (n < 0) - return NULL; + return NULL; for (i = 0; i < n; i++) { - double *p = &xy[i+i]; - if (ImagingDrawPoint(self->image->image, (int) p[0], (int) p[1], + double *p = &xy[i+i]; + if (ImagingDrawPoint(self->image->image, (int) p[0], (int) p[1], &ink, self->blend) < 0) { - free(xy); - return NULL; - } + free(xy); + return NULL; + } } free(xy); @@ -2558,7 +2558,7 @@ _draw_points(ImagingDrawObject* self, PyObject* args) return Py_None; } -#ifdef WITH_ARROW +#ifdef WITH_ARROW /* from outline.c */ extern ImagingOutline PyOutline_AsOutline(PyObject* outline); @@ -2572,7 +2572,7 @@ _draw_outline(ImagingDrawObject* self, PyObject* args) int ink; int fill = 0; if (!PyArg_ParseTuple(args, "Oi|i", &outline_, &ink, &fill)) - return NULL; + return NULL; outline = PyOutline_AsOutline(outline_); if (!outline) { @@ -2582,7 +2582,7 @@ _draw_outline(ImagingDrawObject* self, PyObject* args) if (ImagingDrawOutline(self->image->image, outline, &ink, fill, self->blend) < 0) - return NULL; + return NULL; Py_INCREF(Py_None); return Py_None; @@ -2598,7 +2598,7 @@ _draw_pieslice(ImagingDrawObject* self, PyObject* args) int start, end; if (!PyArg_ParseTuple(args, "(iiii)iiii", &x0, &y0, &x1, &y1, &start, &end, &ink, &fill)) - return NULL; + return NULL; if (ImagingDrawPieslice(self->image->image, x0, y0, x1, y1, start, end, &ink, fill, self->blend) < 0) @@ -2619,33 +2619,33 @@ _draw_polygon(ImagingDrawObject* self, PyObject* args) int ink; int fill = 0; if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) - return NULL; + return NULL; n = PyPath_Flatten(data, &xy); if (n < 0) - return NULL; + return NULL; if (n < 2) { - PyErr_SetString( + PyErr_SetString( PyExc_TypeError, "coordinate list must contain at least 2 coordinates" ); - return NULL; + return NULL; } /* Copy list of vertices to array */ ixy = (int*) malloc(n * 2 * sizeof(int)); for (i = 0; i < n; i++) { - ixy[i+i] = (int) xy[i+i]; - ixy[i+i+1] = (int) xy[i+i+1]; + ixy[i+i] = (int) xy[i+i]; + ixy[i+i+1] = (int) xy[i+i+1]; } free(xy); if (ImagingDrawPolygon(self->image->image, n, ixy, &ink, fill, self->blend) < 0) { - free(ixy); - return NULL; + free(ixy); + return NULL; } free(ixy); @@ -2664,17 +2664,17 @@ _draw_rectangle(ImagingDrawObject* self, PyObject* args) int ink; int fill = 0; if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) - return NULL; + return NULL; n = PyPath_Flatten(data, &xy); if (n < 0) - return NULL; + return NULL; if (n != 2) { - PyErr_SetString( + PyErr_SetString( PyExc_TypeError, "coordinate list must contain exactly 2 coordinates" ); - return NULL; + return NULL; } n = ImagingDrawRectangle( @@ -2727,7 +2727,7 @@ pixel_access_new(ImagingObject* imagep, PyObject* args) self = PyObject_New(PixelAccessObject, &PixelAccess_Type); if (self == NULL) - return NULL; + return NULL; /* keep a reference to the image object */ Py_INCREF(imagep); @@ -2771,8 +2771,8 @@ pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) return -1; if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { - PyErr_SetString(PyExc_IndexError, outside_image); - return -1; + PyErr_SetString(PyExc_IndexError, outside_image); + return -1; } if (!color) /* FIXME: raise exception? */ @@ -2787,7 +2787,7 @@ pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) } /* -------------------------------------------------------------------- */ -/* EFFECTS (experimental) */ +/* EFFECTS (experimental) */ /* -------------------------------------------------------------------- */ #ifdef WITH_EFFECTS @@ -2806,7 +2806,7 @@ _effect_mandelbrot(ImagingObject* self, PyObject* args) if (!PyArg_ParseTuple(args, "|(ii)(dddd)i", &xsize, &ysize, &extent[0], &extent[1], &extent[2], &extent[3], &quality)) - return NULL; + return NULL; return PyImagingNew(ImagingEffectMandelbrot(xsize, ysize, extent, quality)); } @@ -2817,7 +2817,7 @@ _effect_noise(ImagingObject* self, PyObject* args) int xsize, ysize; float sigma = 128; if (!PyArg_ParseTuple(args, "(ii)|f", &xsize, &ysize, &sigma)) - return NULL; + return NULL; return PyImagingNew(ImagingEffectNoise(xsize, ysize, sigma)); } @@ -2828,7 +2828,7 @@ _effect_spread(ImagingObject* self, PyObject* args) int dist; if (!PyArg_ParseTuple(args, "i", &dist)) - return NULL; + return NULL; return PyImagingNew(ImagingEffectSpread(self->image, dist)); } @@ -2836,7 +2836,7 @@ _effect_spread(ImagingObject* self, PyObject* args) #endif /* -------------------------------------------------------------------- */ -/* UTILITIES */ +/* UTILITIES */ /* -------------------------------------------------------------------- */ static PyObject* @@ -2851,7 +2851,7 @@ _crc32(PyObject* self, PyObject* args) if (!PyArg_ParseTuple(args, PY_ARG_BYTES_LENGTH"|(ii)", &buffer, &bytes, &hi, &lo)) - return NULL; + return NULL; crc = ((UINT32) (hi & 0xFFFF) << 16) + (lo & 0xFFFF); @@ -2867,19 +2867,19 @@ _getcodecstatus(PyObject* self, PyObject* args) char* msg; if (!PyArg_ParseTuple(args, "i", &status)) - return NULL; + return NULL; switch (status) { case IMAGING_CODEC_OVERRUN: - msg = "buffer overrun"; break; + msg = "buffer overrun"; break; case IMAGING_CODEC_BROKEN: - msg = "broken data stream"; break; + msg = "broken data stream"; break; case IMAGING_CODEC_UNKNOWN: - msg = "unrecognized data stream contents"; break; + msg = "unrecognized data stream contents"; break; case IMAGING_CODEC_CONFIG: - msg = "codec configuration error"; break; + msg = "codec configuration error"; break; case IMAGING_CODEC_MEMORY: - msg = "out of memory"; break; + msg = "out of memory"; break; default: Py_RETURN_NONE; } @@ -2888,7 +2888,7 @@ _getcodecstatus(PyObject* self, PyObject* args) } /* -------------------------------------------------------------------- */ -/* DEBUGGING HELPERS */ +/* DEBUGGING HELPERS */ /* -------------------------------------------------------------------- */ @@ -2900,7 +2900,7 @@ _save_ppm(ImagingObject* self, PyObject* args) char* filename; if (!PyArg_ParseTuple(args, "s", &filename)) - return NULL; + return NULL; if (!ImagingSavePPM(self->image, filename)) return NULL; @@ -3026,19 +3026,19 @@ _getattr_mode(ImagingObject* self, void* closure) static PyObject* _getattr_size(ImagingObject* self, void* closure) { - return Py_BuildValue("ii", self->image->xsize, self->image->ysize); + return Py_BuildValue("ii", self->image->xsize, self->image->ysize); } static PyObject* _getattr_bands(ImagingObject* self, void* closure) { - return PyInt_FromLong(self->image->bands); + return PyInt_FromLong(self->image->bands); } static PyObject* _getattr_id(ImagingObject* self, void* closure) { - return PyInt_FromSsize_t((Py_ssize_t) self->image); + return PyInt_FromSsize_t((Py_ssize_t) self->image); } static PyObject* @@ -3100,12 +3100,12 @@ static PySequenceMethods image_as_sequence = { static PyTypeObject Imaging_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "ImagingCore", /*tp_name*/ - sizeof(ImagingObject), /*tp_size*/ - 0, /*tp_itemsize*/ + "ImagingCore", /*tp_name*/ + sizeof(ImagingObject), /*tp_size*/ + 0, /*tp_itemsize*/ /* methods */ - (destructor)_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + (destructor)_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -3136,12 +3136,12 @@ static PyTypeObject Imaging_Type = { static PyTypeObject ImagingFont_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "ImagingFont", /*tp_name*/ - sizeof(ImagingFontObject), /*tp_size*/ - 0, /*tp_itemsize*/ + "ImagingFont", /*tp_name*/ + sizeof(ImagingFontObject), /*tp_size*/ + 0, /*tp_itemsize*/ /* methods */ - (destructor)_font_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + (destructor)_font_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -3170,12 +3170,12 @@ static PyTypeObject ImagingFont_Type = { static PyTypeObject ImagingDraw_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "ImagingDraw", /*tp_name*/ - sizeof(ImagingDrawObject), /*tp_size*/ - 0, /*tp_itemsize*/ + "ImagingDraw", /*tp_name*/ + sizeof(ImagingDrawObject), /*tp_size*/ + 0, /*tp_itemsize*/ /* methods */ - (destructor)_draw_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + (destructor)_draw_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ From 9f9ccc16648b893fa8902553f19c4c1f68e4182f Mon Sep 17 00:00:00 2001 From: Damian Wrobel Date: Fri, 22 Mar 2013 19:51:31 +0100 Subject: [PATCH 10/31] Fixes an uninitialized value for an optional parameter. Effectively, this prevented any remote scanners to be discovered. --- Sane/_sane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sane/_sane.c b/Sane/_sane.c index c94a120a0..b424015a8 100644 --- a/Sane/_sane.c +++ b/Sane/_sane.c @@ -1202,7 +1202,7 @@ PySane_get_devices(PyObject *self, PyObject *args) const SANE_Device *dev; SANE_Status st; PyObject *list; - int local_only, i; + int local_only = 0, i; if (!PyArg_ParseTuple(args, "|i", &local_only)) { From c39a51bcf0cac30aef8b5a88e7e20718c6d66d3a Mon Sep 17 00:00:00 2001 From: homm Date: Sat, 23 Mar 2013 05:44:36 +0400 Subject: [PATCH 11/31] Significant performance improvement of `alpha_composite` function. --- libImaging/AlphaComposite.c | 97 +++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 52 deletions(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index c5801b779..8cc519d3f 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -12,81 +12,74 @@ #include "Imaging.h" +typedef struct +{ + UINT8 r; + UINT8 g; + UINT8 b; + UINT8 a; +} rgba8; + + + Imaging ImagingAlphaComposite(Imaging imDst, Imaging imSrc) { Imaging imOut; int x, y; - float dstR, dstG, dstB, dstA; - float srcR, srcG, srcB, srcA; - float outR, outG, outB, outA; /* Check arguments */ if (!imDst || !imSrc || - strcmp(imDst->mode, "RGBA") || - imDst->type != IMAGING_TYPE_UINT8 || - imDst->bands != 4) - return ImagingError_ModeError(); + strcmp(imDst->mode, "RGBA") || + imDst->type != IMAGING_TYPE_UINT8 || + imDst->bands != 4) + return ImagingError_ModeError(); + if (strcmp(imDst->mode, imSrc->mode) || - imDst->type != imSrc->type || - imDst->bands != imSrc->bands || - imDst->xsize != imSrc->xsize || - imDst->ysize != imSrc->ysize) - return ImagingError_Mismatch(); + imDst->type != imSrc->type || + imDst->bands != imSrc->bands || + imDst->xsize != imSrc->xsize || + imDst->ysize != imSrc->ysize) + return ImagingError_Mismatch(); imOut = ImagingNew(imDst->mode, imDst->xsize, imDst->ysize); if (!imOut) - return NULL; + return NULL; ImagingCopyInfo(imOut, imDst); for (y = 0; y < imDst->ysize; y++) { - UINT8* dst = (UINT8*) imDst->image[y]; - UINT8* src = (UINT8*) imSrc->image[y]; - UINT8* out = (UINT8*) imOut->image[y]; + rgba8* pdst = (rgba8*) imDst->image[y]; + rgba8* psrc = (rgba8*) imSrc->image[y]; + rgba8* pout = (rgba8*) imOut->image[y]; - for (x = 0; x < imDst->linesize; x += 4) { + for (x = 0; x < imDst->xsize; x ++) { + rgba8 src = psrc[x]; - dstR = dst[x + 0] / 255.0; - dstG = dst[x + 1] / 255.0; - dstB = dst[x + 2] / 255.0; - dstA = dst[x + 3] / 255.0; + if (src.a == 0) { + // Copy 4 bytes at once. + pout[x] = pdst[x]; + } else { + rgba8 dst = pdst[x]; + rgba8* out = &pout[x]; - srcR = src[x + 0] / 255.0; - srcG = src[x + 1] / 255.0; - srcB = src[x + 2] / 255.0; - srcA = src[x + 3] / 255.0; + // Integer implementation with increased precision. + // Each variable has extra meaningful bits. + // Divisions are rounded. - if (dstA == 1.0) { - outR = srcR * srcA + dstR * (1.0 - srcA); - outG = srcG * srcA + dstG * (1.0 - srcA); - outB = srcB * srcA + dstB * (1.0 - srcA); - outA = 1.0; - } else if (srcA == 0.0) { - outR = dstR; - outG = dstG; - outB = dstB; - outA = dstA; - } else { - outA = srcA + dstA * (1.0 - srcA); - if (outA == 0.0) { - outR = 0.0; - outG = 0.0; - outB = 0.0; - } else { - outR = (srcR * srcA + dstR * dstA * (1.0 - srcA)) / outA; - outG = (srcG * srcA + dstG * dstA * (1.0 - srcA)) / outA; - outB = (srcB * srcA + dstB * dstA * (1.0 - srcA)) / outA; - } - } + UINT16 blend = dst.a * (255 - src.a); // 16 bit max + UINT16 outa = (src.a << 4) + ((blend + 0x8) >> 4); // 12 + UINT16 coef1 = (src.a << 16) / outa; // 12 + UINT16 coef2 = (blend << 8) / outa; // 12 - out[x + 0] = (UINT8) (255.0 * outR + 0.5); - out[x + 1] = (UINT8) (255.0 * outG + 0.5); - out[x + 2] = (UINT8) (255.0 * outB + 0.5); - out[x + 3] = (UINT8) (255.0 * outA + 0.5); + out->r = (src.r * coef1 + dst.r * coef2 + 0x800) >> 12; + out->g = (src.g * coef1 + dst.g * coef2 + 0x800) >> 12; + out->b = (src.b * coef1 + dst.b * coef2 + 0x800) >> 12; + out->a = (outa + 0x8) >> 4; + } - } + } } From f432530df3e03b1c3d135f38a47b05bd954e51cf Mon Sep 17 00:00:00 2001 From: wiredfool Date: Fri, 22 Mar 2013 21:15:45 -0700 Subject: [PATCH 12/31] approximate test for lossy image writing --- Tests/test_file_webp.py | 17 ++++++++++++++--- Tests/tester.py | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Tests/test_file_webp.py b/Tests/test_file_webp.py index 460b22d9c..0d2c984b0 100644 --- a/Tests/test_file_webp.py +++ b/Tests/test_file_webp.py @@ -2,7 +2,7 @@ from tester import * from PIL import Image -def test_read(): +def xtest_read(): """ Can we write a webp without error. Does it have the bits we expect?""" file = "Images/lena.webp" @@ -37,7 +37,18 @@ def test_write(): assert_no_exception(lambda: im.load()) assert_no_exception(lambda: im.getdata()) + # If we're using the exact same version of webp, this test should pass. + # but it doesn't if the webp is generated on Ubuntu and tested on Fedora. + # generated with: dwebp -ppm temp.webp -o lena_webp_write.ppm - target = Image.open('Tests/images/lena_webp_write.ppm') - assert_image_equal(im, target) + #target = Image.open('Tests/images/lena_webp_write.ppm') + #assert_image_equal(im, target) + + # This test asserts that the images are similar. If the average pixel difference + # between the two images is less than the epsilon value, then we're going to + # accept that it's a reasonable lossy version of the image. The included lena images + # for webp are showing ~16 on Ubuntu, the jpegs are showing ~18. + target = lena('RGB') + assert_image_similar(im, target, 20.0) + diff --git a/Tests/tester.py b/Tests/tester.py index 370740cb4..41ae8b2eb 100644 --- a/Tests/tester.py +++ b/Tests/tester.py @@ -150,6 +150,21 @@ def assert_image_equal(a, b, msg=None): else: success() +def assert_image_similar(a, b, epsilon, msg=None): + epsilon = float(epsilon) + if a.mode != b.mode: + return failure(msg or "got mode %r, expected %r" % (a.mode, b.mode)) + elif a.size != b.size: + return failure(msg or "got size %r, expected %r" % (a.size, b.size)) + diff = 0 + for abyte,bbyte in zip(a.tobytes(),b.tobytes()): + diff += abs(ord(abyte)-ord(bbyte)) + ave_diff = float(diff)/(a.size[0]*a.size[1]) + if epsilon < ave_diff: + failure(msg or "average pixel value difference %.4f > epsilon %.4f" %(ave_diff, epsilon)) + else: + success() + def tempfile(template, *extra): import os, sys files = [] From 5eae020aef6c545809e87c451ad3b88a6faa8c79 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Fri, 22 Mar 2013 21:25:37 -0700 Subject: [PATCH 13/31] py3 as well --- Tests/tester.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Tests/tester.py b/Tests/tester.py index 41ae8b2eb..e534623d1 100644 --- a/Tests/tester.py +++ b/Tests/tester.py @@ -157,8 +157,13 @@ def assert_image_similar(a, b, epsilon, msg=None): elif a.size != b.size: return failure(msg or "got size %r, expected %r" % (a.size, b.size)) diff = 0 - for abyte,bbyte in zip(a.tobytes(),b.tobytes()): - diff += abs(ord(abyte)-ord(bbyte)) + try: + ord(b'0') + for abyte,bbyte in zip(a.tobytes(),b.tobytes()): + diff += abs(ord(abyte)-ord(bbyte)) + except: + for abyte,bbyte in zip(a.tobytes(),b.tobytes()): + diff += abs(abyte-bbyte) ave_diff = float(diff)/(a.size[0]*a.size[1]) if epsilon < ave_diff: failure(msg or "average pixel value difference %.4f > epsilon %.4f" %(ave_diff, epsilon)) From 2a743c95279142af58cdf8ce16b0b8d35bede2e8 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Fri, 22 Mar 2013 22:27:12 -0700 Subject: [PATCH 14/31] JpegImagePlugin sets bufsize for optimized images --- PIL/ImageFile.py | 8 ++++++-- PIL/JpegImagePlugin.py | 10 +++++++++- Tests/test_file_jpeg.py | 7 +++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/PIL/ImageFile.py b/PIL/ImageFile.py index 2b4eeb7b4..b08f14b90 100644 --- a/PIL/ImageFile.py +++ b/PIL/ImageFile.py @@ -433,8 +433,9 @@ class Parser: # @param im Image object. # @param fp File object. # @param tile Tile list. +# @param bufsize Optional buffer size -def _save(im, fp, tile): +def _save(im, fp, tile, bufsize=0): "Helper to save image based on tile list" im.load() @@ -442,7 +443,10 @@ def _save(im, fp, tile): im.encoderconfig = () tile.sort(key=_tilesort) # FIXME: make MAXBLOCK a configuration parameter - bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c + # It would be great if we could have the encoder specifiy what it needs + # But, it would need at least the image size in most cases. RawEncode is + # a tricky case. + bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c try: fh = fp.fileno() fp.flush() diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index 6df8b926c..a9bb120b9 100644 --- a/PIL/JpegImagePlugin.py +++ b/PIL/JpegImagePlugin.py @@ -554,7 +554,15 @@ def _save(im, fp, filename): info.get("exif", b"") ) - ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)]) + # if we optimize, libjpeg needs a buffer big enough to hold the whole image in a shot. + # Guessing on the size, at im.size bytes. (raw pizel size is channels*size, this + # is a value that's been used in a django patch. + # https://github.com/jdriscoll/django-imagekit/issues/50 + bufsize=0 + if "optimize" in info: + bufsize = im.size[0]*im.size[1] + + ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)], bufsize) def _save_cjpeg(im, fp, filename): # ALTERNATIVE: handle JPEGs via the IJG command line utilities. diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index 011405501..556786aa7 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -113,6 +113,13 @@ def test_optimize(): assert_image_equal(im1, im2) assert_true(im1.bytes >= im2.bytes) +def test_optimize_large_buffer(): + #https://github.com/python-imaging/Pillow/issues/148 + f = tempfile('temp.jpg') + # this requires ~ 1.5x Image.MAXBLOCK + im = Image.new("RGB", (4096,4096), 0xff3333) + im.save(f, format="JPEG", optimize=True) + def test_progressive(): im1 = roundtrip(lena()) im2 = roundtrip(lena(), progressive=1) From e88490b4f27bf7192dcbfe409ade17dc367dc8cb Mon Sep 17 00:00:00 2001 From: homm Date: Sat, 23 Mar 2013 14:26:14 +0400 Subject: [PATCH 15/31] =?UTF-8?q?Precision=20improvement.=20=E2=89=8860%?= =?UTF-8?q?=20performance=20lost?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libImaging/AlphaComposite.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index 8cc519d3f..ce4dca2b0 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -50,35 +50,32 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) for (y = 0; y < imDst->ysize; y++) { - rgba8* pdst = (rgba8*) imDst->image[y]; - rgba8* psrc = (rgba8*) imSrc->image[y]; - rgba8* pout = (rgba8*) imOut->image[y]; + rgba8* dst = (rgba8*) imDst->image[y]; + rgba8* src = (rgba8*) imSrc->image[y]; + rgba8* out = (rgba8*) imOut->image[y]; for (x = 0; x < imDst->xsize; x ++) { - rgba8 src = psrc[x]; - if (src.a == 0) { + if (src->a == 0) { // Copy 4 bytes at once. - pout[x] = pdst[x]; + *out = *dst; } else { - rgba8 dst = pdst[x]; - rgba8* out = &pout[x]; - // Integer implementation with increased precision. // Each variable has extra meaningful bits. // Divisions are rounded. - UINT16 blend = dst.a * (255 - src.a); // 16 bit max - UINT16 outa = (src.a << 4) + ((blend + 0x8) >> 4); // 12 - UINT16 coef1 = (src.a << 16) / outa; // 12 + UINT16 blend = dst->a * (255 - src->a); // 16 bit max + UINT16 outa = (src->a << 4) + ((blend << 4) + 127) / 255; // 12 + UINT16 coef1 = ((src->a * 255) << 8) / outa; // 12 UINT16 coef2 = (blend << 8) / outa; // 12 - out->r = (src.r * coef1 + dst.r * coef2 + 0x800) >> 12; - out->g = (src.g * coef1 + dst.g * coef2 + 0x800) >> 12; - out->b = (src.b * coef1 + dst.b * coef2 + 0x800) >> 12; - out->a = (outa + 0x8) >> 4; + out->r = ((src->r * coef1 + dst->r * coef2 + 0x7ff) / 255) >> 4; + out->g = ((src->g * coef1 + dst->g * coef2 + 0x7ff) / 255) >> 4; + out->b = ((src->b * coef1 + dst->b * coef2 + 0x7ff) / 255) >> 4; + out->a = (outa + 0x7) >> 4; } + dst++; src++; out++; } } From 0663e1444420a23da876bbe7e6e032081287ab22 Mon Sep 17 00:00:00 2001 From: homm Date: Sat, 23 Mar 2013 16:51:55 +0400 Subject: [PATCH 16/31] speedup. divisions replaced by shifts. --- libImaging/AlphaComposite.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index ce4dca2b0..8a3d94ffe 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -64,14 +64,25 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) // Each variable has extra meaningful bits. // Divisions are rounded. - UINT16 blend = dst->a * (255 - src->a); // 16 bit max - UINT16 outa = (src->a << 4) + ((blend << 4) + 127) / 255; // 12 - UINT16 coef1 = ((src->a * 255) << 8) / outa; // 12 + // This code uses trick from Paste.c: + // (a + (2 << (n-1)) - 1) / ((2 << n)-1) + // almost equivalent to: + // tmp = a + (2 << (n-1)), ((tmp >> n) + tmp) >> n + + // 0xff * 0xff = 16 meaningful bits. + UINT16 blend = dst->a * (255 - src->a); + // Shift 4 bits up, to don't loose blend precision + // on very transparent pixels. + UINT16 outa = (src->a << 4) + (((blend << 4) + (blend >> 4) + 0x80) >> 8); + UINT16 coef1 = (((src->a << 8) - src->a) << 8) / outa; // 12 UINT16 coef2 = (blend << 8) / outa; // 12 - out->r = ((src->r * coef1 + dst->r * coef2 + 0x7ff) / 255) >> 4; - out->g = ((src->g * coef1 + dst->g * coef2 + 0x7ff) / 255) >> 4; - out->b = ((src->b * coef1 + dst->b * coef2 + 0x7ff) / 255) >> 4; + UINT32 tmpr = src->r * coef1 + dst->r * coef2 + 0x800; + out->r = ((tmpr >> 8) + tmpr) >> 12; + UINT32 tmpg = src->g * coef1 + dst->g * coef2 + 0x800; + out->g = ((tmpg >> 8) + tmpg) >> 12; + UINT32 tmpb = src->b * coef1 + dst->b * coef2 + 0x800; + out->b = ((tmpb >> 8) + tmpb) >> 12; out->a = (outa + 0x7) >> 4; } From af96b5d4b27a2bbf7e8fd3e8ea9b10bb51c3a039 Mon Sep 17 00:00:00 2001 From: homm Date: Mon, 25 Mar 2013 00:06:02 +0400 Subject: [PATCH 17/31] Precision improvement. No performance affected. --- libImaging/AlphaComposite.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index 8a3d94ffe..93afe2a95 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -69,21 +69,23 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) // almost equivalent to: // tmp = a + (2 << (n-1)), ((tmp >> n) + tmp) >> n - // 0xff * 0xff = 16 meaningful bits. UINT16 blend = dst->a * (255 - src->a); - // Shift 4 bits up, to don't loose blend precision - // on very transparent pixels. - UINT16 outa = (src->a << 4) + (((blend << 4) + (blend >> 4) + 0x80) >> 8); - UINT16 coef1 = (((src->a << 8) - src->a) << 8) / outa; // 12 - UINT16 coef2 = (blend << 8) / outa; // 12 + UINT16 outa255 = src->a * 255 + blend; + // There we use 7 bits for precision. + // We could use more, but we go beyond 32 bits. + UINT16 coef1 = src->a * 255 * 255 * 128 / outa255; + UINT16 coef2 = blend * 255 * 128 / outa255; - UINT32 tmpr = src->r * coef1 + dst->r * coef2 + 0x800; - out->r = ((tmpr >> 8) + tmpr) >> 12; - UINT32 tmpg = src->g * coef1 + dst->g * coef2 + 0x800; - out->g = ((tmpg >> 8) + tmpg) >> 12; - UINT32 tmpb = src->b * coef1 + dst->b * coef2 + 0x800; - out->b = ((tmpb >> 8) + tmpb) >> 12; - out->a = (outa + 0x7) >> 4; + #define SHIFTFORDIV255(a)\ + ((a >> 8) + a >> 8) + + UINT32 tmpr = src->r * coef1 + dst->r * coef2 + (0x80 << 7); + out->r = SHIFTFORDIV255(tmpr) >> 7; + UINT32 tmpg = src->g * coef1 + dst->g * coef2 + (0x80 << 7); + out->g = SHIFTFORDIV255(tmpg) >> 7; + UINT32 tmpb = src->b * coef1 + dst->b * coef2 + (0x80 << 7); + out->b = SHIFTFORDIV255(tmpb) >> 7; + out->a = SHIFTFORDIV255(outa255 + 0x80); } dst++; src++; out++; From a83ef0f0ed65961eace4869fcf6aa906576caed0 Mon Sep 17 00:00:00 2001 From: homm Date: Mon, 25 Mar 2013 09:49:35 +0400 Subject: [PATCH 18/31] =?UTF-8?q?=E2=89=8820%=20faster,=202=20times=20more?= =?UTF-8?q?=20precisely=20(0.17%=20difference=20against=200.37%)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libImaging/AlphaComposite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index 93afe2a95..86af8e940 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -74,7 +74,7 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) // There we use 7 bits for precision. // We could use more, but we go beyond 32 bits. UINT16 coef1 = src->a * 255 * 255 * 128 / outa255; - UINT16 coef2 = blend * 255 * 128 / outa255; + UINT16 coef2 = 255 * 128 - coef1; #define SHIFTFORDIV255(a)\ ((a >> 8) + a >> 8) From 5303f0ea667d46ee116ef53dc12cb923e1c74f8a Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Tue, 26 Mar 2013 11:24:07 +0100 Subject: [PATCH 19/31] added tests to cover save of four different png transparencies --- Tests/images/l_trns.png | Bin 0 -> 1164 bytes Tests/images/p_trns_single.png | Bin 0 -> 1942 bytes Tests/test_file_png.py | 28 ++++++++++++++++++++++++++++ _imaging.c | 22 +++++++++++----------- 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 Tests/images/l_trns.png create mode 100644 Tests/images/p_trns_single.png diff --git a/Tests/images/l_trns.png b/Tests/images/l_trns.png new file mode 100644 index 0000000000000000000000000000000000000000..a26a82076fc63ff68d99e54a36d82af72760c530 GIT binary patch literal 1164 zcmV;71atd|P)cRZO75qG4qMD+_K6J6sulroX^H(D;#< zXhPVvMoS8$Vu02Ht&91*4}JQiN#Ezbcg{UCb7t}e;mJ|~t0zg3xRe6Gj6>H&La&rJDnEaS- zJCS6MKtgwWFpnpEx3eZjc#o<9=thcL!X3&m5LBlDLV|+2pn)_pQfFyg%cxlLKMwSTuU$P1!Nr64j^jHH)ITD`=P;bMe2V|rUq*y2* zhT&cWsQZone#{_4NYXi=xpDZ+UN*v0CsXqf0taY-?CyH1KB}n*AETEBB?P)^4tb2f z)S3+C6_1QWuO_g{2ZtC$bdk_7*-EdvmdYjfGT_sDx@@~g2I&BXc987iQ;D|aOe^zTfk{9cM z;KIhe^`+L@t3Nk4|4C1xX)6Os8QNbVtAI$?C?S}3m_)>;5eYSs`b>i(7D|0JB zUl5bV;m?1(oguLGTno`}&~&2~lRW)lbN~1xfW6=M!vGY$z`h;mTOdEax$*f~PVKjU zc~)))^BwoizK%L17cX94y>RBJA1?fNe*Zi_`mpUh+IczMMY4wrUJB~U!IRyLl_WvG zEj@DR$PEBjKw5j39mLCovc27RTbGtPd0Sx1nj6}H zqxV8k(n+jx2)Z6JuO5la_4s|^S@L~DHY@u&F|tnU1M?xCnj>$6bz%g&|3VBYCsJIT z9D{&*P9GqHC(5ZFVfqbT{E3?>4#jv*Iz>WU5HTcDfAUPqrqraRY>Ha6fnF2u4i`rw eoh7y?YQq1$+hYIO;Bt!q00001bh_(XF z$LE9?TO1;|y$1;)k=b}7gK(H2YK*FO6AcgF&aC8I6Bz6Ms2+>_Etm3E^I6+ho z{LPA*;P?YjNYn;u$NYbBI8W3G`VlB2uXZy%0m^wc>@xJ9^4Gz3>A z$JG$Q)qynwzVr%&-*R<4g6O>wGa&*Gm^_NGlio1ZK|<0y5Tl6+(+S!3*h|PEoFbgH zw=}#Y5ac<|9Ls5%BeofCqm>!glAgIY5dKZ*bVe!7uw@U|K@paHpU&Z~EwIEHASlVi z+(!uGgb8#p?F_nXozUZE84a*G*bZ_-D|*NklV5(WlCb;h7>wQ<;pG4p^r zeL72N3<(}_@DTp>^Qo!2{GzHq)qboMx0EX?lzyDaG(8gaUt??U}4ey z?(`46C*%4wh5IKa{CPu_OQgQjBYB8ZIUVFyx*2o*&1OYW(=1h^srDJ#o|HZ0R@q5! z3?6_WmE%npyp)*^ybw`~$Fj69Yv7_;-~6-E3uB|T-DkLsF*%Wf;mWXXxs*Tl$QZB< z}tB^Sw+rwTr#GvlsOsVdmkQoQjle% z&Oa%PoT}OD^VKt))qF5lST++nT&VDA>s~8$xy|LbR3>s>n$gEDWnxoYcxz+tvrkS+ zQ}g;n8P?7PxBP$lq+-4H&ePQF@$VEjWlNoYH0f7(*X#L1O7GoXPT{*M41JtXTrGJd zIw!cfA+Ky+<;?YqQ?ji;Y+Q7Dj>vcUs;!y}Vq>7hTdXnX>ZoO2Cx4CF>Uw3FB=J^| z=kh$wqKi7$rkF*|hGlQoo{vly53gy9u}b8Itx9yfMB&I=CS|O8_Fz^ge}~|s0e89K zoWNS2_G-Z0VRCVBiSFwSnZDXxy$a@b$olqxliW}!h-;)rRrzOC z^Yz-vZvTHKZ<8dhOyz8PchH0^CWZo>k0-lkA5?%s=dBb z>9{ia?y21hvvj;8>)V<7dXMm|C7zMS>WK@*9)8Ned#+c_^}AoS3A~i0dg;rC3{T~v zXqmfl;nEJjey!klJC0v%T&;-@(WbtuzS5MtR(JS-?D-#Krvkpy8{Sv=PG_HVY+RST z#l#<1`0X069N42OKAO9FOc$VuKdrX=R(Z@6nyl{B|Gh+_aBgoB^$4C$hcxRVtMVQ=fYLUereRxKPBp&0)7fV~_qHDN9uM literal 0 HcmV?d00001 diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index c8ee36c93..4c14c9a64 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -128,6 +128,34 @@ def test_load_transparent_p(): # image has 124 uniqe qlpha values assert_equal(len(im.split()[3].getcolors()), 124) +def test_save_p_transparent_palette(): + in_file = "Tests/images/pil123p.png" + im = Image.open(in_file) + + file = tempfile("temp.png") + assert_no_exception(lambda: im.save(file)) + +def test_save_p_single_transparency(): + in_file = "Tests/images/p_trns_single.png" + im = Image.open(in_file) + + file = tempfile("temp.png") + assert_no_exception(lambda: im.save(file)) + +def test_save_l_transparency(): + in_file = "Tests/images/l_trns.png" + im = Image.open(in_file) + + file = tempfile("temp.png") + assert_no_exception(lambda: im.save(file)) + +def test_save_rgb_single_transparency(): + in_file = "Tests/images/caption_6_33_22.png" + im = Image.open(in_file) + + file = tempfile("temp.png") + assert_no_exception(lambda: im.save(file)) + def test_load_verify(): # Check open/load/verify exception (@PIL150) diff --git a/_imaging.c b/_imaging.c index 878e4e362..c9d3c8247 100644 --- a/_imaging.c +++ b/_imaging.c @@ -742,16 +742,16 @@ _convert(ImagingObject* self, PyObject* args) ImagingObject *paletteimage = NULL; if (!PyArg_ParseTuple(args, "s|iO", &mode, &dither, &paletteimage)) - return NULL; + return NULL; if (paletteimage != NULL) { if (!PyImaging_Check(paletteimage)) { - PyObject_Print((PyObject *)paletteimage, stderr, 0); - PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'"); - return NULL; + PyObject_Print((PyObject *)paletteimage, stderr, 0); + PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'"); + return NULL; } if (paletteimage->image->palette == NULL) { - PyErr_SetString(PyExc_ValueError, "null palette"); - return NULL; + PyErr_SetString(PyExc_ValueError, "null palette"); + return NULL; } } @@ -1431,16 +1431,16 @@ _putpalettealpha(ImagingObject* self, PyObject* args) int index; int alpha = 0; if (!PyArg_ParseTuple(args, "i|i", &index, &alpha)) - return NULL; + return NULL; if (!self->image->palette) { - PyErr_SetString(PyExc_ValueError, no_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, no_palette); + return NULL; } if (index < 0 || index >= 256) { - PyErr_SetString(PyExc_ValueError, outside_palette); - return NULL; + PyErr_SetString(PyExc_ValueError, outside_palette); + return NULL; } strcpy(self->image->palette->mode, "RGBA"); From f50feb592bfc3247783673030b0fc22339f453dd Mon Sep 17 00:00:00 2001 From: Ronald Oussoren Date: Tue, 26 Mar 2013 13:36:13 +0100 Subject: [PATCH 20/31] Explitly import JpegPresets from the PIL package --- PIL/JpegImagePlugin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index a9bb120b9..1c260dd6b 100644 --- a/PIL/JpegImagePlugin.py +++ b/PIL/JpegImagePlugin.py @@ -36,7 +36,7 @@ __version__ = "0.6" import array, struct from PIL import Image, ImageFile, _binary -from JpegPresets import presets +from PIL.JpegPresets import presets i8 = _binary.i8 o8 = _binary.o8 @@ -483,7 +483,7 @@ def _save(im, fp, filename): elif subsampling == "keep": if im.format != "JPEG": raise ValueError("Cannot use 'keep' when original image is not a JPEG") - subsampling = get_sampling(im) + subsampling = get_sampling(im) def validate_qtables(qtables): if qtables is None: @@ -513,7 +513,7 @@ def _save(im, fp, filename): else: qtables[idx] = list(table) return qtables - + if qtables == "keep": if im.format != "JPEG": raise ValueError("Cannot use 'keep' when original image is not a JPEG") @@ -560,7 +560,7 @@ def _save(im, fp, filename): # https://github.com/jdriscoll/django-imagekit/issues/50 bufsize=0 if "optimize" in info: - bufsize = im.size[0]*im.size[1] + bufsize = im.size[0]*im.size[1] ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)], bufsize) From 8c55b8305c47c8a0432208778ad4647810708d36 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Wed, 27 Mar 2013 09:04:11 -0700 Subject: [PATCH 21/31] fixed duplicate dpkg --- setup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 78087fa07..65b8b1e42 100644 --- a/setup.py +++ b/setup.py @@ -453,8 +453,6 @@ class pil_build_ext(build_ext): tmpfile = os.path.join(self.build_temp, 'multiarch') if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) - ret = os.system('dpkg-architecture -qDEB_HOST_MULTIARCH > %s' % - tmpfile) ret = os.system( 'dpkg-architecture -qDEB_HOST_MULTIARCH > %s 2> /dev/null' % tmpfile) From 7129baa9b2ceb9939db4b0bdf818d7cb1fae7ba3 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Wed, 27 Mar 2013 09:44:28 -0700 Subject: [PATCH 22/31] fix for if isinstance(filter, collections.Callable) crash. Python bug #7624 on <2.6.6 --- PIL/ImageFilter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PIL/ImageFilter.py b/PIL/ImageFilter.py index 71f42c3ac..c13f75bbc 100644 --- a/PIL/ImageFilter.py +++ b/PIL/ImageFilter.py @@ -17,7 +17,7 @@ from functools import reduce -class Filter: +class Filter(object): pass ## From 86bb25e73546c3e491aef75c1e13d559665adfee Mon Sep 17 00:00:00 2001 From: wiredfool Date: Wed, 27 Mar 2013 09:52:01 -0700 Subject: [PATCH 23/31] reenable basic webp test, skip if support not installed --- Tests/test_file_webp.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Tests/test_file_webp.py b/Tests/test_file_webp.py index 0d2c984b0..f7aad97f9 100644 --- a/Tests/test_file_webp.py +++ b/Tests/test_file_webp.py @@ -2,7 +2,12 @@ from tester import * from PIL import Image -def xtest_read(): +codecs = dir(Image.core) + +if "webp_encoder" not in codecs or "webp_decoder" not in codecs: + skip("webp support not available") + +def test_read(): """ Can we write a webp without error. Does it have the bits we expect?""" file = "Images/lena.webp" From 38b0bef46471805aba178ed214efe35734744223 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Wed, 27 Mar 2013 10:00:35 -0700 Subject: [PATCH 24/31] webp is in import, not a codec --- Tests/test_file_webp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/test_file_webp.py b/Tests/test_file_webp.py index f7aad97f9..5d48f0aff 100644 --- a/Tests/test_file_webp.py +++ b/Tests/test_file_webp.py @@ -2,10 +2,10 @@ from tester import * from PIL import Image -codecs = dir(Image.core) - -if "webp_encoder" not in codecs or "webp_decoder" not in codecs: - skip("webp support not available") +try: + import _webp +except: + skip('webp support not installed') def test_read(): """ Can we write a webp without error. Does it have the bits we expect?""" From a511ef8b052db9d339caa2733c3145aef80a045f Mon Sep 17 00:00:00 2001 From: homm Date: Wed, 27 Mar 2013 23:18:10 +0400 Subject: [PATCH 25/31] move declarations to make ANSI compilers happy --- libImaging/AlphaComposite.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index 86af8e940..9876cda5f 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -69,6 +69,7 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) // almost equivalent to: // tmp = a + (2 << (n-1)), ((tmp >> n) + tmp) >> n + UINT32 tmpr, tmpg, tmpb; UINT16 blend = dst->a * (255 - src->a); UINT16 outa255 = src->a * 255 + blend; // There we use 7 bits for precision. @@ -79,11 +80,11 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) #define SHIFTFORDIV255(a)\ ((a >> 8) + a >> 8) - UINT32 tmpr = src->r * coef1 + dst->r * coef2 + (0x80 << 7); + tmpr = src->r * coef1 + dst->r * coef2 + (0x80 << 7); out->r = SHIFTFORDIV255(tmpr) >> 7; - UINT32 tmpg = src->g * coef1 + dst->g * coef2 + (0x80 << 7); + tmpg = src->g * coef1 + dst->g * coef2 + (0x80 << 7); out->g = SHIFTFORDIV255(tmpg) >> 7; - UINT32 tmpb = src->b * coef1 + dst->b * coef2 + (0x80 << 7); + tmpb = src->b * coef1 + dst->b * coef2 + (0x80 << 7); out->b = SHIFTFORDIV255(tmpb) >> 7; out->a = SHIFTFORDIV255(outa255 + 0x80); } From ebb9029fbe7cfb963a705f8126e806e9bd38929f Mon Sep 17 00:00:00 2001 From: homm Date: Wed, 27 Mar 2013 23:19:04 +0400 Subject: [PATCH 26/31] add parentheses to avoid warnings --- libImaging/AlphaComposite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index 9876cda5f..9433fae53 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -78,7 +78,7 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc) UINT16 coef2 = 255 * 128 - coef1; #define SHIFTFORDIV255(a)\ - ((a >> 8) + a >> 8) + ((((a) >> 8) + a) >> 8) tmpr = src->r * coef1 + dst->r * coef2 + (0x80 << 7); out->r = SHIFTFORDIV255(tmpr) >> 7; From a213235e60295d6344fbf8f173ea648b603f14a9 Mon Sep 17 00:00:00 2001 From: Alex Clark Date: Tue, 2 Apr 2013 20:19:13 -0400 Subject: [PATCH 27/31] Add donation info --- README.rst | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index a9679a5c3..fd988ad65 100644 --- a/README.rst +++ b/README.rst @@ -80,6 +80,21 @@ Current platform support for Pillow. Binary distributions are contributed for ea .. [1] x86 only .. [2] In some cases, x86 support may indicate 32-bit compilation on 64-bit architecture (vs. compilation on 32-bit hardware). +Donations +--------- + +You can help fund Pillow development! + +.. Note:: New contributors: please add your name (and donation preference) here and send a pull request. + +Pillow is a volunteer effort led by Alex Clark. Any contributor interested in receiving donations may add their name (and donation preference) here. + ++--------------------------------------+---------------------------------------+ +| **Developer** | **Preference** | ++--------------------------------------+---------------------------------------+ +| Alex Clark (fork author) | http://gittip.com/aclark4life | ++--------------------------------------+---------------------------------------+ + Python Imaging Library ====================== @@ -386,4 +401,3 @@ Python Imaging Library http://mingw.org (compiler) http://sebsauvage.net/python/mingw.html (build instructions) http://sourceforge.net/projects/gnuwin32 (prebuilt libraries) - From 2a2a1ea144554cc17d141374e2d9223bfd2f5e07 Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Sun, 7 Apr 2013 19:02:11 +0200 Subject: [PATCH 28/31] Fix tests which are hardcoded for little-endian CPUs --- Tests/test_image_array.py | 4 ++-- Tests/test_lib_pack.py | 6 ++++-- Tests/test_mode_i16.py | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Tests/test_image_array.py b/Tests/test_image_array.py index c2e85903a..351621d3a 100644 --- a/Tests/test_image_array.py +++ b/Tests/test_image_array.py @@ -10,8 +10,8 @@ def test_toarray(): return ai["shape"], ai["typestr"], len(ai["data"]) # assert_equal(test("1"), ((100, 128), '|b1', 1600)) assert_equal(test("L"), ((100, 128), '|u1', 12800)) - assert_equal(test("I"), ((100, 128), ' Date: Mon, 8 Apr 2013 00:52:15 +0200 Subject: [PATCH 29/31] Make quantization code more portable --- _imaging.c | 1 - libImaging/Quant.c | 395 ++++++++++++++++++-------------------- libImaging/Quant.h | 40 ---- libImaging/QuantDefines.h | 25 --- libImaging/QuantHash.c | 250 +++++++++++------------- libImaging/QuantHash.h | 55 ++++-- libImaging/QuantHeap.c | 49 ++--- libImaging/QuantHeap.h | 18 +- libImaging/QuantOctree.c | 28 +-- libImaging/QuantOctree.h | 12 +- libImaging/QuantTypes.h | 25 +-- 11 files changed, 405 insertions(+), 493 deletions(-) delete mode 100644 libImaging/Quant.h delete mode 100644 libImaging/QuantDefines.h diff --git a/_imaging.c b/_imaging.c index c9d3c8247..2ee7eef42 100644 --- a/_imaging.c +++ b/_imaging.c @@ -1369,7 +1369,6 @@ _putdata(ImagingObject* self, PyObject* args) #ifdef WITH_QUANTIZE -#include "Quant.h" static PyObject* _quantize(ImagingObject* self, PyObject* args) { diff --git a/libImaging/Quant.c b/libImaging/Quant.c index ff15ac01f..7f328bda9 100644 --- a/libImaging/Quant.c +++ b/libImaging/Quant.c @@ -25,17 +25,15 @@ #include #include -#include "Quant.h" +#include "QuantTypes.h" #include "QuantOctree.h" - -#include "QuantDefines.h" #include "QuantHash.h" #include "QuantHeap.h" #define NO_OUTPUT typedef struct { - unsigned long scale; + uint32_t scale; } PixelHashData; typedef struct _PixelList { @@ -50,7 +48,7 @@ typedef struct _BoxNode { PixelList *head[3],*tail[3]; int axis; int volume; - unsigned long pixelCount; + uint32_t pixelCount; } BoxNode; #define _SQR(x) ((x)*(x)) @@ -76,104 +74,92 @@ typedef struct _BoxNode { ((q)->c.g=(p)->c.g>>(s)), \ ((q)->c.b=(p)->c.b>>(s)) -static unsigned long -unshifted_pixel_hash(const HashTable h, const void *p) +static uint32_t +unshifted_pixel_hash(const HashTable *h, const Pixel pixel) { - Pixel *pixel=(Pixel *)&p; - unsigned long hash=PIXEL_HASH(pixel->c.r, - pixel->c.g, - pixel->c.b); - return hash; + return PIXEL_HASH(pixel.c.r, pixel.c.g, pixel.c.b); } static int -unshifted_pixel_cmp(const HashTable h, const void *a, const void *b) +unshifted_pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2) { - Pixel *pixel1=(Pixel *)&a; - Pixel *pixel2=(Pixel *)&b; - if (pixel1->c.r==pixel2->c.r) { - if (pixel1->c.g==pixel2->c.g) { - if (pixel1->c.b==pixel2->c.b) { + if (pixel1.c.r==pixel2.c.r) { + if (pixel1.c.g==pixel2.c.g) { + if (pixel1.c.b==pixel2.c.b) { return 0; } else { - return (int)(pixel1->c.b)-(int)(pixel2->c.b); + return (int)(pixel1.c.b)-(int)(pixel2.c.b); } } else { - return (int)(pixel1->c.g)-(int)(pixel2->c.g); + return (int)(pixel1.c.g)-(int)(pixel2.c.g); } } else { - return (int)(pixel1->c.r)-(int)(pixel2->c.r); + return (int)(pixel1.c.r)-(int)(pixel2.c.r); } } -static unsigned long -pixel_hash(const HashTable h,const void *p) +static uint32_t +pixel_hash(const HashTable *h,const Pixel pixel) { PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); - Pixel *pixel=(Pixel *)&p; - unsigned long hash=PIXEL_HASH(pixel->c.r>>d->scale, - pixel->c.g>>d->scale, - pixel->c.b>>d->scale); - return hash; + return PIXEL_HASH(pixel.c.r>>d->scale, pixel.c.g>>d->scale, pixel.c.b>>d->scale); } static int -pixel_cmp(const HashTable h,const void *a,const void *b) +pixel_cmp(const HashTable *h,const Pixel pixel1, const Pixel pixel2) { PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); - Pixel *pixel1=(Pixel *)&a; - Pixel *pixel2=(Pixel *)&b; - unsigned long A,B; - A=PIXEL_HASH(pixel1->c.r>>d->scale, - pixel1->c.g>>d->scale, - pixel1->c.b>>d->scale); - B=PIXEL_HASH(pixel2->c.r>>d->scale, - pixel2->c.g>>d->scale, - pixel2->c.b>>d->scale); + uint32_t A,B; + A=PIXEL_HASH(pixel1.c.r>>d->scale, pixel1.c.g>>d->scale, pixel1.c.b>>d->scale); + B=PIXEL_HASH(pixel2.c.r>>d->scale, pixel2.c.g>>d->scale, pixel2.c.b>>d->scale); return (A==B)?0:((Ascale=0; +#ifndef NO_OUTPUT timer=timer3=clock(); +#endif for (i=0;iscale++; #ifndef NO_OUTPUT printf ("rehashing - new scale: %d\n",(int)d->scale); -#endif timer2=clock(); - hashtable_rehash_compute(hash,rehash_collide); - timer2=clock()-timer2; -#ifndef NO_OUTPUT - printf ("rehash took %f sec\n",timer2/(double)CLOCKS_PER_SEC); #endif + hashtable_rehash_compute(hash,rehash_collide); +#ifndef NO_OUTPUT + timer2=clock()-timer2; + printf ("rehash took %f sec\n",timer2/(double)CLOCKS_PER_SEC); timer+=timer2; +#endif } } #ifndef NO_OUTPUT @@ -201,7 +187,7 @@ create_pixel_hash(Pixel *pixelData,unsigned long nPixels) } static void -destroy_pixel_hash(HashTable hash) +destroy_pixel_hash(HashTable *hash) { PixelHashData *d=(PixelHashData *)hashtable_get_user_data(hash); if (d) free(d); @@ -237,17 +223,15 @@ compute_box_volume(BoxNode *b) } static void -hash_to_list(HashTable h, const void *key, const void *val, void *u) +hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *u) { PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); PixelList **pl=(PixelList **)u; PixelList *p; - Pixel *pixel=(Pixel *)&key; int i; Pixel q; - int count=(unsigned long) val; - PIXEL_SCALE(pixel,&q,d->scale); + PIXEL_SCALE(&pixel,&q,d->scale); p=malloc(sizeof(PixelList)); if (!p) return; @@ -327,7 +311,7 @@ test_sorted(PixelList *pl[3]) #endif static int -box_heap_cmp(const Heap h, const void *A, const void *B) +box_heap_cmp(const Heap *h, const void *A, const void *B) { BoxNode *a=(BoxNode *)A; BoxNode *b=(BoxNode *)B; @@ -341,11 +325,11 @@ splitlists(PixelList *h[3], PixelList *t[3], PixelList *nh[2][3], PixelList *nt[2][3], - unsigned long nCount[2], + uint32_t nCount[2], int axis, - unsigned long pixelCount) + uint32_t pixelCount) { - unsigned long left; + uint32_t left; PixelList *l,*r,*c,*n; int i; @@ -476,7 +460,7 @@ split(BoxNode *node) int i; PixelList *heads[2][3]; PixelList *tails[2][3]; - unsigned long newCounts[2]; + uint32_t newCounts[2]; BoxNode *left,*right; rh=node->head[0]->p.c.r; @@ -618,13 +602,13 @@ split(BoxNode *node) static BoxNode * median_cut(PixelList *hl[3], - unsigned long imPixelCount, + uint32_t imPixelCount, int nPixels) { PixelList *tl[3]; int i; BoxNode *root; - Heap h; + Heap* h; BoxNode *thisNode; h=ImagingQuantHeapNew(box_heap_cmp); @@ -701,7 +685,7 @@ checkContained(BoxNode *n,Pixel *pp) #endif static int -annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box) +annotate_hash_table(BoxNode *n,HashTable *h,uint32_t *box) { PixelList *p; PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h); @@ -717,7 +701,7 @@ annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box) } for (p=n->head[0];p;p=p->next[0]) { PIXEL_UNSCALE(&(p->p),&q,d->scale); - if (!hashtable_insert(h,(void *)q.v,(void *)*box)) { + if (!hashtable_insert(h,q,*box)) { #ifndef NO_OUTPUT printf ("hashtable insert failed\n"); #endif @@ -731,20 +715,20 @@ annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box) static int _sort_ulong_ptr_keys(const void *a, const void *b) { - unsigned long A=**(unsigned long **)a; - unsigned long B=**(unsigned long **)b; + uint32_t A=**(uint32_t **)a; + uint32_t B=**(uint32_t **)b; return (A==B)?0:((A=nPaletteEntries) { @@ -1091,35 +1075,35 @@ compute_palette_from_quantized_pixels( static int k_means(Pixel *pixelData, - unsigned long nPixels, + uint32_t nPixels, Pixel *paletteData, - unsigned long nPaletteEntries, - unsigned long *qp, + uint32_t nPaletteEntries, + uint32_t *qp, int threshold) { - unsigned long *avg[3]; - unsigned long *count; - unsigned long i; - unsigned long *avgDist; - unsigned long **avgDistSortKey; + uint32_t *avg[3]; + uint32_t *count; + uint32_t i; + uint32_t *avgDist; + uint32_t **avgDistSortKey; int changes; int built=0; - if (!(count=malloc(sizeof(unsigned long)*nPaletteEntries))) { + if (!(count=malloc(sizeof(uint32_t)*nPaletteEntries))) { return 0; } for(i=0;i<3;i++) { avg[i]=NULL; } for(i=0;i<3;i++) { - if (!(avg[i]=malloc(sizeof(unsigned long)*nPaletteEntries))) { + if (!(avg[i]=malloc(sizeof(uint32_t)*nPaletteEntries))) { goto error_1; } } - avgDist=malloc(sizeof(unsigned long)*nPaletteEntries*nPaletteEntries); + avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries); if (!avgDist) { goto error_1; } - avgDistSortKey=malloc(sizeof(unsigned long *)*nPaletteEntries*nPaletteEntries); + avgDistSortKey=malloc(sizeof(uint32_t *)*nPaletteEntries*nPaletteEntries); if (!avgDistSortKey) { goto error_2; } #ifndef NO_OUTPUT @@ -1172,26 +1156,26 @@ error_1: int quantize(Pixel *pixelData, - unsigned long nPixels, - unsigned long nQuantPixels, + uint32_t nPixels, + uint32_t nQuantPixels, Pixel **palette, - unsigned long *paletteLength, - unsigned long **quantizedPixels, + uint32_t *paletteLength, + uint32_t **quantizedPixels, int kmeans) { PixelList *hl[3]; - HashTable h; + HashTable *h; BoxNode *root; - unsigned long i; - unsigned long *qp; - unsigned long nPaletteEntries; + uint32_t i; + uint32_t *qp; + uint32_t nPaletteEntries; - unsigned long *avgDist; - unsigned long **avgDistSortKey; + uint32_t *avgDist; + uint32_t **avgDistSortKey; Pixel *p; #ifndef NO_OUTPUT - unsigned long timer,timer2; + uint32_t timer,timer2; #endif #ifndef NO_OUTPUT @@ -1266,13 +1250,13 @@ quantize(Pixel *pixelData, free_box_tree(root); root=NULL; - qp=malloc(sizeof(unsigned long)*nPixels); + qp=malloc(sizeof(uint32_t)*nPixels); if (!qp) { goto error_4; } - avgDist=malloc(sizeof(unsigned long)*nPaletteEntries*nPaletteEntries); + avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries); if (!avgDist) { goto error_5; } - avgDistSortKey=malloc(sizeof(unsigned long *)*nPaletteEntries*nPaletteEntries); + avgDistSortKey=malloc(sizeof(uint32_t *)*nPaletteEntries*nPaletteEntries); if (!avgDistSortKey) { goto error_6; } if (!build_distance_tables(avgDist,avgDistSortKey,p,nPaletteEntries)) { @@ -1286,12 +1270,12 @@ quantize(Pixel *pixelData, #ifdef TEST_NEAREST_NEIGHBOUR #include { - unsigned long bestmatch,bestdist,dist; - HashTable h2; + uint32_t bestmatch,bestdist,dist; + HashTable *h2; printf ("nearest neighbour search (full search)..."); fflush(stdout); timer=clock(); h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); for (i=0;inew),pixel); + uint32_t oldDist=*dist; + uint32_t newDist; + newDist=_DISTSQR(&(data->new),&pixel); if (data->secondPixel || newDistdata->furthestDistance) { data->furthestDistance=oldDist; - data->furthest.v=pixel->v; + data->furthest.v=pixel.v; } } int quantize2(Pixel *pixelData, - unsigned long nPixels, - unsigned long nQuantPixels, + uint32_t nPixels, + uint32_t nQuantPixels, Pixel **palette, - unsigned long *paletteLength, - unsigned long **quantizedPixels, + uint32_t *paletteLength, + uint32_t **quantizedPixels, int kmeans) { - HashTable h; - unsigned long i; - unsigned long mean[3]; + HashTable *h; + uint32_t i; + uint32_t mean[3]; Pixel *p; DistanceData data; - unsigned long *qp; - unsigned long *avgDist; - unsigned long **avgDistSortKey; + uint32_t *qp; + uint32_t *avgDist; + uint32_t **avgDistSortKey; p=malloc(sizeof(Pixel)*nQuantPixels); if (!p) return 0; mean[0]=mean[1]=mean[2]=0; h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp); for (i=0;i. - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __QUANT_H__ -#define __QUANT_H__ - -typedef union { - struct { - unsigned char r,g,b,a; - } c; - struct { - unsigned char v[4]; - } a; - unsigned long v; -} Pixel; - -int quantize(Pixel *, - unsigned long, - unsigned long, - Pixel **, - unsigned long *, - unsigned long **, - int); - -int quantize2(Pixel *, - unsigned long, - unsigned long, - Pixel **, - unsigned long *, - unsigned long **, - int); -#endif diff --git a/libImaging/QuantDefines.h b/libImaging/QuantDefines.h deleted file mode 100644 index 5b080104e..000000000 --- a/libImaging/QuantDefines.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * The Python Imaging Library - * $Id$ - * - * image quantizer - * - * Written by Toby J Sargeant . - * - * See the README file for information on usage and redistribution. - */ - -#ifndef __DEFINES_H__ -#define __DEFINES_H__ - -#if 0 - -void *newMalloc(size_t,const char *,const char *,int); -void newFree(void *,const char *,const char *,int); -void print_malloc_stats(); -#define malloc(x) newMalloc(x,__FILE__,__FUNCTION__,__LINE__) -#define free(x) newFree(x,__FILE__,__FUNCTION__,__LINE__) - -#endif - -#endif diff --git a/libImaging/QuantHash.c b/libImaging/QuantHash.c index e6438402d..58d881349 100644 --- a/libImaging/QuantHash.c +++ b/libImaging/QuantHash.c @@ -22,35 +22,35 @@ #include #include "QuantHash.h" -#include "QuantDefines.h" -typedef struct _IntHashNode { - struct _IntHashNode *next; - void *key,*value; -} IntHashNode; +typedef struct _HashNode { + struct _HashNode *next; + HashKey_t key; + HashVal_t value; +} HashNode; -typedef struct _IntHashTable { - IntHashNode **table; - unsigned long length; - unsigned long count; +typedef struct _HashTable { + HashNode **table; + uint32_t length; + uint32_t count; HashFunc hashFunc; HashCmpFunc cmpFunc; - DestroyFunc keyDestroyFunc; - DestroyFunc valDestroyFunc; + KeyDestroyFunc keyDestroyFunc; + ValDestroyFunc valDestroyFunc; void *userData; -} IntHashTable; +} HashTable; #define MIN_LENGTH 11 #define RESIZE_FACTOR 3 -static int _hashtable_insert_node(IntHashTable *,IntHashNode *,int,int,CollisionFunc); +static int _hashtable_insert_node(HashTable *,HashNode *,int,int,CollisionFunc); #if 0 -static int _hashtable_test(IntHashTable *); +static int _hashtable_test(HashTable *); #endif -HashTable hashtable_new(HashFunc hf,HashCmpFunc cf) { - IntHashTable *h; - h=malloc(sizeof(IntHashTable)); +HashTable *hashtable_new(HashFunc hf,HashCmpFunc cf) { + HashTable *h; + h=malloc(sizeof(HashTable)); if (!h) { return NULL; } h->hashFunc=hf; h->cmpFunc=cf; @@ -59,25 +59,24 @@ HashTable hashtable_new(HashFunc hf,HashCmpFunc cf) { h->length=MIN_LENGTH; h->count=0; h->userData=NULL; - h->table=malloc(sizeof(IntHashNode *)*h->length); + h->table=malloc(sizeof(HashNode *)*h->length); if (!h->table) { free(h); return NULL; } - memset (h->table,0,sizeof(IntHashNode *)*h->length); - return (HashTable)h; + memset (h->table,0,sizeof(HashNode *)*h->length); + return h; } -static void _hashtable_destroy(HashTable H,const void *key,const void *val,void *u) { - IntHashTable *h=(IntHashTable *)H; - if (h->keyDestroyFunc&&key) { - h->keyDestroyFunc((HashTable)h,(void *)key); +static void _hashtable_destroy(const HashTable *h,const HashKey_t key,const HashVal_t val,void *u) { + if (h->keyDestroyFunc) { + h->keyDestroyFunc(h,key); } - if (h->valDestroyFunc&&val) { - h->valDestroyFunc((HashTable)h,(void *)val); + if (h->valDestroyFunc) { + h->valDestroyFunc(h,val); } } -static unsigned long _findPrime(unsigned long start,int dir) { +static uint32_t _findPrime(uint32_t start,int dir) { static int unit[]={0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0}; - unsigned long t; + uint32_t t; while (start>1) { if (!unit[start&0x0f]) { start+=dir; @@ -94,22 +93,20 @@ static unsigned long _findPrime(unsigned long start,int dir) { return start; } -static void _hashtable_rehash(IntHashTable *h, - CollisionFunc cf, - unsigned long newSize) { - IntHashNode **oldTable=h->table; - unsigned long i; - IntHashNode *n,*nn; - unsigned long oldSize; +static void _hashtable_rehash(HashTable *h,CollisionFunc cf,uint32_t newSize) { + HashNode **oldTable=h->table; + uint32_t i; + HashNode *n,*nn; + uint32_t oldSize; oldSize=h->length; - h->table=malloc(sizeof(IntHashNode *)*newSize); + h->table=malloc(sizeof(HashNode *)*newSize); if (!h->table) { h->table=oldTable; return; } h->length=newSize; h->count=0; - memset (h->table,0,sizeof(IntHashNode *)*h->length); + memset (h->table,0,sizeof(HashNode *)*h->length); for (i=0;inext; @@ -119,9 +116,9 @@ static void _hashtable_rehash(IntHashTable *h, free(oldTable); } -static void _hashtable_resize(IntHashTable *h) { - unsigned long newSize; - unsigned long oldSize; +static void _hashtable_resize(HashTable *h) { + uint32_t newSize; + uint32_t oldSize; oldSize=h->length; newSize=oldSize; if (h->count*RESIZE_FACTORlength) { @@ -136,13 +133,13 @@ static void _hashtable_resize(IntHashTable *h) { } #if 0 -static int _hashtable_test(IntHashTable *h) { - unsigned long i; +static int _hashtable_test(HashTable *h) { + uint32_t i; int j; - IntHashNode *n; + HashNode *n; for (i=0;ilength;i++) { for (n=h->table[i];n&&n->next;n=n->next) { - j=h->cmpFunc((HashTable)h,n->key,n->next->key); + j=h->cmpFunc(h,n->key,n->next->key); printf ("%c",j?(j<0?'-':'+'):'='); } printf ("\n"); @@ -151,26 +148,26 @@ static int _hashtable_test(IntHashTable *h) { } #endif -static int _hashtable_insert_node(IntHashTable *h,IntHashNode *node,int resize,int update,CollisionFunc cf) { - unsigned long hash=h->hashFunc((HashTable)h,node->key)%h->length; - IntHashNode **n,*nv; +static int _hashtable_insert_node(HashTable *h,HashNode *node,int resize,int update,CollisionFunc cf) { + uint32_t hash=h->hashFunc(h,node->key)%h->length; + HashNode **n,*nv; int i; for (n=&(h->table[hash]);*n;n=&((*n)->next)) { nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,node->key); + i=h->cmpFunc(h,nv->key,node->key); if (!i) { if (cf) { nv->key=node->key; - cf((HashTable)h,&(nv->key),&(nv->value),node->key,node->value); + cf(h,&(nv->key),&(nv->value),node->key,node->value); free(node); return 1; } else { if (h->valDestroyFunc) { - h->valDestroyFunc((HashTable)h,nv->value); + h->valDestroyFunc(h,nv->value); } if (h->keyDestroyFunc) { - h->keyDestroyFunc((HashTable)h,nv->key); + h->keyDestroyFunc(h,nv->key); } nv->key=node->key; nv->value=node->value; @@ -192,17 +189,17 @@ static int _hashtable_insert_node(IntHashTable *h,IntHashNode *node,int resize,i } } -static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int update) { - IntHashNode **n,*nv; - IntHashNode *t; +static int _hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val,int resize,int update) { + HashNode **n,*nv; + HashNode *t; int i; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + uint32_t hash=h->hashFunc(h,key)%h->length; for (n=&(h->table[hash]);*n;n=&((*n)->next)) { nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,key); + i=h->cmpFunc(h,nv->key,key); if (!i) { - if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,nv->value); } + if (h->valDestroyFunc) { h->valDestroyFunc(h,nv->value); } nv->value=val; return 1; } else if (i>0) { @@ -210,7 +207,7 @@ static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int } } if (!update) { - t=malloc(sizeof(IntHashNode)); + t=malloc(sizeof(HashNode)); if (!t) return 0; t->next=*n; *n=t; @@ -224,15 +221,15 @@ static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int } } -static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,void *newVal,int resize) { - IntHashNode **n,*nv; - IntHashNode *t; +static int _hashtable_lookup_or_insert(HashTable *h,HashKey_t key,HashVal_t *retVal,HashVal_t newVal,int resize) { + HashNode **n,*nv; + HashNode *t; int i; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + uint32_t hash=h->hashFunc(h,key)%h->length; for (n=&(h->table[hash]);*n;n=&((*n)->next)) { nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,key); + i=h->cmpFunc(h,nv->key,key); if (!i) { *retVal=nv->value; return 1; @@ -240,7 +237,7 @@ static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,v break; } } - t=malloc(sizeof(IntHashNode)); + t=malloc(sizeof(HashNode)); if (!t) return 0; t->next=*n; *n=t; @@ -252,26 +249,25 @@ static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,v return 1; } -int hashtable_insert_or_update_computed(HashTable H, - void *key, +int hashtable_insert_or_update_computed(HashTable *h, + HashKey_t key, ComputeFunc newFunc, ComputeFunc existsFunc) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode **n,*nv; - IntHashNode *t; + HashNode **n,*nv; + HashNode *t; int i; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; + uint32_t hash=h->hashFunc(h,key)%h->length; for (n=&(h->table[hash]);*n;n=&((*n)->next)) { nv=*n; - i=h->cmpFunc((HashTable)h,nv->key,key); + i=h->cmpFunc(h,nv->key,key); if (!i) { - void *old=nv->value; + HashVal_t old=nv->value; if (existsFunc) { - existsFunc(H,nv->key,&(nv->value)); + existsFunc(h,nv->key,&(nv->value)); if (nv->value!=old) { if (h->valDestroyFunc) { - h->valDestroyFunc((HashTable)h,old); + h->valDestroyFunc(h,old); } } } else { @@ -282,13 +278,13 @@ int hashtable_insert_or_update_computed(HashTable H, break; } } - t=malloc(sizeof(IntHashNode)); + t=malloc(sizeof(HashNode)); if (!t) return 0; t->key=key; t->next=*n; *n=t; if (newFunc) { - newFunc(H,t->key,&(t->value)); + newFunc(h,t->key,&(t->value)); } else { free(t); return 0; @@ -298,52 +294,47 @@ int hashtable_insert_or_update_computed(HashTable H, return 1; } -int hashtable_update(HashTable H,void *key,void *val) { - IntHashTable *h=(IntHashTable *)H; +int hashtable_update(HashTable *h,HashKey_t key,HashVal_t val) { return _hashtable_insert(h,key,val,1,0); } -int hashtable_insert(HashTable H,void *key,void *val) { - IntHashTable *h=(IntHashTable *)H; +int hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val) { return _hashtable_insert(h,key,val,1,0); } -void hashtable_foreach_update(HashTable H,IteratorUpdateFunc i,void *u) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode *n; - unsigned long x; +void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u) { + HashNode *n; + uint32_t x; if (h->table) { for (x=0;xlength;x++) { for (n=h->table[x];n;n=n->next) { - i((HashTable)h,n->key,(void **)&(n->value),u); + i(h,n->key,&(n->value),u); } } } } -void hashtable_foreach(HashTable H,IteratorFunc i,void *u) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode *n; - unsigned long x; +void hashtable_foreach(HashTable *h,IteratorFunc i,void *u) { + HashNode *n; + uint32_t x; if (h->table) { for (x=0;xlength;x++) { for (n=h->table[x];n;n=n->next) { - i((HashTable)h,n->key,n->value,u); + i(h,n->key,n->value,u); } } } } -void hashtable_free(HashTable H) { - IntHashTable *h=(IntHashTable *)H; - IntHashNode *n,*nn; - unsigned long i; +void hashtable_free(HashTable *h) { + HashNode *n,*nn; + uint32_t i; if (h->table) { if (h->keyDestroyFunc || h->keyDestroyFunc) { - hashtable_foreach(H,_hashtable_destroy,NULL); + hashtable_foreach(h,_hashtable_destroy,NULL); } for (i=0;ilength;i++) { for (n=h->table[i];n;n=nn) { @@ -356,31 +347,29 @@ void hashtable_free(HashTable H) { free(h); } -DestroyFunc hashtable_set_value_destroy_func(HashTable H,DestroyFunc d) { - IntHashTable *h=(IntHashTable *)H; - DestroyFunc r=h->valDestroyFunc; +ValDestroyFunc hashtable_set_value_destroy_func(HashTable *h,ValDestroyFunc d) { + ValDestroyFunc r=h->valDestroyFunc; h->valDestroyFunc=d; return r; } -DestroyFunc hashtable_set_key_destroy_func(HashTable H,DestroyFunc d) { - IntHashTable *h=(IntHashTable *)H; - DestroyFunc r=h->keyDestroyFunc; +KeyDestroyFunc hashtable_set_key_destroy_func(HashTable *h,KeyDestroyFunc d) { + KeyDestroyFunc r=h->keyDestroyFunc; h->keyDestroyFunc=d; return r; } -static int _hashtable_remove(IntHashTable *h, - const void *key, - void **keyRet, - void **valRet, +static int _hashtable_remove(HashTable *h, + const HashKey_t key, + HashKey_t *keyRet, + HashVal_t *valRet, int resize) { - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - IntHashNode *n,*p; + uint32_t hash=h->hashFunc(h,key)%h->length; + HashNode *n,*p; int i; for (p=NULL,n=h->table[hash];n;p=n,n=n->next) { - i=h->cmpFunc((HashTable)h,n->key,key); + i=h->cmpFunc(h,n->key,key); if (!i) { if (p) p=n->next; else h->table[hash]=n->next; *keyRet=n->key; @@ -395,17 +384,17 @@ static int _hashtable_remove(IntHashTable *h, return 0; } -static int _hashtable_delete(IntHashTable *h,const void *key,int resize) { - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - IntHashNode *n,*p; +static int _hashtable_delete(HashTable *h,const HashKey_t key,int resize) { + uint32_t hash=h->hashFunc(h,key)%h->length; + HashNode *n,*p; int i; for (p=NULL,n=h->table[hash];n;p=n,n=n->next) { - i=h->cmpFunc((HashTable)h,n->key,key); + i=h->cmpFunc(h,n->key,key); if (!i) { if (p) p=n->next; else h->table[hash]=n->next; - if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,n->value); } - if (h->keyDestroyFunc) { h->keyDestroyFunc((HashTable)h,n->key); } + if (h->valDestroyFunc) { h->valDestroyFunc(h,n->value); } + if (h->keyDestroyFunc) { h->keyDestroyFunc(h,n->key); } free(n); h->count++; return 1; @@ -416,39 +405,33 @@ static int _hashtable_delete(IntHashTable *h,const void *key,int resize) { return 0; } -int hashtable_remove(HashTable H,const void *key,void **keyRet,void **valRet) { - IntHashTable *h=(IntHashTable *)H; +int hashtable_remove(HashTable *h,const HashKey_t key,HashKey_t *keyRet,HashVal_t *valRet) { return _hashtable_remove(h,key,keyRet,valRet,1); } -int hashtable_delete(HashTable H,const void *key) { - IntHashTable *h=(IntHashTable *)H; +int hashtable_delete(HashTable *h,const HashKey_t key) { return _hashtable_delete(h,key,1); } -void hashtable_rehash_compute(HashTable H,CollisionFunc cf) { - IntHashTable *h=(IntHashTable *)H; +void hashtable_rehash_compute(HashTable *h,CollisionFunc cf) { _hashtable_rehash(h,cf,h->length); } -void hashtable_rehash(HashTable H) { - IntHashTable *h=(IntHashTable *)H; +void hashtable_rehash(HashTable *h) { _hashtable_rehash(h,NULL,h->length); } -int hashtable_lookup_or_insert(HashTable H,void *key,void **valp,void *val) { - IntHashTable *h=(IntHashTable *)H; +int hashtable_lookup_or_insert(HashTable *h,HashKey_t key,HashVal_t *valp,HashVal_t val) { return _hashtable_lookup_or_insert(h,key,valp,val,1); } -int hashtable_lookup(const HashTable H,const void *key,void **valp) { - IntHashTable *h=(IntHashTable *)H; - unsigned long hash=h->hashFunc((HashTable)h,key)%h->length; - IntHashNode *n; +int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp) { + uint32_t hash=h->hashFunc(h,key)%h->length; + HashNode *n; int i; for (n=h->table[hash];n;n=n->next) { - i=h->cmpFunc((HashTable)h,n->key,key); + i=h->cmpFunc(h,n->key,key); if (!i) { *valp=n->value; return 1; @@ -459,18 +442,15 @@ int hashtable_lookup(const HashTable H,const void *key,void **valp) { return 0; } -unsigned long hashtable_get_count(const HashTable H) { - IntHashTable *h=(IntHashTable *)H; +uint32_t hashtable_get_count(const HashTable *h) { return h->count; } -void *hashtable_get_user_data(const HashTable H) { - IntHashTable *h=(IntHashTable *)H; +void *hashtable_get_user_data(const HashTable *h) { return h->userData; } -void *hashtable_set_user_data(HashTable H,void *data) { - IntHashTable *h=(IntHashTable *)H; +void *hashtable_set_user_data(HashTable *h,void *data) { void *r=h->userData; h->userData=data; return r; diff --git a/libImaging/QuantHash.h b/libImaging/QuantHash.h index b98b56eaa..028b4af89 100644 --- a/libImaging/QuantHash.h +++ b/libImaging/QuantHash.h @@ -9,28 +9,41 @@ * See the README file for information on usage and redistribution. */ -#ifndef __HASH_H__ -#define __HASH_H__ +#ifndef __QUANTHASH_H__ +#define __QUANTHASH_H__ #include "QuantTypes.h" -HashTable hashtable_new(HashFunc,HashCmpFunc); -void hashtable_free(HashTable); -void hashtable_foreach(HashTable,IteratorFunc,void *); -void hashtable_foreach_update(HashTable,IteratorUpdateFunc,void *); -int hashtable_insert(HashTable,void *,void *); -int hashtable_update(HashTable,void *,void *); -int hashtable_lookup(const HashTable,const void *,void **); -int hashtable_lookup_or_insert(HashTable,void *,void **,void *); -int hashtable_insert_or_update_computed(HashTable,void *,ComputeFunc,ComputeFunc); -int hashtable_delete(HashTable,const void *); -int hashtable_remove(HashTable,const void *,void **,void **); -void *hashtable_set_user_data(HashTable,void *); -void *hashtable_get_user_data(const HashTable); -DestroyFunc hashtable_set_key_destroy_func(HashTable,DestroyFunc); -DestroyFunc hashtable_set_value_destroy_func(HashTable,DestroyFunc); -unsigned long hashtable_get_count(const HashTable); -void hashtable_rehash(HashTable); -void hashtable_rehash_compute(HashTable,CollisionFunc); +typedef struct _HashTable HashTable; +typedef Pixel HashKey_t; +typedef uint32_t HashVal_t; -#endif +typedef uint32_t (*HashFunc)(const HashTable *,const HashKey_t); +typedef int (*HashCmpFunc)(const HashTable *,const HashKey_t,const HashKey_t); +typedef void (*IteratorFunc)(const HashTable *,const HashKey_t,const HashVal_t,void *); +typedef void (*IteratorUpdateFunc)(const HashTable *,const HashKey_t,HashVal_t *,void *); +typedef void (*KeyDestroyFunc)(const HashTable *,HashKey_t); +typedef void (*ValDestroyFunc)(const HashTable *,HashVal_t); +typedef void (*ComputeFunc)(const HashTable *,const HashKey_t,HashVal_t *); +typedef void (*CollisionFunc)(const HashTable *,HashKey_t *,HashVal_t *,HashKey_t,HashVal_t); + +HashTable * hashtable_new(HashFunc hf,HashCmpFunc cf); +void hashtable_free(HashTable *h); +void hashtable_foreach(HashTable *h,IteratorFunc i,void *u); +void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u); +int hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val); +int hashtable_update(HashTable *h,HashKey_t key,HashVal_t val); +int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp); +int hashtable_lookup_or_insert(HashTable *h,HashKey_t key,HashVal_t *valp,HashVal_t val); +int hashtable_insert_or_update_computed(HashTable *h,HashKey_t key,ComputeFunc newFunc,ComputeFunc existsFunc); +int hashtable_delete(HashTable *h,const HashKey_t key); +int hashtable_remove(HashTable *h,const HashKey_t key,HashKey_t *keyRet,HashVal_t *valRet); +void *hashtable_set_user_data(HashTable *h,void *data); +void *hashtable_get_user_data(const HashTable *h); +KeyDestroyFunc hashtable_set_key_destroy_func(HashTable *,KeyDestroyFunc d); +ValDestroyFunc hashtable_set_value_destroy_func(HashTable *,ValDestroyFunc d); +uint32_t hashtable_get_count(const HashTable *h); +void hashtable_rehash(HashTable *h); +void hashtable_rehash_compute(HashTable *h,CollisionFunc cf); + +#endif // __QUANTHASH_H__ diff --git a/libImaging/QuantHeap.c b/libImaging/QuantHeap.c index 9332a5cd7..bddcf142c 100644 --- a/libImaging/QuantHeap.c +++ b/libImaging/QuantHeap.c @@ -21,31 +21,29 @@ #include #include -#include "QuantHash.h" -#include "QuantDefines.h" +#include "QuantHeap.h" -typedef struct { +typedef struct _Heap { void **heap; int heapsize; int heapcount; HeapCmpFunc cf; -} IntHeap; +} Heap; #define INITIAL_SIZE 256 -#define DEBUG +// #define DEBUG #ifdef DEBUG -static int _heap_test(Heap); +static int _heap_test(Heap *); #endif -void ImagingQuantHeapFree(Heap H) { - IntHeap *h=(IntHeap *)H; +void ImagingQuantHeapFree(Heap *h) { free(h->heap); free(h); } -static int _heap_grow(IntHeap *h,int newsize) { +static int _heap_grow(Heap *h,int newsize) { void *newheap; if (!newsize) newsize=h->heapsize<<1; if (newsizeheapsize) return 0; @@ -59,15 +57,14 @@ static int _heap_grow(IntHeap *h,int newsize) { } #ifdef DEBUG -static int _heap_test(Heap H) { - IntHeap *h=(IntHeap *)H; +static int _heap_test(Heap *h) { int k; for (k=1;k*2<=h->heapcount;k++) { - if (h->cf(H,h->heap[k],h->heap[k*2])<0) { + if (h->cf(h,h->heap[k],h->heap[k*2])<0) { printf ("heap is bad\n"); return 0; } - if (k*2+1<=h->heapcount && h->cf(H,h->heap[k],h->heap[k*2+1])<0) { + if (k*2+1<=h->heapcount && h->cf(h,h->heap[k],h->heap[k*2+1])<0) { printf ("heap is bad\n"); return 0; } @@ -76,8 +73,7 @@ static int _heap_test(Heap H) { } #endif -int ImagingQuantHeapRemove(Heap H,void **r) { - IntHeap *h=(IntHeap *)H; +int ImagingQuantHeapRemove(Heap* h,void **r) { int k,l; void *v; @@ -89,31 +85,30 @@ int ImagingQuantHeapRemove(Heap H,void **r) { for (k=1;k*2<=h->heapcount;k=l) { l=k*2; if (lheapcount) { - if (h->cf(H,h->heap[l],h->heap[l+1])<0) { + if (h->cf(h,h->heap[l],h->heap[l+1])<0) { l++; } } - if (h->cf(H,v,h->heap[l])>0) { + if (h->cf(h,v,h->heap[l])>0) { break; } h->heap[k]=h->heap[l]; } h->heap[k]=v; #ifdef DEBUG - if (!_heap_test(H)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); } + if (!_heap_test(h)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); } #endif return 1; } -int ImagingQuantHeapAdd(Heap H,void *val) { - IntHeap *h=(IntHeap *)H; +int ImagingQuantHeapAdd(Heap *h,void *val) { int k; if (h->heapcount==h->heapsize-1) { _heap_grow(h,0); } k=++h->heapcount; while (k!=1) { - if (h->cf(H,val,h->heap[k/2])<=0) { + if (h->cf(h,val,h->heap[k/2])<=0) { break; } h->heap[k]=h->heap[k/2]; @@ -121,13 +116,12 @@ int ImagingQuantHeapAdd(Heap H,void *val) { } h->heap[k]=val; #ifdef DEBUG - if (!_heap_test(H)) { printf ("oops - heap_add messed up the heap\n"); exit(1); } + if (!_heap_test(h)) { printf ("oops - heap_add messed up the heap\n"); exit(1); } #endif return 1; } -int ImagingQuantHeapTop(Heap H,void **r) { - IntHeap *h=(IntHeap *)H; +int ImagingQuantHeapTop(Heap *h,void **r) { if (!h->heapcount) { return 0; } @@ -136,15 +130,14 @@ int ImagingQuantHeapTop(Heap H,void **r) { } Heap *ImagingQuantHeapNew(HeapCmpFunc cf) { - IntHeap *h; + Heap *h; - h=malloc(sizeof(IntHeap)); + h=malloc(sizeof(Heap)); if (!h) return NULL; h->heapsize=INITIAL_SIZE; h->heap=malloc(sizeof(void *)*h->heapsize); if (!h->heap) { free(h); return NULL; } h->heapcount=0; h->cf=cf; - return (Heap)h; + return h; } - diff --git a/libImaging/QuantHeap.h b/libImaging/QuantHeap.h index 5a213c42a..77bf0d9d5 100644 --- a/libImaging/QuantHeap.h +++ b/libImaging/QuantHeap.h @@ -9,15 +9,19 @@ * See the README file for information on usage and redistribution. */ -#ifndef __HEAP_H__ -#define __HEAP_H__ +#ifndef __QUANTHEAP_H__ +#define __QUANTHEAP_H__ #include "QuantTypes.h" -void ImagingQuantHeapFree(Heap); -int ImagingQuantHeapRemove(Heap,void **); -int ImagingQuantHeapAdd(Heap,void *); -int ImagingQuantHeapTop(Heap,void **); +typedef struct _Heap Heap; + +typedef int (*HeapCmpFunc)(const Heap *,const void *,const void *); + +void ImagingQuantHeapFree(Heap *); +int ImagingQuantHeapRemove(Heap *,void **); +int ImagingQuantHeapAdd(Heap *,void *); +int ImagingQuantHeapTop(Heap *,void **); Heap *ImagingQuantHeapNew(HeapCmpFunc); -#endif +#endif // __QUANTHEAP_H__ diff --git a/libImaging/QuantOctree.c b/libImaging/QuantOctree.c index fcdf9e0b0..e841d6fbb 100644 --- a/libImaging/QuantOctree.c +++ b/libImaging/QuantOctree.c @@ -27,15 +27,15 @@ #include #include -#include "Quant.h" +#include "QuantOctree.h" typedef struct _ColorBucket{ /* contains palette index when used for look up cube */ - unsigned long count; - unsigned long r; - unsigned long g; - unsigned long b; - unsigned long a; + uint32_t count; + uint32_t r; + uint32_t g; + uint32_t b; + uint32_t a; } *ColorBucket; typedef struct _ColorCube{ @@ -262,7 +262,7 @@ set_lookup_value(const ColorCube cube, const Pixel *p, long value) { bucket->count = value; } -unsigned long +uint32_t lookup_color(const ColorCube cube, const Pixel *p) { ColorBucket bucket = color_bucket_from_cube(cube, p); return bucket->count; @@ -302,9 +302,9 @@ create_palette_array(const ColorBucket palette, unsigned int paletteLength) { static void map_image_pixels(const Pixel *pixelData, - unsigned long nPixels, + uint32_t nPixels, const ColorCube lookupCube, - unsigned long *pixelArray) + uint32_t *pixelArray) { long i; for (i=0; i +#endif -typedef unsigned long (*HashFunc)(const HashTable,const void *); -typedef int (*HashCmpFunc)(const HashTable,const void *,const void *); -typedef void (*IteratorFunc)(const HashTable,const void *,const void *,void *); -typedef void (*IteratorUpdateFunc)(const HashTable,const void *,void **,void *); -typedef void (*DestroyFunc)(const HashTable,void *); -typedef void (*ComputeFunc)(const HashTable,const void *,void **); -typedef void (*CollisionFunc)(const HashTable,void **,void **,void *,void *); - -typedef int (*HeapCmpFunc)(const Heap,const void *,const void *); +typedef union { + struct { + unsigned char r,g,b,a; + } c; + struct { + unsigned char v[4]; + } a; + uint32_t v; +} Pixel; #endif From 836e3e05d8644d4f65c44a1aa02d953762900615 Mon Sep 17 00:00:00 2001 From: David Schmidt Date: Tue, 9 Apr 2013 13:21:38 +0200 Subject: [PATCH 30/31] create a palette before converting transparent L-Mode to RGBA fixes #154 --- PIL/Image.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/PIL/Image.py b/PIL/Image.py index 1e29db198..cafc5a22f 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -713,6 +713,16 @@ class Image: if dither is None: dither = FLOYDSTEINBERG + # fake a P-mode image, otherwise the transparency will get lost as there is + # currently no other way to convert transparency into an RGBA image + if self.mode == "L" and mode == "RGBA" and "transparency" in self.info: + from PIL import ImagePalette + self.mode = "P" + bytePalette = bytes([i//3 for i in range(768)]) + self.palette = ImagePalette.raw("RGB", bytePalette) + self.palette.dirty = 1 + self.load() + try: im = self.im.convert(mode, dither) except ValueError: From 2838015c8492c428ca48df347c2235330b5992c1 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Tue, 9 Apr 2013 12:25:55 -0700 Subject: [PATCH 31/31] header formating --- README.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index f7e559f76..e3b0e161b 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,7 @@ Why a fork? PIL is not setuptools compatible. Please see http://mail.python.org/pipermail/image-sig/2010-August/006480.html for a more detailed explanation. Also, PIL's current bi-yearly (or greater) release schedule is too infrequent to accomodate the large number and frequency of issues reported. Porting -======= +------- Pillow is a functional dropin for the Python Imaging Library. To run under Pillow, existing code needs to be modified to import the Imaging @@ -101,12 +101,12 @@ Current platform support for Pillow. Binary distributions are contributed for ea .. [2] In some cases, x86 support may indicate 32-bit compilation on 64-bit architecture (vs. compilation on 32-bit hardware). Installation -============ +------------ If there is a binary package for your system, that is the preferred way of obtaining Pillow. Building from Source --------------------- ++++++++++ Some of Pillow's features require external libraries. @@ -135,7 +135,7 @@ Once you have assembed the prerequisites, run: $ pip install pillow Platform Specific Instructions ------------------------------- ++++++++++ Mac OSX ******* @@ -158,6 +158,8 @@ The library prerequisites are installed with:: # Ubuntu 12.04 LTS sudo apt-get install libtiff4-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms1-dev libwebp-dev +Windows +******* Donations ---------