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: 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/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 ## diff --git a/PIL/JpegImagePlugin.py b/PIL/JpegImagePlugin.py index 6df8b926c..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") @@ -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/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index d556360a9..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. @@ -550,11 +550,14 @@ 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", 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]) elif im.mode == "L": transparency = max(0, min(65535, im.encoderinfo["transparency"])) chunk(fp, b"tRNS", o16(transparency)) diff --git a/README.rst b/README.rst index 73b97f983..e3b0e161b 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. @@ -22,6 +23,26 @@ 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 +modules from the PIL namespace instead of the global namespace. + +Change:: + + import Image + +to:: + + from PIL import Image + +Note that if your code imports _imaging, that will also be hosted in the PIL namespace. The preferred method of importing _imaging is:: + + from PIL import Image + _imaging = Image.core + What about image code bugs? --------------------------- @@ -80,18 +101,18 @@ 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. * libjpeg provides JPEG functionality. - * Pillow has been tested with libjpev versions 6b and 8 + * Pillow has been tested with libjpev versions 6b, 8, and 9 * zlib provides access to compressed PNGs @@ -105,7 +126,7 @@ Some of Pillow's features require external libraries. * libwebp provides the Webp format. -If the prerequisites are installed in the standard library locations for your machine, no configuration shoule be required. If they are installed in a non-standard location, you may need to configure setuptools to use those locations. See [[url here]] for more information. +If the prerequisites are installed in the standard library locations for your machine, no configuration shoule be required. If they are installed in a non-standard location, you may need to configure setuptools to use those locations. Once you have assembed the prerequisites, run: @@ -114,7 +135,7 @@ Once you have assembed the prerequisites, run: $ pip install pillow Platform Specific Instructions ------------------------------- ++++++++++ Mac OSX ******* @@ -137,23 +158,23 @@ 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 -##Undone## Debian library versions. +Windows +******* +Donations +--------- +You can help fund Pillow development! -Porting -======= +.. Note:: New contributors: please add your name (and donation preference) here and send a pull request. -Pillow is a functional dropin for the Python Imaging Library. To run under Pillow, existing code needs to be modified to import the Imaging modules from the PIL namespace instead of the global namespace. - -Change:: - - import Image - -to:: - - from PIL import Image +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 | ++--------------------------------------+---------------------------------------+ @@ -463,4 +484,3 @@ Python Imaging Library http://mingw.org (compiler) http://sebsauvage.net/python/mingw.html (build instructions) http://sourceforge.net/projects/gnuwin32 (prebuilt libraries) - 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)) { diff --git a/Tests/images/l_trns.png b/Tests/images/l_trns.png new file mode 100644 index 000000000..a26a82076 Binary files /dev/null and b/Tests/images/l_trns.png differ diff --git a/Tests/images/p_trns_single.png b/Tests/images/p_trns_single.png new file mode 100644 index 000000000..8f37bd452 Binary files /dev/null and b/Tests/images/p_trns_single.png differ 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) 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/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) diff --git a/Tests/test_file_webp.py b/Tests/test_file_webp.py index 460b22d9c..5d48f0aff 100644 --- a/Tests/test_file_webp.py +++ b/Tests/test_file_webp.py @@ -2,6 +2,11 @@ from tester import * from PIL import Image +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?""" @@ -37,7 +42,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/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), ' epsilon %.4f" %(ave_diff, epsilon)) + else: + success() + def tempfile(template, *extra): import os, sys files = [] diff --git a/_imaging.c b/_imaging.c index b62cd68b3..2ee7eef42 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) { @@ -1369,7 +1369,6 @@ _putdata(ImagingObject* self, PyObject* args) #ifdef WITH_QUANTIZE -#include "Quant.h" static PyObject* _quantize(ImagingObject* self, PyObject* args) { @@ -1377,7 +1376,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 +1399,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 +1430,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 +1456,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 +1486,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 +1511,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 +1526,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 +1546,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 +1598,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 +1636,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 +1690,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 +1755,7 @@ _transpose(ImagingObject* self, PyObject* args) int op; if (!PyArg_ParseTuple(args, "i", &op)) - return NULL; + return NULL; imIn = self->image; @@ -1835,8 +1834,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 +1850,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 +1914,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 +1939,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 +1951,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 +1966,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 +1993,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 +2004,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 +2015,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 +2026,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 +2037,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 +2053,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 +2071,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 +2084,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 +2095,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 +2106,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 +2117,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 +2128,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 +2151,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 +2294,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 +2341,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 +2361,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 +2396,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 +2416,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 +2449,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 +2469,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 +2518,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 +2536,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 +2557,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 +2571,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 +2581,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 +2597,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 +2618,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 +2663,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 +2726,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 +2770,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 +2786,7 @@ pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) } /* -------------------------------------------------------------------- */ -/* EFFECTS (experimental) */ +/* EFFECTS (experimental) */ /* -------------------------------------------------------------------- */ #ifdef WITH_EFFECTS @@ -2806,7 +2805,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 +2816,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 +2827,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 +2835,7 @@ _effect_spread(ImagingObject* self, PyObject* args) #endif /* -------------------------------------------------------------------- */ -/* UTILITIES */ +/* UTILITIES */ /* -------------------------------------------------------------------- */ static PyObject* @@ -2851,7 +2850,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 +2866,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 +2887,7 @@ _getcodecstatus(PyObject* self, PyObject* args) } /* -------------------------------------------------------------------- */ -/* DEBUGGING HELPERS */ +/* DEBUGGING HELPERS */ /* -------------------------------------------------------------------- */ @@ -2900,7 +2899,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 +3025,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 +3099,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 +3135,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 +3169,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*/ diff --git a/_imagingft.c b/_imagingft.c index 7028293ec..e19125e04 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; diff --git a/libImaging/AlphaComposite.c b/libImaging/AlphaComposite.c index c5801b779..9433fae53 100644 --- a/libImaging/AlphaComposite.c +++ b/libImaging/AlphaComposite.c @@ -12,81 +12,85 @@ #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* dst = (rgba8*) imDst->image[y]; + rgba8* src = (rgba8*) imSrc->image[y]; + rgba8* out = (rgba8*) imOut->image[y]; - for (x = 0; x < imDst->linesize; x += 4) { + for (x = 0; x < imDst->xsize; 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. + *out = *dst; + } else { + // Integer implementation with increased precision. + // Each variable has extra meaningful bits. + // Divisions are rounded. - srcR = src[x + 0] / 255.0; - srcG = src[x + 1] / 255.0; - srcB = src[x + 2] / 255.0; - srcA = src[x + 3] / 255.0; + // 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 - 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; - } - } + UINT32 tmpr, tmpg, tmpb; + UINT16 blend = dst->a * (255 - src->a); + 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 = 255 * 128 - coef1; - 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); + #define SHIFTFORDIV255(a)\ + ((((a) >> 8) + a) >> 8) - } + tmpr = src->r * coef1 + dst->r * coef2 + (0x80 << 7); + out->r = SHIFTFORDIV255(tmpr) >> 7; + tmpg = src->g * coef1 + dst->g * coef2 + (0x80 << 7); + out->g = SHIFTFORDIV255(tmpg) >> 7; + tmpb = src->b * coef1 + dst->b * coef2 + (0x80 << 7); + out->b = SHIFTFORDIV255(tmpb) >> 7; + out->a = SHIFTFORDIV255(outa255 + 0x80); + } + + dst++; src++; out++; + } } 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 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)