File: | _imaging.c |
Warning: | line 4172, column 38 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * The Python Imaging Library. | |||
3 | * | |||
4 | * the imaging library bindings | |||
5 | * | |||
6 | * history: | |||
7 | * 1995-09-24 fl Created | |||
8 | * 1996-03-24 fl Ready for first public release (release 0.0) | |||
9 | * 1996-03-25 fl Added fromstring (for Jack's "img" library) | |||
10 | * 1996-03-28 fl Added channel operations | |||
11 | * 1996-03-31 fl Added point operation | |||
12 | * 1996-04-08 fl Added new/new_block/new_array factories | |||
13 | * 1996-04-13 fl Added decoders | |||
14 | * 1996-05-04 fl Added palette hack | |||
15 | * 1996-05-12 fl Compile cleanly as C++ | |||
16 | * 1996-05-19 fl Added matrix conversions, gradient fills | |||
17 | * 1996-05-27 fl Added display_mode | |||
18 | * 1996-07-22 fl Added getbbox, offset | |||
19 | * 1996-07-23 fl Added sequence semantics | |||
20 | * 1996-08-13 fl Added logical operators, point mode | |||
21 | * 1996-08-16 fl Modified paste interface | |||
22 | * 1996-09-06 fl Added putdata methods, use abstract interface | |||
23 | * 1996-11-01 fl Added xbm encoder | |||
24 | * 1996-11-04 fl Added experimental path stuff, draw_lines, etc | |||
25 | * 1996-12-10 fl Added zip decoder, crc32 interface | |||
26 | * 1996-12-14 fl Added modulo arithmetics | |||
27 | * 1996-12-29 fl Added zip encoder | |||
28 | * 1997-01-03 fl Added fli and msp decoders | |||
29 | * 1997-01-04 fl Added experimental sun_rle and tga_rle decoders | |||
30 | * 1997-01-05 fl Added gif encoder, getpalette hack | |||
31 | * 1997-02-23 fl Added histogram mask | |||
32 | * 1997-05-12 fl Minor tweaks to match the IFUNC95 interface | |||
33 | * 1997-05-21 fl Added noise generator, spread effect | |||
34 | * 1997-06-05 fl Added mandelbrot generator | |||
35 | * 1997-08-02 fl Modified putpalette to coerce image mode if necessary | |||
36 | * 1998-01-11 fl Added INT32 support | |||
37 | * 1998-01-22 fl Fixed draw_points to draw the last point too | |||
38 | * 1998-06-28 fl Added getpixel, getink, draw_ink | |||
39 | * 1998-07-12 fl Added getextrema | |||
40 | * 1998-07-17 fl Added point conversion to arbitrary formats | |||
41 | * 1998-09-21 fl Added support for resampling filters | |||
42 | * 1998-09-22 fl Added support for quad transform | |||
43 | * 1998-12-29 fl Added support for arcs, chords, and pieslices | |||
44 | * 1999-01-10 fl Added some experimental arrow graphics stuff | |||
45 | * 1999-02-06 fl Added draw_bitmap, font acceleration stuff | |||
46 | * 2001-04-17 fl Fixed some egcs compiler nits | |||
47 | * 2001-09-17 fl Added screen grab primitives (win32) | |||
48 | * 2002-03-09 fl Added stretch primitive | |||
49 | * 2002-03-10 fl Fixed filter handling in rotate | |||
50 | * 2002-06-06 fl Added I, F, and RGB support to putdata | |||
51 | * 2002-06-08 fl Added rankfilter | |||
52 | * 2002-06-09 fl Added support for user-defined filter kernels | |||
53 | * 2002-11-19 fl Added clipboard grab primitives (win32) | |||
54 | * 2002-12-11 fl Added draw context | |||
55 | * 2003-04-26 fl Tweaks for Python 2.3 beta 1 | |||
56 | * 2003-05-21 fl Added createwindow primitive (win32) | |||
57 | * 2003-09-13 fl Added thread section hooks | |||
58 | * 2003-09-15 fl Added expand helper | |||
59 | * 2003-09-26 fl Added experimental LA support | |||
60 | * 2004-02-21 fl Handle zero-size images in quantize | |||
61 | * 2004-06-05 fl Added ptr attribute (used to access Imaging objects) | |||
62 | * 2004-06-05 fl Don't crash when fetching pixels from zero-wide images | |||
63 | * 2004-09-17 fl Added getcolors | |||
64 | * 2004-10-04 fl Added modefilter | |||
65 | * 2005-10-02 fl Added access proxy | |||
66 | * 2006-06-18 fl Always draw last point in polyline | |||
67 | * | |||
68 | * Copyright (c) 1997-2006 by Secret Labs AB | |||
69 | * Copyright (c) 1995-2006 by Fredrik Lundh | |||
70 | * | |||
71 | * See the README file for information on usage and redistribution. | |||
72 | */ | |||
73 | ||||
74 | #define PY_SSIZE_T_CLEAN | |||
75 | #include "Python.h" | |||
76 | ||||
77 | #ifdef HAVE_LIBJPEG1 | |||
78 | #include "jconfig.h" | |||
79 | #endif | |||
80 | ||||
81 | #ifdef HAVE_LIBZ1 | |||
82 | #include "zlib.h" | |||
83 | #endif | |||
84 | ||||
85 | #ifdef HAVE_LIBTIFF1 | |||
86 | #ifndef _TIFFIO_ | |||
87 | #include <tiffio.h> | |||
88 | #endif | |||
89 | #endif | |||
90 | ||||
91 | #include "libImaging/Imaging.h" | |||
92 | ||||
93 | #define _USE_MATH_DEFINES | |||
94 | #include <math.h> | |||
95 | ||||
96 | /* Configuration stuff. Feel free to undef things you don't need. */ | |||
97 | #define WITH_IMAGECHOPS /* ImageChops support */ | |||
98 | #define WITH_IMAGEDRAW /* ImageDraw support */ | |||
99 | #define WITH_MAPPING /* use memory mapping to read some file formats */ | |||
100 | #define WITH_IMAGEPATH /* ImagePath stuff */ | |||
101 | #define WITH_ARROW /* arrow graphics stuff (experimental) */ | |||
102 | #define WITH_EFFECTS /* special effects */ | |||
103 | #define WITH_QUANTIZE /* quantization support */ | |||
104 | #define WITH_RANKFILTER /* rank filter */ | |||
105 | #define WITH_MODEFILTER /* mode filter */ | |||
106 | #define WITH_THREADING /* "friendly" threading support */ | |||
107 | #define WITH_UNSHARPMASK /* Kevin Cazabon's unsharpmask module */ | |||
108 | ||||
109 | #undef VERBOSE | |||
110 | ||||
111 | #define B16(p, i)((((int)p[(i)]) << 8) + p[(i) + 1]) ((((int)p[(i)]) << 8) + p[(i) + 1]) | |||
112 | #define L16(p, i)((((int)p[(i) + 1]) << 8) + p[(i)]) ((((int)p[(i) + 1]) << 8) + p[(i)]) | |||
113 | #define S16(v)((v) < 32768 ? (v) : ((v)-65536)) ((v) < 32768 ? (v) : ((v)-65536)) | |||
114 | ||||
115 | /* -------------------------------------------------------------------- */ | |||
116 | /* OBJECT ADMINISTRATION */ | |||
117 | /* -------------------------------------------------------------------- */ | |||
118 | ||||
119 | typedef struct { | |||
120 | PyObject_HEADPyObject ob_base; Imaging image; | |||
121 | ImagingAccess access; | |||
122 | } ImagingObject; | |||
123 | ||||
124 | static PyTypeObject Imaging_Type; | |||
125 | ||||
126 | #ifdef WITH_IMAGEDRAW | |||
127 | ||||
128 | typedef struct { | |||
129 | /* to write a character, cut out sxy from glyph data, place | |||
130 | at current position plus dxy, and advance by (dx, dy) */ | |||
131 | int dx, dy; | |||
132 | int dx0, dy0, dx1, dy1; | |||
133 | int sx0, sy0, sx1, sy1; | |||
134 | } Glyph; | |||
135 | ||||
136 | typedef struct { | |||
137 | PyObject_HEADPyObject ob_base; ImagingObject *ref; | |||
138 | Imaging bitmap; | |||
139 | int ysize; | |||
140 | int baseline; | |||
141 | Glyph glyphs[256]; | |||
142 | } ImagingFontObject; | |||
143 | ||||
144 | static PyTypeObject ImagingFont_Type; | |||
145 | ||||
146 | typedef struct { | |||
147 | PyObject_HEADPyObject ob_base; ImagingObject *image; | |||
148 | UINT8unsigned char ink[4]; | |||
149 | int blend; | |||
150 | } ImagingDrawObject; | |||
151 | ||||
152 | static PyTypeObject ImagingDraw_Type; | |||
153 | ||||
154 | #endif | |||
155 | ||||
156 | typedef struct { | |||
157 | PyObject_HEADPyObject ob_base; ImagingObject *image; | |||
158 | int readonly; | |||
159 | } PixelAccessObject; | |||
160 | ||||
161 | static PyTypeObject PixelAccess_Type; | |||
162 | ||||
163 | PyObject * | |||
164 | PyImagingNew(Imaging imOut) { | |||
165 | ImagingObject *imagep; | |||
166 | ||||
167 | if (!imOut) { | |||
168 | return NULL((void*)0); | |||
169 | } | |||
170 | ||||
171 | imagep = PyObject_New(ImagingObject, &Imaging_Type)( (ImagingObject *) _PyObject_New(&Imaging_Type) ); | |||
172 | if (imagep == NULL((void*)0)) { | |||
173 | ImagingDelete(imOut); | |||
174 | return NULL((void*)0); | |||
175 | } | |||
176 | ||||
177 | #ifdef VERBOSE | |||
178 | printf("imaging %p allocated\n", imagep)__printf_chk (2 - 1, "imaging %p allocated\n", imagep); | |||
179 | #endif | |||
180 | ||||
181 | imagep->image = imOut; | |||
182 | imagep->access = ImagingAccessNew(imOut); | |||
183 | ||||
184 | return (PyObject *)imagep; | |||
185 | } | |||
186 | ||||
187 | static void | |||
188 | _dealloc(ImagingObject *imagep) { | |||
189 | #ifdef VERBOSE | |||
190 | printf("imaging %p deleted\n", imagep)__printf_chk (2 - 1, "imaging %p deleted\n", imagep); | |||
191 | #endif | |||
192 | ||||
193 | if (imagep->access) { | |||
194 | ImagingAccessDelete(imagep->image, imagep->access); | |||
195 | } | |||
196 | ImagingDelete(imagep->image); | |||
197 | PyObject_DelPyObject_Free(imagep); | |||
198 | } | |||
199 | ||||
200 | #define PyImaging_Check(op)((((PyObject*)(op))->ob_type) == &Imaging_Type) (Py_TYPE(op)(((PyObject*)(op))->ob_type) == &Imaging_Type) | |||
201 | ||||
202 | Imaging | |||
203 | PyImaging_AsImaging(PyObject *op) { | |||
204 | if (!PyImaging_Check(op)((((PyObject*)(op))->ob_type) == &Imaging_Type)) { | |||
205 | PyErr_BadInternalCall()_PyErr_BadInternalCall("src/_imaging.c", 205); | |||
206 | return NULL((void*)0); | |||
207 | } | |||
208 | ||||
209 | return ((ImagingObject *)op)->image; | |||
210 | } | |||
211 | ||||
212 | /* -------------------------------------------------------------------- */ | |||
213 | /* THREAD HANDLING */ | |||
214 | /* -------------------------------------------------------------------- */ | |||
215 | ||||
216 | void | |||
217 | ImagingSectionEnter(ImagingSectionCookie *cookie) { | |||
218 | #ifdef WITH_THREADING | |||
219 | *cookie = (PyThreadState *)PyEval_SaveThread(); | |||
220 | #endif | |||
221 | } | |||
222 | ||||
223 | void | |||
224 | ImagingSectionLeave(ImagingSectionCookie *cookie) { | |||
225 | #ifdef WITH_THREADING | |||
226 | PyEval_RestoreThread((PyThreadState *)*cookie); | |||
227 | #endif | |||
228 | } | |||
229 | ||||
230 | /* -------------------------------------------------------------------- */ | |||
231 | /* BUFFER HANDLING */ | |||
232 | /* -------------------------------------------------------------------- */ | |||
233 | /* Python compatibility API */ | |||
234 | ||||
235 | int | |||
236 | PyImaging_CheckBuffer(PyObject *buffer) { | |||
237 | return PyObject_CheckBuffer(buffer)(((buffer)->ob_type->tp_as_buffer != ((void*)0)) && ((buffer)->ob_type->tp_as_buffer->bf_getbuffer != ( (void*)0))); | |||
238 | } | |||
239 | ||||
240 | int | |||
241 | PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view) { | |||
242 | /* must call check_buffer first! */ | |||
243 | return PyObject_GetBuffer(buffer, view, PyBUF_SIMPLE0); | |||
244 | } | |||
245 | ||||
246 | /* -------------------------------------------------------------------- */ | |||
247 | /* EXCEPTION REROUTING */ | |||
248 | /* -------------------------------------------------------------------- */ | |||
249 | ||||
250 | /* error messages */ | |||
251 | static const char *must_be_sequence = "argument must be a sequence"; | |||
252 | static const char *must_be_two_coordinates = | |||
253 | "coordinate list must contain exactly 2 coordinates"; | |||
254 | static const char *wrong_mode = "unrecognized image mode"; | |||
255 | static const char *wrong_raw_mode = "unrecognized raw mode"; | |||
256 | static const char *outside_image = "image index out of range"; | |||
257 | static const char *outside_palette = "palette index out of range"; | |||
258 | static const char *wrong_palette_size = "invalid palette size"; | |||
259 | static const char *no_palette = "image has no palette"; | |||
260 | static const char *readonly = "image is readonly"; | |||
261 | /* static const char* no_content = "image has no content"; */ | |||
262 | ||||
263 | void * | |||
264 | ImagingError_OSError(void) { | |||
265 | PyErr_SetString(PyExc_OSError, "error when accessing file"); | |||
266 | return NULL((void*)0); | |||
267 | } | |||
268 | ||||
269 | void * | |||
270 | ImagingError_MemoryError(void) { | |||
271 | return PyErr_NoMemory(); | |||
272 | } | |||
273 | ||||
274 | void * | |||
275 | ImagingError_Mismatch(void) { | |||
276 | PyErr_SetString(PyExc_ValueError, "images do not match"); | |||
277 | return NULL((void*)0); | |||
278 | } | |||
279 | ||||
280 | void * | |||
281 | ImagingError_ModeError(void) { | |||
282 | PyErr_SetString(PyExc_ValueError, "image has wrong mode"); | |||
283 | return NULL((void*)0); | |||
284 | } | |||
285 | ||||
286 | void * | |||
287 | ImagingError_ValueError(const char *message) { | |||
288 | PyErr_SetString( | |||
289 | PyExc_ValueError, (message) ? (char *)message : "unrecognized argument value"); | |||
290 | return NULL((void*)0); | |||
291 | } | |||
292 | ||||
293 | void | |||
294 | ImagingError_Clear(void) { | |||
295 | PyErr_Clear(); | |||
296 | } | |||
297 | ||||
298 | /* -------------------------------------------------------------------- */ | |||
299 | /* HELPERS */ | |||
300 | /* -------------------------------------------------------------------- */ | |||
301 | ||||
302 | static int | |||
303 | getbands(const char *mode) { | |||
304 | Imaging im; | |||
305 | int bands; | |||
306 | ||||
307 | /* FIXME: add primitive to libImaging to avoid extra allocation */ | |||
308 | im = ImagingNew(mode, 0, 0); | |||
309 | if (!im) { | |||
310 | return -1; | |||
311 | } | |||
312 | ||||
313 | bands = im->bands; | |||
314 | ||||
315 | ImagingDelete(im); | |||
316 | ||||
317 | return bands; | |||
318 | } | |||
319 | ||||
320 | #define TYPE_UINT8(0x100 | sizeof(unsigned char)) (0x100 | sizeof(UINT8unsigned char)) | |||
321 | #define TYPE_INT32(0x200 | sizeof(int)) (0x200 | sizeof(INT32int)) | |||
322 | #define TYPE_FLOAT16(0x500 | sizeof(unsigned short)) (0x500 | sizeof(FLOAT16unsigned short)) | |||
323 | #define TYPE_FLOAT32(0x300 | sizeof(float)) (0x300 | sizeof(FLOAT32float)) | |||
324 | #define TYPE_DOUBLE(0x400 | sizeof(double)) (0x400 | sizeof(double)) | |||
325 | ||||
326 | static void * | |||
327 | getlist(PyObject *arg, Py_ssize_t *length, const char *wrong_length, int type) { | |||
328 | /* - allocates and returns a c array of the items in the | |||
329 | python sequence arg. | |||
330 | - the size of the returned array is in length | |||
331 | - all of the arg items must be numeric items of the type | |||
332 | specified in type | |||
333 | - sequence length is checked against the length parameter IF | |||
334 | an error parameter is passed in wrong_length | |||
335 | - caller is responsible for freeing the memory | |||
336 | */ | |||
337 | ||||
338 | Py_ssize_t i, n; | |||
339 | int itemp; | |||
340 | double dtemp; | |||
341 | FLOAT32float ftemp; | |||
342 | UINT8unsigned char *list; | |||
343 | PyObject *seq; | |||
344 | PyObject *op; | |||
345 | ||||
346 | if (!PySequence_Check(arg)) { | |||
347 | PyErr_SetString(PyExc_TypeError, must_be_sequence); | |||
348 | return NULL((void*)0); | |||
349 | } | |||
350 | ||||
351 | n = PySequence_Size(arg); | |||
352 | if (length && wrong_length && n != *length) { | |||
353 | PyErr_SetString(PyExc_ValueError, wrong_length); | |||
354 | return NULL((void*)0); | |||
355 | } | |||
356 | ||||
357 | /* malloc check ok, type & ff is just a sizeof(something) | |||
358 | calloc checks for overflow */ | |||
359 | list = calloc(n, type & 0xff); | |||
360 | if (!list) { | |||
361 | return ImagingError_MemoryError(); | |||
362 | } | |||
363 | ||||
364 | seq = PySequence_Fast(arg, must_be_sequence); | |||
365 | if (!seq) { | |||
366 | free(list); | |||
367 | return NULL((void*)0); | |||
368 | } | |||
369 | ||||
370 | for (i = 0; i < n; i++) { | |||
371 | op = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); | |||
372 | // DRY, branch prediction is going to work _really_ well | |||
373 | // on this switch. And 3 fewer loops to copy/paste. | |||
374 | switch (type) { | |||
375 | case TYPE_UINT8(0x100 | sizeof(unsigned char)): | |||
376 | itemp = PyLong_AsLong(op); | |||
377 | list[i] = CLIP8(itemp)((itemp) <= 0 ? 0 : (itemp) < 256 ? (itemp) : 255); | |||
378 | break; | |||
379 | case TYPE_INT32(0x200 | sizeof(int)): | |||
380 | itemp = PyLong_AsLong(op); | |||
381 | memcpy(list + i * sizeof(INT32int), &itemp, sizeof(itemp)); | |||
382 | break; | |||
383 | case TYPE_FLOAT32(0x300 | sizeof(float)): | |||
384 | ftemp = (FLOAT32float)PyFloat_AsDouble(op); | |||
385 | memcpy(list + i * sizeof(ftemp), &ftemp, sizeof(ftemp)); | |||
386 | break; | |||
387 | case TYPE_DOUBLE(0x400 | sizeof(double)): | |||
388 | dtemp = PyFloat_AsDouble(op); | |||
389 | memcpy(list + i * sizeof(dtemp), &dtemp, sizeof(dtemp)); | |||
390 | break; | |||
391 | } | |||
392 | } | |||
393 | ||||
394 | Py_DECREF(seq)_Py_DECREF(((PyObject*)(seq))); | |||
395 | ||||
396 | if (PyErr_Occurred()) { | |||
397 | free(list); | |||
398 | return NULL((void*)0); | |||
399 | } | |||
400 | ||||
401 | if (length) { | |||
402 | *length = n; | |||
403 | } | |||
404 | ||||
405 | return list; | |||
406 | } | |||
407 | ||||
408 | FLOAT32float | |||
409 | float16tofloat32(const FLOAT16unsigned short in) { | |||
410 | UINT32unsigned int t1; | |||
411 | UINT32unsigned int t2; | |||
412 | UINT32unsigned int t3; | |||
413 | FLOAT32float out[1] = {0}; | |||
414 | ||||
415 | t1 = in & 0x7fff; // Non-sign bits | |||
416 | t2 = in & 0x8000; // Sign bit | |||
417 | t3 = in & 0x7c00; // Exponent | |||
418 | ||||
419 | t1 <<= 13; // Align mantissa on MSB | |||
420 | t2 <<= 16; // Shift sign bit into position | |||
421 | ||||
422 | t1 += 0x38000000; // Adjust bias | |||
423 | ||||
424 | t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero | |||
425 | ||||
426 | t1 |= t2; // Re-insert sign bit | |||
427 | ||||
428 | memcpy(out, &t1, 4); | |||
429 | return out[0]; | |||
430 | } | |||
431 | ||||
432 | static inline PyObject * | |||
433 | getpixel(Imaging im, ImagingAccess access, int x, int y) { | |||
434 | union { | |||
435 | UINT8unsigned char b[4]; | |||
436 | UINT16unsigned short h; | |||
437 | INT32int i; | |||
438 | FLOAT32float f; | |||
439 | } pixel; | |||
440 | ||||
441 | if (x < 0) { | |||
442 | x = im->xsize + x; | |||
443 | } | |||
444 | if (y < 0) { | |||
445 | y = im->ysize + y; | |||
446 | } | |||
447 | ||||
448 | if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { | |||
449 | PyErr_SetString(PyExc_IndexError, outside_image); | |||
450 | return NULL((void*)0); | |||
451 | } | |||
452 | ||||
453 | access->get_pixel(im, x, y, &pixel); | |||
454 | ||||
455 | switch (im->type) { | |||
456 | case IMAGING_TYPE_UINT80: | |||
457 | switch (im->bands) { | |||
458 | case 1: | |||
459 | return PyLong_FromLong(pixel.b[0]); | |||
460 | case 2: | |||
461 | return Py_BuildValue_Py_BuildValue_SizeT("BB", pixel.b[0], pixel.b[1]); | |||
462 | case 3: | |||
463 | return Py_BuildValue_Py_BuildValue_SizeT("BBB", pixel.b[0], pixel.b[1], pixel.b[2]); | |||
464 | case 4: | |||
465 | return Py_BuildValue_Py_BuildValue_SizeT( | |||
466 | "BBBB", pixel.b[0], pixel.b[1], pixel.b[2], pixel.b[3]); | |||
467 | } | |||
468 | break; | |||
469 | case IMAGING_TYPE_INT321: | |||
470 | return PyLong_FromLong(pixel.i); | |||
471 | case IMAGING_TYPE_FLOAT322: | |||
472 | return PyFloat_FromDouble(pixel.f); | |||
473 | case IMAGING_TYPE_SPECIAL3: | |||
474 | if (strncmp(im->mode, "I;16", 4) == 0) { | |||
475 | return PyLong_FromLong(pixel.h); | |||
476 | } | |||
477 | break; | |||
478 | } | |||
479 | ||||
480 | /* unknown type */ | |||
481 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
482 | return Py_None(&_Py_NoneStruct); | |||
483 | } | |||
484 | ||||
485 | static char * | |||
486 | getink(PyObject *color, Imaging im, char *ink) { | |||
487 | int g = 0, b = 0, a = 0; | |||
488 | double f = 0; | |||
489 | /* Windows 64 bit longs are 32 bits, and 0xFFFFFFFF (white) is a | |||
490 | python long (not int) that raises an overflow error when trying | |||
491 | to return it into a 32 bit C long | |||
492 | */ | |||
493 | PY_LONG_LONGlong long r = 0; | |||
494 | FLOAT32float ftmp; | |||
495 | INT32int itmp; | |||
496 | ||||
497 | /* fill ink buffer (four bytes) with something that can | |||
498 | be cast to either UINT8 or INT32 */ | |||
499 | ||||
500 | int rIsInt = 0; | |||
501 | if (PyTuple_Check(color)((((((PyObject*)(color))->ob_type))->tp_flags & ((1UL << 26))) != 0) && PyTuple_GET_SIZE(color)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(color))))-> ob_size) == 1) { | |||
502 | color = PyTuple_GetItem(color, 0); | |||
503 | } | |||
504 | if (im->type == IMAGING_TYPE_UINT80 || im->type == IMAGING_TYPE_INT321 || | |||
505 | im->type == IMAGING_TYPE_SPECIAL3) { | |||
506 | if (PyLong_Check(color)((((((PyObject*)(color))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
507 | r = PyLong_AsLongLong(color); | |||
508 | if (r == -1 && PyErr_Occurred()) { | |||
509 | return NULL((void*)0); | |||
510 | } | |||
511 | rIsInt = 1; | |||
512 | } else if (im->type == IMAGING_TYPE_UINT80) { | |||
513 | if (!PyTuple_Check(color)((((((PyObject*)(color))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
514 | PyErr_SetString(PyExc_TypeError, "color must be int or tuple"); | |||
515 | return NULL((void*)0); | |||
516 | } | |||
517 | } else { | |||
518 | PyErr_SetString( | |||
519 | PyExc_TypeError, "color must be int or single-element tuple"); | |||
520 | return NULL((void*)0); | |||
521 | } | |||
522 | } | |||
523 | ||||
524 | switch (im->type) { | |||
525 | case IMAGING_TYPE_UINT80: | |||
526 | /* unsigned integer */ | |||
527 | if (im->bands == 1) { | |||
528 | /* unsigned integer, single layer */ | |||
529 | if (rIsInt != 1) { | |||
530 | if (PyTuple_GET_SIZE(color)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(color))))-> ob_size) != 1) { | |||
531 | PyErr_SetString(PyExc_TypeError, "color must be int or single-element tuple"); | |||
532 | return NULL((void*)0); | |||
533 | } else if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(color, "L", &r)) { | |||
534 | return NULL((void*)0); | |||
535 | } | |||
536 | } | |||
537 | ink[0] = (char)CLIP8(r)((r) <= 0 ? 0 : (r) < 256 ? (r) : 255); | |||
538 | ink[1] = ink[2] = ink[3] = 0; | |||
539 | } else { | |||
540 | a = 255; | |||
541 | if (rIsInt) { | |||
542 | /* compatibility: ABGR */ | |||
543 | a = (UINT8unsigned char)(r >> 24); | |||
544 | b = (UINT8unsigned char)(r >> 16); | |||
545 | g = (UINT8unsigned char)(r >> 8); | |||
546 | r = (UINT8unsigned char)r; | |||
547 | } else { | |||
548 | int tupleSize = PyTuple_GET_SIZE(color)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(color))))-> ob_size); | |||
549 | if (im->bands == 2) { | |||
550 | if (tupleSize != 1 && tupleSize != 2) { | |||
551 | PyErr_SetString(PyExc_TypeError, "color must be int, or tuple of one or two elements"); | |||
552 | return NULL((void*)0); | |||
553 | } else if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(color, "L|i", &r, &a)) { | |||
554 | return NULL((void*)0); | |||
555 | } | |||
556 | g = b = r; | |||
557 | } else { | |||
558 | if (tupleSize != 3 && tupleSize != 4) { | |||
559 | PyErr_SetString(PyExc_TypeError, "color must be int, or tuple of one, three or four elements"); | |||
560 | return NULL((void*)0); | |||
561 | } else if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(color, "Lii|i", &r, &g, &b, &a)) { | |||
562 | return NULL((void*)0); | |||
563 | } | |||
564 | } | |||
565 | } | |||
566 | ink[0] = (char)CLIP8(r)((r) <= 0 ? 0 : (r) < 256 ? (r) : 255); | |||
567 | ink[1] = (char)CLIP8(g)((g) <= 0 ? 0 : (g) < 256 ? (g) : 255); | |||
568 | ink[2] = (char)CLIP8(b)((b) <= 0 ? 0 : (b) < 256 ? (b) : 255); | |||
569 | ink[3] = (char)CLIP8(a)((a) <= 0 ? 0 : (a) < 256 ? (a) : 255); | |||
570 | } | |||
571 | return ink; | |||
572 | case IMAGING_TYPE_INT321: | |||
573 | /* signed integer */ | |||
574 | itmp = r; | |||
575 | memcpy(ink, &itmp, sizeof(itmp)); | |||
576 | return ink; | |||
577 | case IMAGING_TYPE_FLOAT322: | |||
578 | /* floating point */ | |||
579 | f = PyFloat_AsDouble(color); | |||
580 | if (f == -1.0 && PyErr_Occurred()) { | |||
581 | return NULL((void*)0); | |||
582 | } | |||
583 | ftmp = f; | |||
584 | memcpy(ink, &ftmp, sizeof(ftmp)); | |||
585 | return ink; | |||
586 | case IMAGING_TYPE_SPECIAL3: | |||
587 | if (strncmp(im->mode, "I;16", 4) == 0) { | |||
588 | ink[0] = (UINT8unsigned char)r; | |||
589 | ink[1] = (UINT8unsigned char)(r >> 8); | |||
590 | ink[2] = ink[3] = 0; | |||
591 | return ink; | |||
592 | } | |||
593 | } | |||
594 | ||||
595 | PyErr_SetString(PyExc_ValueError, wrong_mode); | |||
596 | return NULL((void*)0); | |||
597 | } | |||
598 | ||||
599 | /* -------------------------------------------------------------------- */ | |||
600 | /* FACTORIES */ | |||
601 | /* -------------------------------------------------------------------- */ | |||
602 | ||||
603 | static PyObject * | |||
604 | _fill(PyObject *self, PyObject *args) { | |||
605 | char *mode; | |||
606 | int xsize, ysize; | |||
607 | PyObject *color; | |||
608 | char buffer[4]; | |||
609 | Imaging im; | |||
610 | ||||
611 | xsize = ysize = 256; | |||
612 | color = NULL((void*)0); | |||
613 | ||||
614 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s|(ii)O", &mode, &xsize, &ysize, &color)) { | |||
615 | return NULL((void*)0); | |||
616 | } | |||
617 | ||||
618 | im = ImagingNewDirty(mode, xsize, ysize); | |||
619 | if (!im) { | |||
620 | return NULL((void*)0); | |||
621 | } | |||
622 | ||||
623 | buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0; | |||
624 | if (color) { | |||
625 | if (!getink(color, im, buffer)) { | |||
626 | ImagingDelete(im); | |||
627 | return NULL((void*)0); | |||
628 | } | |||
629 | } | |||
630 | ||||
631 | (void)ImagingFill(im, buffer); | |||
632 | ||||
633 | return PyImagingNew(im); | |||
634 | } | |||
635 | ||||
636 | static PyObject * | |||
637 | _new(PyObject *self, PyObject *args) { | |||
638 | char *mode; | |||
639 | int xsize, ysize; | |||
640 | ||||
641 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s(ii)", &mode, &xsize, &ysize)) { | |||
642 | return NULL((void*)0); | |||
643 | } | |||
644 | ||||
645 | return PyImagingNew(ImagingNew(mode, xsize, ysize)); | |||
646 | } | |||
647 | ||||
648 | static PyObject * | |||
649 | _new_block(PyObject *self, PyObject *args) { | |||
650 | char *mode; | |||
651 | int xsize, ysize; | |||
652 | ||||
653 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s(ii)", &mode, &xsize, &ysize)) { | |||
654 | return NULL((void*)0); | |||
655 | } | |||
656 | ||||
657 | return PyImagingNew(ImagingNewBlock(mode, xsize, ysize)); | |||
658 | } | |||
659 | ||||
660 | static PyObject * | |||
661 | _linear_gradient(PyObject *self, PyObject *args) { | |||
662 | char *mode; | |||
663 | ||||
664 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s", &mode)) { | |||
665 | return NULL((void*)0); | |||
666 | } | |||
667 | ||||
668 | return PyImagingNew(ImagingFillLinearGradient(mode)); | |||
669 | } | |||
670 | ||||
671 | static PyObject * | |||
672 | _radial_gradient(PyObject *self, PyObject *args) { | |||
673 | char *mode; | |||
674 | ||||
675 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s", &mode)) { | |||
676 | return NULL((void*)0); | |||
677 | } | |||
678 | ||||
679 | return PyImagingNew(ImagingFillRadialGradient(mode)); | |||
680 | } | |||
681 | ||||
682 | static PyObject * | |||
683 | _alpha_composite(ImagingObject *self, PyObject *args) { | |||
684 | ImagingObject *imagep1; | |||
685 | ImagingObject *imagep2; | |||
686 | ||||
687 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
688 | args, "O!O!", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2)) { | |||
689 | return NULL((void*)0); | |||
690 | } | |||
691 | ||||
692 | return PyImagingNew(ImagingAlphaComposite(imagep1->image, imagep2->image)); | |||
693 | } | |||
694 | ||||
695 | static PyObject * | |||
696 | _blend(ImagingObject *self, PyObject *args) { | |||
697 | ImagingObject *imagep1; | |||
698 | ImagingObject *imagep2; | |||
699 | double alpha; | |||
700 | ||||
701 | alpha = 0.5; | |||
702 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
703 | args, "O!O!|d", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2, &alpha)) { | |||
704 | return NULL((void*)0); | |||
705 | } | |||
706 | ||||
707 | return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image, (float)alpha)); | |||
708 | } | |||
709 | ||||
710 | /* -------------------------------------------------------------------- */ | |||
711 | /* METHODS */ | |||
712 | /* -------------------------------------------------------------------- */ | |||
713 | ||||
714 | static INT16short * | |||
715 | _prepare_lut_table(PyObject *table, Py_ssize_t table_size) { | |||
716 | int i; | |||
717 | Py_buffer buffer_info; | |||
718 | INT32int data_type = TYPE_FLOAT32(0x300 | sizeof(float)); | |||
719 | float item = 0; | |||
720 | void *table_data = NULL((void*)0); | |||
721 | int free_table_data = 0; | |||
722 | INT16short *prepared; | |||
723 | ||||
724 | /* NOTE: This value should be the same as in ColorLUT.c */ | |||
725 | #define PRECISION_BITS (16 - 8 - 2) | |||
726 | ||||
727 | const char *wrong_size = | |||
728 | ("The table should have table_channels * " | |||
729 | "size1D * size2D * size3D float items."); | |||
730 | ||||
731 | if (PyObject_CheckBuffer(table)(((table)->ob_type->tp_as_buffer != ((void*)0)) && ((table)->ob_type->tp_as_buffer->bf_getbuffer != (( void*)0)))) { | |||
732 | if (!PyObject_GetBuffer(table, &buffer_info, PyBUF_CONTIG_RO(0x0008) | PyBUF_FORMAT0x0004)) { | |||
733 | if (buffer_info.ndim == 1 && buffer_info.shape[0] == table_size) { | |||
734 | if (strlen(buffer_info.format) == 1) { | |||
735 | switch (buffer_info.format[0]) { | |||
736 | case 'e': | |||
737 | data_type = TYPE_FLOAT16(0x500 | sizeof(unsigned short)); | |||
738 | table_data = buffer_info.buf; | |||
739 | break; | |||
740 | case 'f': | |||
741 | data_type = TYPE_FLOAT32(0x300 | sizeof(float)); | |||
742 | table_data = buffer_info.buf; | |||
743 | break; | |||
744 | case 'd': | |||
745 | data_type = TYPE_DOUBLE(0x400 | sizeof(double)); | |||
746 | table_data = buffer_info.buf; | |||
747 | break; | |||
748 | } | |||
749 | } | |||
750 | } | |||
751 | PyBuffer_Release(&buffer_info); | |||
752 | } | |||
753 | } | |||
754 | ||||
755 | if (!table_data) { | |||
756 | free_table_data = 1; | |||
757 | table_data = getlist(table, &table_size, wrong_size, TYPE_FLOAT32(0x300 | sizeof(float))); | |||
758 | if (!table_data) { | |||
759 | return NULL((void*)0); | |||
760 | } | |||
761 | } | |||
762 | ||||
763 | /* malloc check ok, max is 2 * 4 * 65**3 = 2197000 */ | |||
764 | prepared = (INT16short *)malloc(sizeof(INT16short) * table_size); | |||
765 | if (!prepared) { | |||
766 | if (free_table_data) { | |||
767 | free(table_data); | |||
768 | } | |||
769 | return (INT16short *)ImagingError_MemoryError(); | |||
770 | } | |||
771 | ||||
772 | for (i = 0; i < table_size; i++) { | |||
773 | FLOAT16unsigned short htmp; | |||
774 | double dtmp; | |||
775 | switch (data_type) { | |||
776 | case TYPE_FLOAT16(0x500 | sizeof(unsigned short)): | |||
777 | memcpy(&htmp, ((char *)table_data) + i * sizeof(htmp), sizeof(htmp)); | |||
778 | item = float16tofloat32(htmp); | |||
779 | break; | |||
780 | case TYPE_FLOAT32(0x300 | sizeof(float)): | |||
781 | memcpy( | |||
782 | &item, ((char *)table_data) + i * sizeof(FLOAT32float), sizeof(FLOAT32float)); | |||
783 | break; | |||
784 | case TYPE_DOUBLE(0x400 | sizeof(double)): | |||
785 | memcpy(&dtmp, ((char *)table_data) + i * sizeof(dtmp), sizeof(dtmp)); | |||
786 | item = (FLOAT32float)dtmp; | |||
787 | break; | |||
788 | } | |||
789 | /* Max value for INT16 */ | |||
790 | if (item >= (0x7fff - 0.5) / (255 << PRECISION_BITS)) { | |||
791 | prepared[i] = 0x7fff; | |||
792 | continue; | |||
793 | } | |||
794 | /* Min value for INT16 */ | |||
795 | if (item <= (-0x8000 + 0.5) / (255 << PRECISION_BITS)) { | |||
796 | prepared[i] = -0x8000; | |||
797 | continue; | |||
798 | } | |||
799 | if (item < 0) { | |||
800 | prepared[i] = item * (255 << PRECISION_BITS) - 0.5; | |||
801 | } else { | |||
802 | prepared[i] = item * (255 << PRECISION_BITS) + 0.5; | |||
803 | } | |||
804 | } | |||
805 | ||||
806 | #undef PRECISION_BITS | |||
807 | if (free_table_data) { | |||
808 | free(table_data); | |||
809 | } | |||
810 | return prepared; | |||
811 | } | |||
812 | ||||
813 | static PyObject * | |||
814 | _color_lut_3d(ImagingObject *self, PyObject *args) { | |||
815 | char *mode; | |||
816 | int filter; | |||
817 | int table_channels; | |||
818 | int size1D, size2D, size3D; | |||
819 | PyObject *table; | |||
820 | ||||
821 | INT16short *prepared_table; | |||
822 | Imaging imOut; | |||
823 | ||||
824 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
825 | args, | |||
826 | "siiiiiO:color_lut_3d", | |||
827 | &mode, | |||
828 | &filter, | |||
829 | &table_channels, | |||
830 | &size1D, | |||
831 | &size2D, | |||
832 | &size3D, | |||
833 | &table)) { | |||
834 | return NULL((void*)0); | |||
835 | } | |||
836 | ||||
837 | /* actually, it is trilinear */ | |||
838 | if (filter != IMAGING_TRANSFORM_BILINEAR2) { | |||
839 | PyErr_SetString(PyExc_ValueError, "Only LINEAR filter is supported."); | |||
840 | return NULL((void*)0); | |||
841 | } | |||
842 | ||||
843 | if (1 > table_channels || table_channels > 4) { | |||
844 | PyErr_SetString(PyExc_ValueError, "table_channels should be from 1 to 4"); | |||
845 | return NULL((void*)0); | |||
846 | } | |||
847 | ||||
848 | if (2 > size1D || size1D > 65 || 2 > size2D || size2D > 65 || 2 > size3D || | |||
849 | size3D > 65) { | |||
850 | PyErr_SetString( | |||
851 | PyExc_ValueError, "Table size in any dimension should be from 2 to 65"); | |||
852 | return NULL((void*)0); | |||
853 | } | |||
854 | ||||
855 | prepared_table = | |||
856 | _prepare_lut_table(table, table_channels * size1D * size2D * size3D); | |||
857 | if (!prepared_table) { | |||
858 | return NULL((void*)0); | |||
859 | } | |||
860 | ||||
861 | imOut = ImagingNewDirty(mode, self->image->xsize, self->image->ysize); | |||
862 | if (!imOut) { | |||
863 | free(prepared_table); | |||
864 | return NULL((void*)0); | |||
865 | } | |||
866 | ||||
867 | if (!ImagingColorLUT3D_linear( | |||
868 | imOut, | |||
869 | self->image, | |||
870 | table_channels, | |||
871 | size1D, | |||
872 | size2D, | |||
873 | size3D, | |||
874 | prepared_table)) { | |||
875 | free(prepared_table); | |||
876 | ImagingDelete(imOut); | |||
877 | return NULL((void*)0); | |||
878 | } | |||
879 | ||||
880 | free(prepared_table); | |||
881 | ||||
882 | return PyImagingNew(imOut); | |||
883 | } | |||
884 | ||||
885 | static PyObject * | |||
886 | _convert(ImagingObject *self, PyObject *args) { | |||
887 | char *mode; | |||
888 | int dither = 0; | |||
889 | ImagingObject *paletteimage = NULL((void*)0); | |||
890 | ||||
891 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s|iO", &mode, &dither, &paletteimage)) { | |||
892 | return NULL((void*)0); | |||
893 | } | |||
894 | if (paletteimage != NULL((void*)0)) { | |||
895 | if (!PyImaging_Check(paletteimage)((((PyObject*)(paletteimage))->ob_type) == &Imaging_Type )) { | |||
896 | PyObject_Print((PyObject *)paletteimage, stderrstderr, 0); | |||
897 | PyErr_SetString( | |||
898 | PyExc_ValueError, "palette argument must be image with mode 'P'"); | |||
899 | return NULL((void*)0); | |||
900 | } | |||
901 | if (paletteimage->image->palette == NULL((void*)0)) { | |||
902 | PyErr_SetString(PyExc_ValueError, "null palette"); | |||
903 | return NULL((void*)0); | |||
904 | } | |||
905 | } | |||
906 | ||||
907 | return PyImagingNew(ImagingConvert( | |||
908 | self->image, mode, paletteimage ? paletteimage->image->palette : NULL((void*)0), dither)); | |||
909 | } | |||
910 | ||||
911 | static PyObject * | |||
912 | _convert2(ImagingObject *self, PyObject *args) { | |||
913 | ImagingObject *imagep1; | |||
914 | ImagingObject *imagep2; | |||
915 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
916 | args, "O!O!", &Imaging_Type, &imagep1, &Imaging_Type, &imagep2)) { | |||
917 | return NULL((void*)0); | |||
918 | } | |||
919 | ||||
920 | if (!ImagingConvert2(imagep1->image, imagep2->image)) { | |||
921 | return NULL((void*)0); | |||
922 | } | |||
923 | ||||
924 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
925 | return Py_None(&_Py_NoneStruct); | |||
926 | } | |||
927 | ||||
928 | static PyObject * | |||
929 | _convert_matrix(ImagingObject *self, PyObject *args) { | |||
930 | char *mode; | |||
931 | float m[12]; | |||
932 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s(ffff)", &mode, m + 0, m + 1, m + 2, m + 3)) { | |||
933 | PyErr_Clear(); | |||
934 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
935 | args, | |||
936 | "s(ffffffffffff)", | |||
937 | &mode, | |||
938 | m + 0, | |||
939 | m + 1, | |||
940 | m + 2, | |||
941 | m + 3, | |||
942 | m + 4, | |||
943 | m + 5, | |||
944 | m + 6, | |||
945 | m + 7, | |||
946 | m + 8, | |||
947 | m + 9, | |||
948 | m + 10, | |||
949 | m + 11)) { | |||
950 | return NULL((void*)0); | |||
951 | } | |||
952 | } | |||
953 | ||||
954 | return PyImagingNew(ImagingConvertMatrix(self->image, mode, m)); | |||
955 | } | |||
956 | ||||
957 | static PyObject * | |||
958 | _convert_transparent(ImagingObject *self, PyObject *args) { | |||
959 | char *mode; | |||
960 | int r, g, b; | |||
961 | if (PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s(iii)", &mode, &r, &g, &b)) { | |||
962 | return PyImagingNew(ImagingConvertTransparent(self->image, mode, r, g, b)); | |||
963 | } | |||
964 | PyErr_Clear(); | |||
965 | if (PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "si", &mode, &r)) { | |||
966 | return PyImagingNew(ImagingConvertTransparent(self->image, mode, r, 0, 0)); | |||
967 | } | |||
968 | return NULL((void*)0); | |||
969 | } | |||
970 | ||||
971 | static PyObject * | |||
972 | _copy(ImagingObject *self, PyObject *args) { | |||
973 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "")) { | |||
974 | return NULL((void*)0); | |||
975 | } | |||
976 | ||||
977 | return PyImagingNew(ImagingCopy(self->image)); | |||
978 | } | |||
979 | ||||
980 | static PyObject * | |||
981 | _crop(ImagingObject *self, PyObject *args) { | |||
982 | int x0, y0, x1, y1; | |||
983 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(iiii)", &x0, &y0, &x1, &y1)) { | |||
984 | return NULL((void*)0); | |||
985 | } | |||
986 | ||||
987 | return PyImagingNew(ImagingCrop(self->image, x0, y0, x1, y1)); | |||
988 | } | |||
989 | ||||
990 | static PyObject * | |||
991 | _expand_image(ImagingObject *self, PyObject *args) { | |||
992 | int x, y; | |||
993 | int mode = 0; | |||
994 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "ii|i", &x, &y, &mode)) { | |||
995 | return NULL((void*)0); | |||
996 | } | |||
997 | ||||
998 | return PyImagingNew(ImagingExpand(self->image, x, y, mode)); | |||
999 | } | |||
1000 | ||||
1001 | static PyObject * | |||
1002 | _filter(ImagingObject *self, PyObject *args) { | |||
1003 | PyObject *imOut; | |||
1004 | Py_ssize_t kernelsize; | |||
1005 | FLOAT32float *kerneldata; | |||
1006 | ||||
1007 | int xsize, ysize, i; | |||
1008 | float divisor, offset; | |||
1009 | PyObject *kernel = NULL((void*)0); | |||
1010 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
1011 | args, "(ii)ffO", &xsize, &ysize, &divisor, &offset, &kernel)) { | |||
1012 | return NULL((void*)0); | |||
1013 | } | |||
1014 | ||||
1015 | /* get user-defined kernel */ | |||
1016 | kerneldata = getlist(kernel, &kernelsize, NULL((void*)0), TYPE_FLOAT32(0x300 | sizeof(float))); | |||
1017 | if (!kerneldata) { | |||
1018 | return NULL((void*)0); | |||
1019 | } | |||
1020 | if (kernelsize != (Py_ssize_t)xsize * (Py_ssize_t)ysize) { | |||
1021 | free(kerneldata); | |||
1022 | return ImagingError_ValueError("bad kernel size"); | |||
1023 | } | |||
1024 | ||||
1025 | for (i = 0; i < kernelsize; ++i) { | |||
1026 | kerneldata[i] /= divisor; | |||
1027 | } | |||
1028 | ||||
1029 | imOut = PyImagingNew(ImagingFilter(self->image, xsize, ysize, kerneldata, offset)); | |||
1030 | ||||
1031 | free(kerneldata); | |||
1032 | ||||
1033 | return imOut; | |||
1034 | } | |||
1035 | ||||
1036 | #ifdef WITH_UNSHARPMASK | |||
1037 | static PyObject * | |||
1038 | _gaussian_blur(ImagingObject *self, PyObject *args) { | |||
1039 | Imaging imIn; | |||
1040 | Imaging imOut; | |||
1041 | ||||
1042 | float radius = 0; | |||
1043 | int passes = 3; | |||
1044 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "f|i", &radius, &passes)) { | |||
1045 | return NULL((void*)0); | |||
1046 | } | |||
1047 | ||||
1048 | imIn = self->image; | |||
1049 | imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize); | |||
1050 | if (!imOut) { | |||
1051 | return NULL((void*)0); | |||
1052 | } | |||
1053 | ||||
1054 | if (!ImagingGaussianBlur(imOut, imIn, radius, passes)) { | |||
1055 | ImagingDelete(imOut); | |||
1056 | return NULL((void*)0); | |||
1057 | } | |||
1058 | ||||
1059 | return PyImagingNew(imOut); | |||
1060 | } | |||
1061 | #endif | |||
1062 | ||||
1063 | static PyObject * | |||
1064 | _getpalette(ImagingObject *self, PyObject *args) { | |||
1065 | PyObject *palette; | |||
1066 | int palettesize = 256; | |||
1067 | int bits; | |||
1068 | ImagingShuffler pack; | |||
1069 | ||||
1070 | char *mode = "RGB"; | |||
1071 | char *rawmode = "RGB"; | |||
1072 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|ss", &mode, &rawmode)) { | |||
1073 | return NULL((void*)0); | |||
1074 | } | |||
1075 | ||||
1076 | if (!self->image->palette) { | |||
1077 | PyErr_SetString(PyExc_ValueError, no_palette); | |||
1078 | return NULL((void*)0); | |||
1079 | } | |||
1080 | ||||
1081 | pack = ImagingFindPacker(mode, rawmode, &bits); | |||
1082 | if (!pack) { | |||
1083 | PyErr_SetString(PyExc_ValueError, wrong_raw_mode); | |||
1084 | return NULL((void*)0); | |||
1085 | } | |||
1086 | ||||
1087 | palette = PyBytes_FromStringAndSize(NULL((void*)0), palettesize * bits / 8); | |||
1088 | if (!palette) { | |||
1089 | return NULL((void*)0); | |||
1090 | } | |||
1091 | ||||
1092 | pack( | |||
1093 | (UINT8unsigned char *)PyBytes_AsString(palette), self->image->palette->palette, palettesize); | |||
1094 | ||||
1095 | return palette; | |||
1096 | } | |||
1097 | ||||
1098 | static PyObject * | |||
1099 | _getpalettemode(ImagingObject *self) { | |||
1100 | if (!self->image->palette) { | |||
1101 | PyErr_SetString(PyExc_ValueError, no_palette); | |||
1102 | return NULL((void*)0); | |||
1103 | } | |||
1104 | ||||
1105 | return PyUnicode_FromString(self->image->palette->mode); | |||
1106 | } | |||
1107 | ||||
1108 | static inline int | |||
1109 | _getxy(PyObject *xy, int *x, int *y) { | |||
1110 | PyObject *value; | |||
1111 | ||||
1112 | if (!PyTuple_Check(xy)((((((PyObject*)(xy))->ob_type))->tp_flags & ((1UL << 26))) != 0) || PyTuple_GET_SIZE(xy)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(xy))))-> ob_size) != 2) { | |||
1113 | goto badarg; | |||
1114 | } | |||
1115 | ||||
1116 | value = PyTuple_GET_ITEM(xy, 0)((((void) (0)), (PyTupleObject *)(xy))->ob_item[0]); | |||
1117 | if (PyLong_Check(value)((((((PyObject*)(value))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
1118 | *x = PyLong_AS_LONG(value)PyLong_AsLong(value); | |||
1119 | } else if (PyFloat_Check(value)((((PyObject*)(value))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype((((PyObject*)(value))->ob_type), (&PyFloat_Type )))) { | |||
1120 | *x = (int)PyFloat_AS_DOUBLE(value)(((PyFloatObject *)(value))->ob_fval); | |||
1121 | } else { | |||
1122 | PyObject *int_value = PyObject_CallMethod_PyObject_CallMethod_SizeT(value, "__int__", NULL((void*)0)); | |||
1123 | if (int_value != NULL((void*)0) && PyLong_Check(int_value)((((((PyObject*)(int_value))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
1124 | *x = PyLong_AS_LONG(int_value)PyLong_AsLong(int_value); | |||
1125 | } else { | |||
1126 | goto badval; | |||
1127 | } | |||
1128 | } | |||
1129 | ||||
1130 | value = PyTuple_GET_ITEM(xy, 1)((((void) (0)), (PyTupleObject *)(xy))->ob_item[1]); | |||
1131 | if (PyLong_Check(value)((((((PyObject*)(value))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
1132 | *y = PyLong_AS_LONG(value)PyLong_AsLong(value); | |||
1133 | } else if (PyFloat_Check(value)((((PyObject*)(value))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype((((PyObject*)(value))->ob_type), (&PyFloat_Type )))) { | |||
1134 | *y = (int)PyFloat_AS_DOUBLE(value)(((PyFloatObject *)(value))->ob_fval); | |||
1135 | } else { | |||
1136 | PyObject *int_value = PyObject_CallMethod_PyObject_CallMethod_SizeT(value, "__int__", NULL((void*)0)); | |||
1137 | if (int_value != NULL((void*)0) && PyLong_Check(int_value)((((((PyObject*)(int_value))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
1138 | *y = PyLong_AS_LONG(int_value)PyLong_AsLong(int_value); | |||
1139 | } else { | |||
1140 | goto badval; | |||
1141 | } | |||
1142 | } | |||
1143 | ||||
1144 | return 0; | |||
1145 | ||||
1146 | badarg: | |||
1147 | PyErr_SetString(PyExc_TypeError, "argument must be sequence of length 2"); | |||
1148 | return -1; | |||
1149 | ||||
1150 | badval: | |||
1151 | PyErr_SetString(PyExc_TypeError, "an integer is required"); | |||
1152 | return -1; | |||
1153 | } | |||
1154 | ||||
1155 | static PyObject * | |||
1156 | _getpixel(ImagingObject *self, PyObject *args) { | |||
1157 | PyObject *xy; | |||
1158 | int x, y; | |||
1159 | ||||
1160 | if (PyTuple_GET_SIZE(args)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(args))))-> ob_size) != 1) { | |||
1161 | PyErr_SetString(PyExc_TypeError, "argument 1 must be sequence of length 2"); | |||
1162 | return NULL((void*)0); | |||
1163 | } | |||
1164 | ||||
1165 | xy = PyTuple_GET_ITEM(args, 0)((((void) (0)), (PyTupleObject *)(args))->ob_item[0]); | |||
1166 | ||||
1167 | if (_getxy(xy, &x, &y)) { | |||
1168 | return NULL((void*)0); | |||
1169 | } | |||
1170 | ||||
1171 | if (self->access == NULL((void*)0)) { | |||
1172 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1173 | return Py_None(&_Py_NoneStruct); | |||
1174 | } | |||
1175 | ||||
1176 | return getpixel(self->image, self->access, x, y); | |||
1177 | } | |||
1178 | ||||
1179 | union hist_extrema { | |||
1180 | UINT8unsigned char u[2]; | |||
1181 | INT32int i[2]; | |||
1182 | FLOAT32float f[2]; | |||
1183 | }; | |||
1184 | ||||
1185 | static union hist_extrema * | |||
1186 | parse_histogram_extremap( | |||
1187 | ImagingObject *self, PyObject *extremap, union hist_extrema *ep) { | |||
1188 | int i0, i1; | |||
1189 | double f0, f1; | |||
1190 | ||||
1191 | if (extremap) { | |||
1192 | switch (self->image->type) { | |||
1193 | case IMAGING_TYPE_UINT80: | |||
1194 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(extremap, "ii", &i0, &i1)) { | |||
1195 | return NULL((void*)0); | |||
1196 | } | |||
1197 | ep->u[0] = CLIP8(i0)((i0) <= 0 ? 0 : (i0) < 256 ? (i0) : 255); | |||
1198 | ep->u[1] = CLIP8(i1)((i1) <= 0 ? 0 : (i1) < 256 ? (i1) : 255); | |||
1199 | break; | |||
1200 | case IMAGING_TYPE_INT321: | |||
1201 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(extremap, "ii", &i0, &i1)) { | |||
1202 | return NULL((void*)0); | |||
1203 | } | |||
1204 | ep->i[0] = i0; | |||
1205 | ep->i[1] = i1; | |||
1206 | break; | |||
1207 | case IMAGING_TYPE_FLOAT322: | |||
1208 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(extremap, "dd", &f0, &f1)) { | |||
1209 | return NULL((void*)0); | |||
1210 | } | |||
1211 | ep->f[0] = (FLOAT32float)f0; | |||
1212 | ep->f[1] = (FLOAT32float)f1; | |||
1213 | break; | |||
1214 | default: | |||
1215 | return NULL((void*)0); | |||
1216 | } | |||
1217 | } else { | |||
1218 | return NULL((void*)0); | |||
1219 | } | |||
1220 | return ep; | |||
1221 | } | |||
1222 | ||||
1223 | static PyObject * | |||
1224 | _histogram(ImagingObject *self, PyObject *args) { | |||
1225 | ImagingHistogram h; | |||
1226 | PyObject *list; | |||
1227 | int i; | |||
1228 | union hist_extrema extrema; | |||
1229 | union hist_extrema *ep; | |||
1230 | ||||
1231 | PyObject *extremap = NULL((void*)0); | |||
1232 | ImagingObject *maskp = NULL((void*)0); | |||
1233 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|OO!", &extremap, &Imaging_Type, &maskp)) { | |||
1234 | return NULL((void*)0); | |||
1235 | } | |||
1236 | ||||
1237 | /* Using a var to avoid allocations. */ | |||
1238 | ep = parse_histogram_extremap(self, extremap, &extrema); | |||
1239 | h = ImagingGetHistogram(self->image, (maskp) ? maskp->image : NULL((void*)0), ep); | |||
1240 | ||||
1241 | if (!h) { | |||
1242 | return NULL((void*)0); | |||
1243 | } | |||
1244 | ||||
1245 | /* Build an integer list containing the histogram */ | |||
1246 | list = PyList_New(h->bands * 256); | |||
1247 | for (i = 0; i < h->bands * 256; i++) { | |||
1248 | PyObject *item; | |||
1249 | item = PyLong_FromLong(h->histogram[i]); | |||
1250 | if (item == NULL((void*)0)) { | |||
1251 | Py_DECREF(list)_Py_DECREF(((PyObject*)(list))); | |||
1252 | list = NULL((void*)0); | |||
1253 | break; | |||
1254 | } | |||
1255 | PyList_SetItem(list, i, item); | |||
1256 | } | |||
1257 | ||||
1258 | /* Destroy the histogram structure */ | |||
1259 | ImagingHistogramDelete(h); | |||
1260 | ||||
1261 | return list; | |||
1262 | } | |||
1263 | ||||
1264 | static PyObject * | |||
1265 | _entropy(ImagingObject *self, PyObject *args) { | |||
1266 | ImagingHistogram h; | |||
1267 | int idx, length; | |||
1268 | long sum; | |||
1269 | double entropy, fsum, p; | |||
1270 | union hist_extrema extrema; | |||
1271 | union hist_extrema *ep; | |||
1272 | ||||
1273 | PyObject *extremap = NULL((void*)0); | |||
1274 | ImagingObject *maskp = NULL((void*)0); | |||
1275 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|OO!", &extremap, &Imaging_Type, &maskp)) { | |||
1276 | return NULL((void*)0); | |||
1277 | } | |||
1278 | ||||
1279 | /* Using a local var to avoid allocations. */ | |||
1280 | ep = parse_histogram_extremap(self, extremap, &extrema); | |||
1281 | h = ImagingGetHistogram(self->image, (maskp) ? maskp->image : NULL((void*)0), ep); | |||
1282 | ||||
1283 | if (!h) { | |||
1284 | return NULL((void*)0); | |||
1285 | } | |||
1286 | ||||
1287 | /* Calculate the histogram entropy */ | |||
1288 | /* First, sum the histogram data */ | |||
1289 | length = h->bands * 256; | |||
1290 | sum = 0; | |||
1291 | for (idx = 0; idx < length; idx++) { | |||
1292 | sum += h->histogram[idx]; | |||
1293 | } | |||
1294 | ||||
1295 | /* Next, normalize the histogram data, */ | |||
1296 | /* using the histogram sum value */ | |||
1297 | fsum = (double)sum; | |||
1298 | entropy = 0.0; | |||
1299 | for (idx = 0; idx < length; idx++) { | |||
1300 | p = (double)h->histogram[idx] / fsum; | |||
1301 | if (p != 0.0) { | |||
1302 | entropy += p * log(p) * M_LOG2E1.4426950408889634074; | |||
1303 | } | |||
1304 | } | |||
1305 | ||||
1306 | /* Destroy the histogram structure */ | |||
1307 | ImagingHistogramDelete(h); | |||
1308 | ||||
1309 | return PyFloat_FromDouble(-entropy); | |||
1310 | } | |||
1311 | ||||
1312 | #ifdef WITH_MODEFILTER | |||
1313 | static PyObject * | |||
1314 | _modefilter(ImagingObject *self, PyObject *args) { | |||
1315 | int size; | |||
1316 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i", &size)) { | |||
1317 | return NULL((void*)0); | |||
1318 | } | |||
1319 | ||||
1320 | return PyImagingNew(ImagingModeFilter(self->image, size)); | |||
1321 | } | |||
1322 | #endif | |||
1323 | ||||
1324 | static PyObject * | |||
1325 | _offset(ImagingObject *self, PyObject *args) { | |||
1326 | int xoffset, yoffset; | |||
1327 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "ii", &xoffset, &yoffset)) { | |||
1328 | return NULL((void*)0); | |||
1329 | } | |||
1330 | ||||
1331 | return PyImagingNew(ImagingOffset(self->image, xoffset, yoffset)); | |||
1332 | } | |||
1333 | ||||
1334 | static PyObject * | |||
1335 | _paste(ImagingObject *self, PyObject *args) { | |||
1336 | int status; | |||
1337 | char ink[4]; | |||
1338 | ||||
1339 | PyObject *source; | |||
1340 | int x0, y0, x1, y1; | |||
1341 | ImagingObject *maskp = NULL((void*)0); | |||
1342 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
1343 | args, "O(iiii)|O!", &source, &x0, &y0, &x1, &y1, &Imaging_Type, &maskp)) { | |||
1344 | return NULL((void*)0); | |||
1345 | } | |||
1346 | ||||
1347 | if (PyImaging_Check(source)((((PyObject*)(source))->ob_type) == &Imaging_Type)) { | |||
1348 | status = ImagingPaste( | |||
1349 | self->image, | |||
1350 | PyImaging_AsImaging(source), | |||
1351 | (maskp) ? maskp->image : NULL((void*)0), | |||
1352 | x0, | |||
1353 | y0, | |||
1354 | x1, | |||
1355 | y1); | |||
1356 | ||||
1357 | } else { | |||
1358 | if (!getink(source, self->image, ink)) { | |||
1359 | return NULL((void*)0); | |||
1360 | } | |||
1361 | status = ImagingFill2( | |||
1362 | self->image, ink, (maskp) ? maskp->image : NULL((void*)0), x0, y0, x1, y1); | |||
1363 | } | |||
1364 | ||||
1365 | if (status < 0) { | |||
1366 | return NULL((void*)0); | |||
1367 | } | |||
1368 | ||||
1369 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1370 | return Py_None(&_Py_NoneStruct); | |||
1371 | } | |||
1372 | ||||
1373 | static PyObject * | |||
1374 | _point(ImagingObject *self, PyObject *args) { | |||
1375 | static const char *wrong_number = "wrong number of lut entries"; | |||
1376 | ||||
1377 | Py_ssize_t n; | |||
1378 | int i, bands; | |||
1379 | Imaging im; | |||
1380 | ||||
1381 | PyObject *list; | |||
1382 | char *mode; | |||
1383 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oz", &list, &mode)) { | |||
1384 | return NULL((void*)0); | |||
1385 | } | |||
1386 | ||||
1387 | if (mode && !strcmp(mode, "F")) { | |||
1388 | FLOAT32float *data; | |||
1389 | ||||
1390 | /* map from 8-bit data to floating point */ | |||
1391 | n = 256; | |||
1392 | data = getlist(list, &n, wrong_number, TYPE_FLOAT32(0x300 | sizeof(float))); | |||
1393 | if (!data) { | |||
1394 | return NULL((void*)0); | |||
1395 | } | |||
1396 | im = ImagingPoint(self->image, mode, (void *)data); | |||
1397 | free(data); | |||
1398 | ||||
1399 | } else if (!strcmp(self->image->mode, "I") && mode && !strcmp(mode, "L")) { | |||
1400 | UINT8unsigned char *data; | |||
1401 | ||||
1402 | /* map from 16-bit subset of 32-bit data to 8-bit */ | |||
1403 | /* FIXME: support arbitrary number of entries (requires API change) */ | |||
1404 | n = 65536; | |||
1405 | data = getlist(list, &n, wrong_number, TYPE_UINT8(0x100 | sizeof(unsigned char))); | |||
1406 | if (!data) { | |||
1407 | return NULL((void*)0); | |||
1408 | } | |||
1409 | im = ImagingPoint(self->image, mode, (void *)data); | |||
1410 | free(data); | |||
1411 | ||||
1412 | } else { | |||
1413 | INT32int *data; | |||
1414 | UINT8unsigned char lut[1024]; | |||
1415 | ||||
1416 | if (mode) { | |||
1417 | bands = getbands(mode); | |||
1418 | if (bands < 0) { | |||
1419 | return NULL((void*)0); | |||
1420 | } | |||
1421 | } else { | |||
1422 | bands = self->image->bands; | |||
1423 | } | |||
1424 | ||||
1425 | /* map to integer data */ | |||
1426 | n = 256 * bands; | |||
1427 | data = getlist(list, &n, wrong_number, TYPE_INT32(0x200 | sizeof(int))); | |||
1428 | if (!data) { | |||
1429 | return NULL((void*)0); | |||
1430 | } | |||
1431 | ||||
1432 | if (mode && !strcmp(mode, "I")) { | |||
1433 | im = ImagingPoint(self->image, mode, (void *)data); | |||
1434 | } else if (mode && bands > 1) { | |||
1435 | for (i = 0; i < 256; i++) { | |||
1436 | lut[i * 4] = CLIP8(data[i])((data[i]) <= 0 ? 0 : (data[i]) < 256 ? (data[i]) : 255 ); | |||
1437 | lut[i * 4 + 1] = CLIP8(data[i + 256])((data[i + 256]) <= 0 ? 0 : (data[i + 256]) < 256 ? (data [i + 256]) : 255); | |||
1438 | lut[i * 4 + 2] = CLIP8(data[i + 512])((data[i + 512]) <= 0 ? 0 : (data[i + 512]) < 256 ? (data [i + 512]) : 255); | |||
1439 | if (n > 768) { | |||
1440 | lut[i * 4 + 3] = CLIP8(data[i + 768])((data[i + 768]) <= 0 ? 0 : (data[i + 768]) < 256 ? (data [i + 768]) : 255); | |||
1441 | } | |||
1442 | } | |||
1443 | im = ImagingPoint(self->image, mode, (void *)lut); | |||
1444 | } else { | |||
1445 | /* map individual bands */ | |||
1446 | for (i = 0; i < n; i++) { | |||
1447 | lut[i] = CLIP8(data[i])((data[i]) <= 0 ? 0 : (data[i]) < 256 ? (data[i]) : 255 ); | |||
1448 | } | |||
1449 | im = ImagingPoint(self->image, mode, (void *)lut); | |||
1450 | } | |||
1451 | free(data); | |||
1452 | } | |||
1453 | ||||
1454 | return PyImagingNew(im); | |||
1455 | } | |||
1456 | ||||
1457 | static PyObject * | |||
1458 | _point_transform(ImagingObject *self, PyObject *args) { | |||
1459 | double scale = 1.0; | |||
1460 | double offset = 0.0; | |||
1461 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|dd", &scale, &offset)) { | |||
1462 | return NULL((void*)0); | |||
1463 | } | |||
1464 | ||||
1465 | return PyImagingNew(ImagingPointTransform(self->image, scale, offset)); | |||
1466 | } | |||
1467 | ||||
1468 | static PyObject * | |||
1469 | _putdata(ImagingObject *self, PyObject *args) { | |||
1470 | Imaging image; | |||
1471 | // i & n are # pixels, require py_ssize_t. x can be as large as n. y, just because. | |||
1472 | Py_ssize_t n, i, x, y; | |||
1473 | ||||
1474 | PyObject *data; | |||
1475 | PyObject *seq = NULL((void*)0); | |||
1476 | PyObject *op; | |||
1477 | double scale = 1.0; | |||
1478 | double offset = 0.0; | |||
1479 | ||||
1480 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O|dd", &data, &scale, &offset)) { | |||
1481 | return NULL((void*)0); | |||
1482 | } | |||
1483 | ||||
1484 | if (!PySequence_Check(data)) { | |||
1485 | PyErr_SetString(PyExc_TypeError, must_be_sequence); | |||
1486 | return NULL((void*)0); | |||
1487 | } | |||
1488 | ||||
1489 | image = self->image; | |||
1490 | ||||
1491 | n = PyObject_LengthPyObject_Size(data); | |||
1492 | if (n > (Py_ssize_t)image->xsize * (Py_ssize_t)image->ysize) { | |||
1493 | PyErr_SetString(PyExc_TypeError, "too many data entries"); | |||
1494 | return NULL((void*)0); | |||
1495 | } | |||
1496 | ||||
1497 | if (image->image8) { | |||
1498 | if (PyBytes_Check(data)((((((PyObject*)(data))->ob_type))->tp_flags & ((1UL << 27))) != 0)) { | |||
1499 | unsigned char *p; | |||
1500 | p = (unsigned char *)PyBytes_AS_STRING(data)(((void) (0)), (((PyBytesObject *)(data))->ob_sval)); | |||
1501 | if (scale == 1.0 && offset == 0.0) { | |||
1502 | /* Plain string data */ | |||
1503 | for (i = y = 0; i < n; i += image->xsize, y++) { | |||
1504 | x = n - i; | |||
1505 | if (x > (int)image->xsize) { | |||
1506 | x = image->xsize; | |||
1507 | } | |||
1508 | memcpy(image->image8[y], p + i, x); | |||
1509 | } | |||
1510 | } else { | |||
1511 | /* Scaled and clipped string data */ | |||
1512 | for (i = x = y = 0; i < n; i++) { | |||
1513 | image->image8[y][x] = CLIP8((int)(p[i] * scale + offset))(((int)(p[i] * scale + offset)) <= 0 ? 0 : ((int)(p[i] * scale + offset)) < 256 ? ((int)(p[i] * scale + offset)) : 255); | |||
1514 | if (++x >= (int)image->xsize) { | |||
1515 | x = 0, y++; | |||
1516 | } | |||
1517 | } | |||
1518 | } | |||
1519 | } else { | |||
1520 | seq = PySequence_Fast(data, must_be_sequence); | |||
1521 | if (!seq) { | |||
1522 | PyErr_SetString(PyExc_TypeError, must_be_sequence); | |||
1523 | return NULL((void*)0); | |||
1524 | } | |||
1525 | if (scale == 1.0 && offset == 0.0) { | |||
1526 | /* Clipped data */ | |||
1527 | for (i = x = y = 0; i < n; i++) { | |||
1528 | op = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); | |||
1529 | image->image8[y][x] = (UINT8unsigned char)CLIP8(PyLong_AsLong(op))((PyLong_AsLong(op)) <= 0 ? 0 : (PyLong_AsLong(op)) < 256 ? (PyLong_AsLong(op)) : 255); | |||
1530 | if (++x >= (int)image->xsize) { | |||
1531 | x = 0, y++; | |||
1532 | } | |||
1533 | } | |||
1534 | ||||
1535 | } else { | |||
1536 | /* Scaled and clipped data */ | |||
1537 | for (i = x = y = 0; i < n; i++) { | |||
1538 | PyObject *op = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); | |||
1539 | image->image8[y][x] = | |||
1540 | CLIP8((int)(PyFloat_AsDouble(op) * scale + offset))(((int)(PyFloat_AsDouble(op) * scale + offset)) <= 0 ? 0 : ((int)(PyFloat_AsDouble(op) * scale + offset)) < 256 ? (( int)(PyFloat_AsDouble(op) * scale + offset)) : 255); | |||
1541 | if (++x >= (int)image->xsize) { | |||
1542 | x = 0, y++; | |||
1543 | } | |||
1544 | } | |||
1545 | } | |||
1546 | PyErr_Clear(); /* Avoid weird exceptions */ | |||
1547 | } | |||
1548 | } else { | |||
1549 | /* 32-bit images */ | |||
1550 | seq = PySequence_Fast(data, must_be_sequence); | |||
1551 | if (!seq) { | |||
1552 | PyErr_SetString(PyExc_TypeError, must_be_sequence); | |||
1553 | return NULL((void*)0); | |||
1554 | } | |||
1555 | switch (image->type) { | |||
1556 | case IMAGING_TYPE_INT321: | |||
1557 | for (i = x = y = 0; i < n; i++) { | |||
1558 | op = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); | |||
1559 | IMAGING_PIXEL_INT32(image, x, y)((image)->image32[(y)][(x)]) = | |||
1560 | (INT32int)(PyFloat_AsDouble(op) * scale + offset); | |||
1561 | if (++x >= (int)image->xsize) { | |||
1562 | x = 0, y++; | |||
1563 | } | |||
1564 | } | |||
1565 | PyErr_Clear(); /* Avoid weird exceptions */ | |||
1566 | break; | |||
1567 | case IMAGING_TYPE_FLOAT322: | |||
1568 | for (i = x = y = 0; i < n; i++) { | |||
1569 | op = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); | |||
1570 | IMAGING_PIXEL_FLOAT32(image, x, y)(((float *)(image)->image32[y])[x]) = | |||
1571 | (FLOAT32float)(PyFloat_AsDouble(op) * scale + offset); | |||
1572 | if (++x >= (int)image->xsize) { | |||
1573 | x = 0, y++; | |||
1574 | } | |||
1575 | } | |||
1576 | PyErr_Clear(); /* Avoid weird exceptions */ | |||
1577 | break; | |||
1578 | default: | |||
1579 | for (i = x = y = 0; i < n; i++) { | |||
1580 | union { | |||
1581 | char ink[4]; | |||
1582 | INT32int inkint; | |||
1583 | } u; | |||
1584 | ||||
1585 | u.inkint = 0; | |||
1586 | ||||
1587 | op = PySequence_Fast_GET_ITEM(seq, i)(((((((PyObject*)(seq))->ob_type))->tp_flags & ((1UL << 25))) != 0) ? (((PyListObject *)(seq))->ob_item[ i]) : ((((void) (0)), (PyTupleObject *)(seq))->ob_item[i]) ); | |||
1588 | if (!op || !getink(op, image, u.ink)) { | |||
1589 | Py_DECREF(seq)_Py_DECREF(((PyObject*)(seq))); | |||
1590 | return NULL((void*)0); | |||
1591 | } | |||
1592 | /* FIXME: what about scale and offset? */ | |||
1593 | image->image32[y][x] = u.inkint; | |||
1594 | if (++x >= (int)image->xsize) { | |||
1595 | x = 0, y++; | |||
1596 | } | |||
1597 | } | |||
1598 | PyErr_Clear(); /* Avoid weird exceptions */ | |||
1599 | break; | |||
1600 | } | |||
1601 | } | |||
1602 | ||||
1603 | Py_XDECREF(seq)_Py_XDECREF(((PyObject*)(seq))); | |||
1604 | ||||
1605 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1606 | return Py_None(&_Py_NoneStruct); | |||
1607 | } | |||
1608 | ||||
1609 | #ifdef WITH_QUANTIZE | |||
1610 | ||||
1611 | static PyObject * | |||
1612 | _quantize(ImagingObject *self, PyObject *args) { | |||
1613 | int colours = 256; | |||
1614 | int method = 0; | |||
1615 | int kmeans = 0; | |||
1616 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|iii", &colours, &method, &kmeans)) { | |||
1617 | return NULL((void*)0); | |||
1618 | } | |||
1619 | ||||
1620 | if (!self->image->xsize || !self->image->ysize) { | |||
1621 | /* no content; return an empty image */ | |||
1622 | return PyImagingNew(ImagingNew("P", self->image->xsize, self->image->ysize)); | |||
1623 | } | |||
1624 | ||||
1625 | return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans)); | |||
1626 | } | |||
1627 | #endif | |||
1628 | ||||
1629 | static PyObject * | |||
1630 | _putpalette(ImagingObject *self, PyObject *args) { | |||
1631 | ImagingShuffler unpack; | |||
1632 | int bits; | |||
1633 | ||||
1634 | char *rawmode; | |||
1635 | UINT8unsigned char *palette; | |||
1636 | Py_ssize_t palettesize; | |||
1637 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "sy#", &rawmode, &palette, &palettesize)) { | |||
1638 | return NULL((void*)0); | |||
1639 | } | |||
1640 | ||||
1641 | if (strcmp(self->image->mode, "L") && strcmp(self->image->mode, "LA") && | |||
1642 | strcmp(self->image->mode, "P") && strcmp(self->image->mode, "PA")) { | |||
1643 | PyErr_SetString(PyExc_ValueError, wrong_mode); | |||
1644 | return NULL((void*)0); | |||
1645 | } | |||
1646 | ||||
1647 | unpack = ImagingFindUnpacker("RGB", rawmode, &bits); | |||
1648 | if (!unpack) { | |||
1649 | PyErr_SetString(PyExc_ValueError, wrong_raw_mode); | |||
1650 | return NULL((void*)0); | |||
1651 | } | |||
1652 | ||||
1653 | if (palettesize * 8 / bits > 256) { | |||
1654 | PyErr_SetString(PyExc_ValueError, wrong_palette_size); | |||
1655 | return NULL((void*)0); | |||
1656 | } | |||
1657 | ||||
1658 | ImagingPaletteDelete(self->image->palette); | |||
1659 | ||||
1660 | strcpy(self->image->mode, strlen(self->image->mode) == 2 ? "PA" : "P"); | |||
1661 | ||||
1662 | self->image->palette = ImagingPaletteNew("RGB"); | |||
1663 | ||||
1664 | unpack(self->image->palette->palette, palette, palettesize * 8 / bits); | |||
1665 | ||||
1666 | return PyLong_FromLong(palettesize * 8 / bits); | |||
1667 | } | |||
1668 | ||||
1669 | static PyObject * | |||
1670 | _putpalettealpha(ImagingObject *self, PyObject *args) { | |||
1671 | int index; | |||
1672 | int alpha = 0; | |||
1673 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i|i", &index, &alpha)) { | |||
1674 | return NULL((void*)0); | |||
1675 | } | |||
1676 | ||||
1677 | if (!self->image->palette) { | |||
1678 | PyErr_SetString(PyExc_ValueError, no_palette); | |||
1679 | return NULL((void*)0); | |||
1680 | } | |||
1681 | ||||
1682 | if (index < 0 || index >= 256) { | |||
1683 | PyErr_SetString(PyExc_ValueError, outside_palette); | |||
1684 | return NULL((void*)0); | |||
1685 | } | |||
1686 | ||||
1687 | strcpy(self->image->palette->mode, "RGBA"); | |||
1688 | self->image->palette->palette[index * 4 + 3] = (UINT8unsigned char)alpha; | |||
1689 | ||||
1690 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1691 | return Py_None(&_Py_NoneStruct); | |||
1692 | } | |||
1693 | ||||
1694 | static PyObject * | |||
1695 | _putpalettealphas(ImagingObject *self, PyObject *args) { | |||
1696 | int i; | |||
1697 | UINT8unsigned char *values; | |||
1698 | Py_ssize_t length; | |||
1699 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "y#", &values, &length)) { | |||
1700 | return NULL((void*)0); | |||
1701 | } | |||
1702 | ||||
1703 | if (!self->image->palette) { | |||
1704 | PyErr_SetString(PyExc_ValueError, no_palette); | |||
1705 | return NULL((void*)0); | |||
1706 | } | |||
1707 | ||||
1708 | if (length > 256) { | |||
1709 | PyErr_SetString(PyExc_ValueError, outside_palette); | |||
1710 | return NULL((void*)0); | |||
1711 | } | |||
1712 | ||||
1713 | strcpy(self->image->palette->mode, "RGBA"); | |||
1714 | for (i = 0; i < length; i++) { | |||
1715 | self->image->palette->palette[i * 4 + 3] = (UINT8unsigned char)values[i]; | |||
1716 | } | |||
1717 | ||||
1718 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1719 | return Py_None(&_Py_NoneStruct); | |||
1720 | } | |||
1721 | ||||
1722 | static PyObject * | |||
1723 | _putpixel(ImagingObject *self, PyObject *args) { | |||
1724 | Imaging im; | |||
1725 | char ink[4]; | |||
1726 | ||||
1727 | int x, y; | |||
1728 | PyObject *color; | |||
1729 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(ii)O", &x, &y, &color)) { | |||
1730 | return NULL((void*)0); | |||
1731 | } | |||
1732 | ||||
1733 | im = self->image; | |||
1734 | ||||
1735 | if (x < 0) { | |||
1736 | x = im->xsize + x; | |||
1737 | } | |||
1738 | if (y < 0) { | |||
1739 | y = im->ysize + y; | |||
1740 | } | |||
1741 | ||||
1742 | if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { | |||
1743 | PyErr_SetString(PyExc_IndexError, outside_image); | |||
1744 | return NULL((void*)0); | |||
1745 | } | |||
1746 | ||||
1747 | if (!getink(color, im, ink)) { | |||
1748 | return NULL((void*)0); | |||
1749 | } | |||
1750 | ||||
1751 | if (self->access) { | |||
1752 | self->access->put_pixel(im, x, y, ink); | |||
1753 | } | |||
1754 | ||||
1755 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1756 | return Py_None(&_Py_NoneStruct); | |||
1757 | } | |||
1758 | ||||
1759 | #ifdef WITH_RANKFILTER | |||
1760 | static PyObject * | |||
1761 | _rankfilter(ImagingObject *self, PyObject *args) { | |||
1762 | int size, rank; | |||
1763 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "ii", &size, &rank)) { | |||
1764 | return NULL((void*)0); | |||
1765 | } | |||
1766 | ||||
1767 | return PyImagingNew(ImagingRankFilter(self->image, size, rank)); | |||
1768 | } | |||
1769 | #endif | |||
1770 | ||||
1771 | static PyObject * | |||
1772 | _resize(ImagingObject *self, PyObject *args) { | |||
1773 | Imaging imIn; | |||
1774 | Imaging imOut; | |||
1775 | ||||
1776 | int xsize, ysize; | |||
1777 | int filter = IMAGING_TRANSFORM_NEAREST0; | |||
1778 | float box[4] = {0, 0, 0, 0}; | |||
1779 | ||||
1780 | imIn = self->image; | |||
1781 | box[2] = imIn->xsize; | |||
1782 | box[3] = imIn->ysize; | |||
1783 | ||||
1784 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
1785 | args, | |||
1786 | "(ii)|i(ffff)", | |||
1787 | &xsize, | |||
1788 | &ysize, | |||
1789 | &filter, | |||
1790 | &box[0], | |||
1791 | &box[1], | |||
1792 | &box[2], | |||
1793 | &box[3])) { | |||
1794 | return NULL((void*)0); | |||
1795 | } | |||
1796 | ||||
1797 | if (xsize < 1 || ysize < 1) { | |||
1798 | return ImagingError_ValueError("height and width must be > 0"); | |||
1799 | } | |||
1800 | ||||
1801 | if (box[0] < 0 || box[1] < 0) { | |||
1802 | return ImagingError_ValueError("box offset can't be negative"); | |||
1803 | } | |||
1804 | ||||
1805 | if (box[2] > imIn->xsize || box[3] > imIn->ysize) { | |||
1806 | return ImagingError_ValueError("box can't exceed original image size"); | |||
1807 | } | |||
1808 | ||||
1809 | if (box[2] - box[0] < 0 || box[3] - box[1] < 0) { | |||
1810 | return ImagingError_ValueError("box can't be empty"); | |||
1811 | } | |||
1812 | ||||
1813 | // If box's coordinates are int and box size matches requested size | |||
1814 | if (box[0] - (int)box[0] == 0 && box[2] - box[0] == xsize && | |||
1815 | box[1] - (int)box[1] == 0 && box[3] - box[1] == ysize) { | |||
1816 | imOut = ImagingCrop(imIn, box[0], box[1], box[2], box[3]); | |||
1817 | } else if (filter == IMAGING_TRANSFORM_NEAREST0) { | |||
1818 | double a[6]; | |||
1819 | ||||
1820 | memset(a, 0, sizeof a); | |||
1821 | a[0] = (double)(box[2] - box[0]) / xsize; | |||
1822 | a[4] = (double)(box[3] - box[1]) / ysize; | |||
1823 | a[2] = box[0]; | |||
1824 | a[5] = box[1]; | |||
1825 | ||||
1826 | imOut = ImagingNewDirty(imIn->mode, xsize, ysize); | |||
1827 | ||||
1828 | imOut = ImagingTransform( | |||
1829 | imOut, imIn, IMAGING_TRANSFORM_AFFINE0, 0, 0, xsize, ysize, a, filter, 1); | |||
1830 | } else { | |||
1831 | imOut = ImagingResample(imIn, xsize, ysize, filter, box); | |||
1832 | } | |||
1833 | ||||
1834 | return PyImagingNew(imOut); | |||
1835 | } | |||
1836 | ||||
1837 | static PyObject * | |||
1838 | _reduce(ImagingObject *self, PyObject *args) { | |||
1839 | Imaging imIn; | |||
1840 | Imaging imOut; | |||
1841 | ||||
1842 | int xscale, yscale; | |||
1843 | int box[4] = {0, 0, 0, 0}; | |||
1844 | ||||
1845 | imIn = self->image; | |||
1846 | box[2] = imIn->xsize; | |||
1847 | box[3] = imIn->ysize; | |||
1848 | ||||
1849 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
1850 | args, | |||
1851 | "(ii)|(iiii)", | |||
1852 | &xscale, | |||
1853 | &yscale, | |||
1854 | &box[0], | |||
1855 | &box[1], | |||
1856 | &box[2], | |||
1857 | &box[3])) { | |||
1858 | return NULL((void*)0); | |||
1859 | } | |||
1860 | ||||
1861 | if (xscale < 1 || yscale < 1) { | |||
1862 | return ImagingError_ValueError("scale must be > 0"); | |||
1863 | } | |||
1864 | ||||
1865 | if (box[0] < 0 || box[1] < 0) { | |||
1866 | return ImagingError_ValueError("box offset can't be negative"); | |||
1867 | } | |||
1868 | ||||
1869 | if (box[2] > imIn->xsize || box[3] > imIn->ysize) { | |||
1870 | return ImagingError_ValueError("box can't exceed original image size"); | |||
1871 | } | |||
1872 | ||||
1873 | if (box[2] <= box[0] || box[3] <= box[1]) { | |||
1874 | return ImagingError_ValueError("box can't be empty"); | |||
1875 | } | |||
1876 | ||||
1877 | if (xscale == 1 && yscale == 1) { | |||
1878 | imOut = ImagingCrop(imIn, box[0], box[1], box[2], box[3]); | |||
1879 | } else { | |||
1880 | // Change box format: (left, top, width, height) | |||
1881 | box[2] -= box[0]; | |||
1882 | box[3] -= box[1]; | |||
1883 | imOut = ImagingReduce(imIn, xscale, yscale, box); | |||
1884 | } | |||
1885 | ||||
1886 | return PyImagingNew(imOut); | |||
1887 | } | |||
1888 | ||||
1889 | #define IS_RGB(mode)(!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode , "RGBX")) \ | |||
1890 | (!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode, "RGBX")) | |||
1891 | ||||
1892 | static PyObject * | |||
1893 | im_setmode(ImagingObject *self, PyObject *args) { | |||
1894 | /* attempt to modify the mode of an image in place */ | |||
1895 | ||||
1896 | Imaging im; | |||
1897 | ||||
1898 | char *mode; | |||
1899 | Py_ssize_t modelen; | |||
1900 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s#:setmode", &mode, &modelen)) { | |||
1901 | return NULL((void*)0); | |||
1902 | } | |||
1903 | ||||
1904 | im = self->image; | |||
1905 | ||||
1906 | /* move all logic in here to the libImaging primitive */ | |||
1907 | ||||
1908 | if (!strcmp(im->mode, mode)) { | |||
1909 | ; /* same mode; always succeeds */ | |||
1910 | } else if (IS_RGB(im->mode)(!strcmp(im->mode, "RGB") || !strcmp(im->mode, "RGBA") || !strcmp(im->mode, "RGBX")) && IS_RGB(mode)(!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode , "RGBX"))) { | |||
1911 | /* color to color */ | |||
1912 | strcpy(im->mode, mode); | |||
1913 | im->bands = modelen; | |||
1914 | if (!strcmp(mode, "RGBA")) { | |||
1915 | (void)ImagingFillBand(im, 3, 255); | |||
1916 | } | |||
1917 | } else { | |||
1918 | /* trying doing an in-place conversion */ | |||
1919 | if (!ImagingConvertInPlace(im, mode)) { | |||
1920 | return NULL((void*)0); | |||
1921 | } | |||
1922 | } | |||
1923 | ||||
1924 | if (self->access) { | |||
1925 | ImagingAccessDelete(im, self->access); | |||
1926 | } | |||
1927 | self->access = ImagingAccessNew(im); | |||
1928 | ||||
1929 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1930 | return Py_None(&_Py_NoneStruct); | |||
1931 | } | |||
1932 | ||||
1933 | static PyObject * | |||
1934 | _transform2(ImagingObject *self, PyObject *args) { | |||
1935 | static const char *wrong_number = "wrong number of matrix entries"; | |||
1936 | ||||
1937 | Imaging imOut; | |||
1938 | Py_ssize_t n; | |||
1939 | double *a; | |||
1940 | ||||
1941 | ImagingObject *imagep; | |||
1942 | int x0, y0, x1, y1; | |||
1943 | int method; | |||
1944 | PyObject *data; | |||
1945 | int filter = IMAGING_TRANSFORM_NEAREST0; | |||
1946 | int fill = 1; | |||
1947 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
1948 | args, | |||
1949 | "(iiii)O!iO|ii", | |||
1950 | &x0, | |||
1951 | &y0, | |||
1952 | &x1, | |||
1953 | &y1, | |||
1954 | &Imaging_Type, | |||
1955 | &imagep, | |||
1956 | &method, | |||
1957 | &data, | |||
1958 | &filter, | |||
1959 | &fill)) { | |||
1960 | return NULL((void*)0); | |||
1961 | } | |||
1962 | ||||
1963 | switch (method) { | |||
1964 | case IMAGING_TRANSFORM_AFFINE0: | |||
1965 | n = 6; | |||
1966 | break; | |||
1967 | case IMAGING_TRANSFORM_PERSPECTIVE2: | |||
1968 | n = 8; | |||
1969 | break; | |||
1970 | case IMAGING_TRANSFORM_QUAD3: | |||
1971 | n = 8; | |||
1972 | break; | |||
1973 | default: | |||
1974 | n = -1; /* force error */ | |||
1975 | } | |||
1976 | ||||
1977 | a = getlist(data, &n, wrong_number, TYPE_DOUBLE(0x400 | sizeof(double))); | |||
1978 | if (!a) { | |||
1979 | return NULL((void*)0); | |||
1980 | } | |||
1981 | ||||
1982 | imOut = ImagingTransform( | |||
1983 | self->image, imagep->image, method, x0, y0, x1, y1, a, filter, fill); | |||
1984 | ||||
1985 | free(a); | |||
1986 | ||||
1987 | if (!imOut) { | |||
1988 | return NULL((void*)0); | |||
1989 | } | |||
1990 | ||||
1991 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
1992 | return Py_None(&_Py_NoneStruct); | |||
1993 | } | |||
1994 | ||||
1995 | static PyObject * | |||
1996 | _transpose(ImagingObject *self, PyObject *args) { | |||
1997 | Imaging imIn; | |||
1998 | Imaging imOut; | |||
1999 | ||||
2000 | int op; | |||
2001 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i", &op)) { | |||
2002 | return NULL((void*)0); | |||
2003 | } | |||
2004 | ||||
2005 | imIn = self->image; | |||
2006 | ||||
2007 | switch (op) { | |||
2008 | case 0: /* flip left right */ | |||
2009 | case 1: /* flip top bottom */ | |||
2010 | case 3: /* rotate 180 */ | |||
2011 | imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize); | |||
2012 | break; | |||
2013 | case 2: /* rotate 90 */ | |||
2014 | case 4: /* rotate 270 */ | |||
2015 | case 5: /* transpose */ | |||
2016 | case 6: /* transverse */ | |||
2017 | imOut = ImagingNewDirty(imIn->mode, imIn->ysize, imIn->xsize); | |||
2018 | break; | |||
2019 | default: | |||
2020 | PyErr_SetString(PyExc_ValueError, "No such transpose operation"); | |||
2021 | return NULL((void*)0); | |||
2022 | } | |||
2023 | ||||
2024 | if (imOut) { | |||
2025 | switch (op) { | |||
2026 | case 0: | |||
2027 | (void)ImagingFlipLeftRight(imOut, imIn); | |||
2028 | break; | |||
2029 | case 1: | |||
2030 | (void)ImagingFlipTopBottom(imOut, imIn); | |||
2031 | break; | |||
2032 | case 2: | |||
2033 | (void)ImagingRotate90(imOut, imIn); | |||
2034 | break; | |||
2035 | case 3: | |||
2036 | (void)ImagingRotate180(imOut, imIn); | |||
2037 | break; | |||
2038 | case 4: | |||
2039 | (void)ImagingRotate270(imOut, imIn); | |||
2040 | break; | |||
2041 | case 5: | |||
2042 | (void)ImagingTranspose(imOut, imIn); | |||
2043 | break; | |||
2044 | case 6: | |||
2045 | (void)ImagingTransverse(imOut, imIn); | |||
2046 | break; | |||
2047 | } | |||
2048 | } | |||
2049 | ||||
2050 | return PyImagingNew(imOut); | |||
2051 | } | |||
2052 | ||||
2053 | #ifdef WITH_UNSHARPMASK | |||
2054 | static PyObject * | |||
2055 | _unsharp_mask(ImagingObject *self, PyObject *args) { | |||
2056 | Imaging imIn; | |||
2057 | Imaging imOut; | |||
2058 | ||||
2059 | float radius; | |||
2060 | int percent, threshold; | |||
2061 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "fii", &radius, &percent, &threshold)) { | |||
2062 | return NULL((void*)0); | |||
2063 | } | |||
2064 | ||||
2065 | imIn = self->image; | |||
2066 | imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize); | |||
2067 | if (!imOut) { | |||
2068 | return NULL((void*)0); | |||
2069 | } | |||
2070 | ||||
2071 | if (!ImagingUnsharpMask(imOut, imIn, radius, percent, threshold)) { | |||
2072 | return NULL((void*)0); | |||
2073 | } | |||
2074 | ||||
2075 | return PyImagingNew(imOut); | |||
2076 | } | |||
2077 | #endif | |||
2078 | ||||
2079 | static PyObject * | |||
2080 | _box_blur(ImagingObject *self, PyObject *args) { | |||
2081 | Imaging imIn; | |||
2082 | Imaging imOut; | |||
2083 | ||||
2084 | float radius; | |||
2085 | int n = 1; | |||
2086 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "f|i", &radius, &n)) { | |||
2087 | return NULL((void*)0); | |||
2088 | } | |||
2089 | ||||
2090 | imIn = self->image; | |||
2091 | imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize); | |||
2092 | if (!imOut) { | |||
2093 | return NULL((void*)0); | |||
2094 | } | |||
2095 | ||||
2096 | if (!ImagingBoxBlur(imOut, imIn, radius, n)) { | |||
2097 | ImagingDelete(imOut); | |||
2098 | return NULL((void*)0); | |||
2099 | } | |||
2100 | ||||
2101 | return PyImagingNew(imOut); | |||
2102 | } | |||
2103 | ||||
2104 | /* -------------------------------------------------------------------- */ | |||
2105 | ||||
2106 | static PyObject * | |||
2107 | _isblock(ImagingObject *self) { | |||
2108 | return PyBool_FromLong(self->image->block != NULL((void*)0)); | |||
2109 | } | |||
2110 | ||||
2111 | static PyObject * | |||
2112 | _getbbox(ImagingObject *self) { | |||
2113 | int bbox[4]; | |||
2114 | if (!ImagingGetBBox(self->image, bbox)) { | |||
2115 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2116 | return Py_None(&_Py_NoneStruct); | |||
2117 | } | |||
2118 | ||||
2119 | return Py_BuildValue_Py_BuildValue_SizeT("iiii", bbox[0], bbox[1], bbox[2], bbox[3]); | |||
2120 | } | |||
2121 | ||||
2122 | static PyObject * | |||
2123 | _getcolors(ImagingObject *self, PyObject *args) { | |||
2124 | ImagingColorItem *items; | |||
2125 | int i, colors; | |||
2126 | PyObject *out; | |||
2127 | ||||
2128 | int maxcolors = 256; | |||
2129 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i:getcolors", &maxcolors)) { | |||
2130 | return NULL((void*)0); | |||
2131 | } | |||
2132 | ||||
2133 | items = ImagingGetColors(self->image, maxcolors, &colors); | |||
2134 | if (!items) { | |||
2135 | return NULL((void*)0); | |||
2136 | } | |||
2137 | ||||
2138 | if (colors > maxcolors) { | |||
2139 | out = Py_None(&_Py_NoneStruct); | |||
2140 | Py_INCREF(out)_Py_INCREF(((PyObject*)(out))); | |||
2141 | } else { | |||
2142 | out = PyList_New(colors); | |||
2143 | for (i = 0; i < colors; i++) { | |||
2144 | ImagingColorItem *v = &items[i]; | |||
2145 | PyObject *item = Py_BuildValue_Py_BuildValue_SizeT( | |||
2146 | "iN", v->count, getpixel(self->image, self->access, v->x, v->y)); | |||
2147 | PyList_SetItem(out, i, item); | |||
2148 | } | |||
2149 | } | |||
2150 | ||||
2151 | free(items); | |||
2152 | ||||
2153 | return out; | |||
2154 | } | |||
2155 | ||||
2156 | static PyObject * | |||
2157 | _getextrema(ImagingObject *self) { | |||
2158 | union { | |||
2159 | UINT8unsigned char u[2]; | |||
2160 | INT32int i[2]; | |||
2161 | FLOAT32float f[2]; | |||
2162 | UINT16unsigned short s[2]; | |||
2163 | } extrema; | |||
2164 | int status; | |||
2165 | ||||
2166 | status = ImagingGetExtrema(self->image, &extrema); | |||
2167 | if (status < 0) { | |||
2168 | return NULL((void*)0); | |||
2169 | } | |||
2170 | ||||
2171 | if (status) { | |||
2172 | switch (self->image->type) { | |||
2173 | case IMAGING_TYPE_UINT80: | |||
2174 | return Py_BuildValue_Py_BuildValue_SizeT("BB", extrema.u[0], extrema.u[1]); | |||
2175 | case IMAGING_TYPE_INT321: | |||
2176 | return Py_BuildValue_Py_BuildValue_SizeT("ii", extrema.i[0], extrema.i[1]); | |||
2177 | case IMAGING_TYPE_FLOAT322: | |||
2178 | return Py_BuildValue_Py_BuildValue_SizeT("dd", extrema.f[0], extrema.f[1]); | |||
2179 | case IMAGING_TYPE_SPECIAL3: | |||
2180 | if (strcmp(self->image->mode, "I;16") == 0) { | |||
2181 | return Py_BuildValue_Py_BuildValue_SizeT("HH", extrema.s[0], extrema.s[1]); | |||
2182 | } | |||
2183 | } | |||
2184 | } | |||
2185 | ||||
2186 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2187 | return Py_None(&_Py_NoneStruct); | |||
2188 | } | |||
2189 | ||||
2190 | static PyObject * | |||
2191 | _getprojection(ImagingObject *self) { | |||
2192 | unsigned char *xprofile; | |||
2193 | unsigned char *yprofile; | |||
2194 | PyObject *result; | |||
2195 | ||||
2196 | /* malloc check ok */ | |||
2197 | xprofile = malloc(self->image->xsize); | |||
2198 | yprofile = malloc(self->image->ysize); | |||
2199 | ||||
2200 | if (xprofile == NULL((void*)0) || yprofile == NULL((void*)0)) { | |||
2201 | free(xprofile); | |||
2202 | free(yprofile); | |||
2203 | return ImagingError_MemoryError(); | |||
2204 | } | |||
2205 | ||||
2206 | ImagingGetProjection( | |||
2207 | self->image, (unsigned char *)xprofile, (unsigned char *)yprofile); | |||
2208 | ||||
2209 | result = Py_BuildValue_Py_BuildValue_SizeT( | |||
2210 | "y#y#", | |||
2211 | xprofile, | |||
2212 | (Py_ssize_t)self->image->xsize, | |||
2213 | yprofile, | |||
2214 | (Py_ssize_t)self->image->ysize); | |||
2215 | ||||
2216 | free(xprofile); | |||
2217 | free(yprofile); | |||
2218 | ||||
2219 | return result; | |||
2220 | } | |||
2221 | ||||
2222 | /* -------------------------------------------------------------------- */ | |||
2223 | ||||
2224 | static PyObject * | |||
2225 | _getband(ImagingObject *self, PyObject *args) { | |||
2226 | int band; | |||
2227 | ||||
2228 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i", &band)) { | |||
2229 | return NULL((void*)0); | |||
2230 | } | |||
2231 | ||||
2232 | return PyImagingNew(ImagingGetBand(self->image, band)); | |||
2233 | } | |||
2234 | ||||
2235 | static PyObject * | |||
2236 | _fillband(ImagingObject *self, PyObject *args) { | |||
2237 | int band; | |||
2238 | int color; | |||
2239 | ||||
2240 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "ii", &band, &color)) { | |||
2241 | return NULL((void*)0); | |||
2242 | } | |||
2243 | ||||
2244 | if (!ImagingFillBand(self->image, band, color)) { | |||
2245 | return NULL((void*)0); | |||
2246 | } | |||
2247 | ||||
2248 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2249 | return Py_None(&_Py_NoneStruct); | |||
2250 | } | |||
2251 | ||||
2252 | static PyObject * | |||
2253 | _putband(ImagingObject *self, PyObject *args) { | |||
2254 | ImagingObject *imagep; | |||
2255 | int band; | |||
2256 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!i", &Imaging_Type, &imagep, &band)) { | |||
2257 | return NULL((void*)0); | |||
2258 | } | |||
2259 | ||||
2260 | if (!ImagingPutBand(self->image, imagep->image, band)) { | |||
2261 | return NULL((void*)0); | |||
2262 | } | |||
2263 | ||||
2264 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2265 | return Py_None(&_Py_NoneStruct); | |||
2266 | } | |||
2267 | ||||
2268 | static PyObject * | |||
2269 | _merge(PyObject *self, PyObject *args) { | |||
2270 | char *mode; | |||
2271 | ImagingObject *band0 = NULL((void*)0); | |||
2272 | ImagingObject *band1 = NULL((void*)0); | |||
2273 | ImagingObject *band2 = NULL((void*)0); | |||
2274 | ImagingObject *band3 = NULL((void*)0); | |||
2275 | Imaging bands[4] = {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}; | |||
2276 | ||||
2277 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
2278 | args, | |||
2279 | "sO!|O!O!O!", | |||
2280 | &mode, | |||
2281 | &Imaging_Type, | |||
2282 | &band0, | |||
2283 | &Imaging_Type, | |||
2284 | &band1, | |||
2285 | &Imaging_Type, | |||
2286 | &band2, | |||
2287 | &Imaging_Type, | |||
2288 | &band3)) { | |||
2289 | return NULL((void*)0); | |||
2290 | } | |||
2291 | ||||
2292 | if (band0) { | |||
2293 | bands[0] = band0->image; | |||
2294 | } | |||
2295 | if (band1) { | |||
2296 | bands[1] = band1->image; | |||
2297 | } | |||
2298 | if (band2) { | |||
2299 | bands[2] = band2->image; | |||
2300 | } | |||
2301 | if (band3) { | |||
2302 | bands[3] = band3->image; | |||
2303 | } | |||
2304 | ||||
2305 | return PyImagingNew(ImagingMerge(mode, bands)); | |||
2306 | } | |||
2307 | ||||
2308 | static PyObject * | |||
2309 | _split(ImagingObject *self) { | |||
2310 | int fails = 0; | |||
2311 | Py_ssize_t i; | |||
2312 | PyObject *list; | |||
2313 | PyObject *imaging_object; | |||
2314 | Imaging bands[4] = {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}; | |||
2315 | ||||
2316 | if (!ImagingSplit(self->image, bands)) { | |||
2317 | return NULL((void*)0); | |||
2318 | } | |||
2319 | ||||
2320 | list = PyTuple_New(self->image->bands); | |||
2321 | for (i = 0; i < self->image->bands; i++) { | |||
2322 | imaging_object = PyImagingNew(bands[i]); | |||
2323 | if (!imaging_object) { | |||
2324 | fails += 1; | |||
2325 | } | |||
2326 | PyTuple_SET_ITEM(list, i, imaging_object)PyTuple_SetItem(list, i, imaging_object); | |||
2327 | } | |||
2328 | if (fails) { | |||
2329 | Py_DECREF(list)_Py_DECREF(((PyObject*)(list))); | |||
2330 | list = NULL((void*)0); | |||
2331 | } | |||
2332 | return list; | |||
2333 | } | |||
2334 | ||||
2335 | /* -------------------------------------------------------------------- */ | |||
2336 | ||||
2337 | #ifdef WITH_IMAGECHOPS | |||
2338 | ||||
2339 | static PyObject * | |||
2340 | _chop_invert(ImagingObject *self) { | |||
2341 | return PyImagingNew(ImagingNegative(self->image)); | |||
2342 | } | |||
2343 | ||||
2344 | static PyObject * | |||
2345 | _chop_lighter(ImagingObject *self, PyObject *args) { | |||
2346 | ImagingObject *imagep; | |||
2347 | ||||
2348 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2349 | return NULL((void*)0); | |||
2350 | } | |||
2351 | ||||
2352 | return PyImagingNew(ImagingChopLighter(self->image, imagep->image)); | |||
2353 | } | |||
2354 | ||||
2355 | static PyObject * | |||
2356 | _chop_darker(ImagingObject *self, PyObject *args) { | |||
2357 | ImagingObject *imagep; | |||
2358 | ||||
2359 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2360 | return NULL((void*)0); | |||
2361 | } | |||
2362 | ||||
2363 | return PyImagingNew(ImagingChopDarker(self->image, imagep->image)); | |||
2364 | } | |||
2365 | ||||
2366 | static PyObject * | |||
2367 | _chop_difference(ImagingObject *self, PyObject *args) { | |||
2368 | ImagingObject *imagep; | |||
2369 | ||||
2370 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2371 | return NULL((void*)0); | |||
2372 | } | |||
2373 | ||||
2374 | return PyImagingNew(ImagingChopDifference(self->image, imagep->image)); | |||
2375 | } | |||
2376 | ||||
2377 | static PyObject * | |||
2378 | _chop_multiply(ImagingObject *self, PyObject *args) { | |||
2379 | ImagingObject *imagep; | |||
2380 | ||||
2381 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2382 | return NULL((void*)0); | |||
2383 | } | |||
2384 | ||||
2385 | return PyImagingNew(ImagingChopMultiply(self->image, imagep->image)); | |||
2386 | } | |||
2387 | ||||
2388 | static PyObject * | |||
2389 | _chop_screen(ImagingObject *self, PyObject *args) { | |||
2390 | ImagingObject *imagep; | |||
2391 | ||||
2392 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2393 | return NULL((void*)0); | |||
2394 | } | |||
2395 | ||||
2396 | return PyImagingNew(ImagingChopScreen(self->image, imagep->image)); | |||
2397 | } | |||
2398 | ||||
2399 | static PyObject * | |||
2400 | _chop_add(ImagingObject *self, PyObject *args) { | |||
2401 | ImagingObject *imagep; | |||
2402 | float scale; | |||
2403 | int offset; | |||
2404 | ||||
2405 | scale = 1.0; | |||
2406 | offset = 0; | |||
2407 | ||||
2408 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!|fi", &Imaging_Type, &imagep, &scale, &offset)) { | |||
2409 | return NULL((void*)0); | |||
2410 | } | |||
2411 | ||||
2412 | return PyImagingNew(ImagingChopAdd(self->image, imagep->image, scale, offset)); | |||
2413 | } | |||
2414 | ||||
2415 | static PyObject * | |||
2416 | _chop_subtract(ImagingObject *self, PyObject *args) { | |||
2417 | ImagingObject *imagep; | |||
2418 | float scale; | |||
2419 | int offset; | |||
2420 | ||||
2421 | scale = 1.0; | |||
2422 | offset = 0; | |||
2423 | ||||
2424 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!|fi", &Imaging_Type, &imagep, &scale, &offset)) { | |||
2425 | return NULL((void*)0); | |||
2426 | } | |||
2427 | ||||
2428 | return PyImagingNew(ImagingChopSubtract(self->image, imagep->image, scale, offset)); | |||
2429 | } | |||
2430 | ||||
2431 | static PyObject * | |||
2432 | _chop_and(ImagingObject *self, PyObject *args) { | |||
2433 | ImagingObject *imagep; | |||
2434 | ||||
2435 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2436 | return NULL((void*)0); | |||
2437 | } | |||
2438 | ||||
2439 | return PyImagingNew(ImagingChopAnd(self->image, imagep->image)); | |||
2440 | } | |||
2441 | ||||
2442 | static PyObject * | |||
2443 | _chop_or(ImagingObject *self, PyObject *args) { | |||
2444 | ImagingObject *imagep; | |||
2445 | ||||
2446 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2447 | return NULL((void*)0); | |||
2448 | } | |||
2449 | ||||
2450 | return PyImagingNew(ImagingChopOr(self->image, imagep->image)); | |||
2451 | } | |||
2452 | ||||
2453 | static PyObject * | |||
2454 | _chop_xor(ImagingObject *self, PyObject *args) { | |||
2455 | ImagingObject *imagep; | |||
2456 | ||||
2457 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2458 | return NULL((void*)0); | |||
2459 | } | |||
2460 | ||||
2461 | return PyImagingNew(ImagingChopXor(self->image, imagep->image)); | |||
2462 | } | |||
2463 | ||||
2464 | static PyObject * | |||
2465 | _chop_add_modulo(ImagingObject *self, PyObject *args) { | |||
2466 | ImagingObject *imagep; | |||
2467 | ||||
2468 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2469 | return NULL((void*)0); | |||
2470 | } | |||
2471 | ||||
2472 | return PyImagingNew(ImagingChopAddModulo(self->image, imagep->image)); | |||
2473 | } | |||
2474 | ||||
2475 | static PyObject * | |||
2476 | _chop_subtract_modulo(ImagingObject *self, PyObject *args) { | |||
2477 | ImagingObject *imagep; | |||
2478 | ||||
2479 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2480 | return NULL((void*)0); | |||
2481 | } | |||
2482 | ||||
2483 | return PyImagingNew(ImagingChopSubtractModulo(self->image, imagep->image)); | |||
2484 | } | |||
2485 | ||||
2486 | static PyObject * | |||
2487 | _chop_soft_light(ImagingObject *self, PyObject *args) { | |||
2488 | ImagingObject *imagep; | |||
2489 | ||||
2490 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2491 | return NULL((void*)0); | |||
2492 | } | |||
2493 | ||||
2494 | return PyImagingNew(ImagingChopSoftLight(self->image, imagep->image)); | |||
2495 | } | |||
2496 | ||||
2497 | static PyObject * | |||
2498 | _chop_hard_light(ImagingObject *self, PyObject *args) { | |||
2499 | ImagingObject *imagep; | |||
2500 | ||||
2501 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2502 | return NULL((void*)0); | |||
2503 | } | |||
2504 | ||||
2505 | return PyImagingNew(ImagingChopHardLight(self->image, imagep->image)); | |||
2506 | } | |||
2507 | ||||
2508 | static PyObject * | |||
2509 | _chop_overlay(ImagingObject *self, PyObject *args) { | |||
2510 | ImagingObject *imagep; | |||
2511 | ||||
2512 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &Imaging_Type, &imagep)) { | |||
2513 | return NULL((void*)0); | |||
2514 | } | |||
2515 | ||||
2516 | return PyImagingNew(ImagingOverlay(self->image, imagep->image)); | |||
2517 | } | |||
2518 | #endif | |||
2519 | ||||
2520 | /* -------------------------------------------------------------------- */ | |||
2521 | ||||
2522 | #ifdef WITH_IMAGEDRAW | |||
2523 | ||||
2524 | static PyObject * | |||
2525 | _font_new(PyObject *self_, PyObject *args) { | |||
2526 | ImagingFontObject *self; | |||
2527 | int i, y0, y1; | |||
2528 | static const char *wrong_length = "descriptor table has wrong size"; | |||
2529 | ||||
2530 | ImagingObject *imagep; | |||
2531 | unsigned char *glyphdata; | |||
2532 | Py_ssize_t glyphdata_length; | |||
2533 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
2534 | args, "O!y#", &Imaging_Type, &imagep, &glyphdata, &glyphdata_length)) { | |||
2535 | return NULL((void*)0); | |||
2536 | } | |||
2537 | ||||
2538 | if (glyphdata_length != 256 * 20) { | |||
2539 | PyErr_SetString(PyExc_ValueError, wrong_length); | |||
2540 | return NULL((void*)0); | |||
2541 | } | |||
2542 | ||||
2543 | self = PyObject_New(ImagingFontObject, &ImagingFont_Type)( (ImagingFontObject *) _PyObject_New(&ImagingFont_Type) ); | |||
2544 | if (self == NULL((void*)0)) { | |||
2545 | return NULL((void*)0); | |||
2546 | } | |||
2547 | ||||
2548 | /* glyph bitmap */ | |||
2549 | self->bitmap = imagep->image; | |||
2550 | ||||
2551 | y0 = y1 = 0; | |||
2552 | ||||
2553 | /* glyph glyphs */ | |||
2554 | for (i = 0; i < 256; i++) { | |||
2555 | self->glyphs[i].dx = S16(B16(glyphdata, 0))((((((int)glyphdata[(0)]) << 8) + glyphdata[(0) + 1])) < 32768 ? (((((int)glyphdata[(0)]) << 8) + glyphdata[(0) + 1])) : ((((((int)glyphdata[(0)]) << 8) + glyphdata[( 0) + 1]))-65536)); | |||
2556 | self->glyphs[i].dy = S16(B16(glyphdata, 2))((((((int)glyphdata[(2)]) << 8) + glyphdata[(2) + 1])) < 32768 ? (((((int)glyphdata[(2)]) << 8) + glyphdata[(2) + 1])) : ((((((int)glyphdata[(2)]) << 8) + glyphdata[( 2) + 1]))-65536)); | |||
2557 | self->glyphs[i].dx0 = S16(B16(glyphdata, 4))((((((int)glyphdata[(4)]) << 8) + glyphdata[(4) + 1])) < 32768 ? (((((int)glyphdata[(4)]) << 8) + glyphdata[(4) + 1])) : ((((((int)glyphdata[(4)]) << 8) + glyphdata[( 4) + 1]))-65536)); | |||
2558 | self->glyphs[i].dy0 = S16(B16(glyphdata, 6))((((((int)glyphdata[(6)]) << 8) + glyphdata[(6) + 1])) < 32768 ? (((((int)glyphdata[(6)]) << 8) + glyphdata[(6) + 1])) : ((((((int)glyphdata[(6)]) << 8) + glyphdata[( 6) + 1]))-65536)); | |||
2559 | self->glyphs[i].dx1 = S16(B16(glyphdata, 8))((((((int)glyphdata[(8)]) << 8) + glyphdata[(8) + 1])) < 32768 ? (((((int)glyphdata[(8)]) << 8) + glyphdata[(8) + 1])) : ((((((int)glyphdata[(8)]) << 8) + glyphdata[( 8) + 1]))-65536)); | |||
2560 | self->glyphs[i].dy1 = S16(B16(glyphdata, 10))((((((int)glyphdata[(10)]) << 8) + glyphdata[(10) + 1]) ) < 32768 ? (((((int)glyphdata[(10)]) << 8) + glyphdata [(10) + 1])) : ((((((int)glyphdata[(10)]) << 8) + glyphdata [(10) + 1]))-65536)); | |||
2561 | self->glyphs[i].sx0 = S16(B16(glyphdata, 12))((((((int)glyphdata[(12)]) << 8) + glyphdata[(12) + 1]) ) < 32768 ? (((((int)glyphdata[(12)]) << 8) + glyphdata [(12) + 1])) : ((((((int)glyphdata[(12)]) << 8) + glyphdata [(12) + 1]))-65536)); | |||
2562 | self->glyphs[i].sy0 = S16(B16(glyphdata, 14))((((((int)glyphdata[(14)]) << 8) + glyphdata[(14) + 1]) ) < 32768 ? (((((int)glyphdata[(14)]) << 8) + glyphdata [(14) + 1])) : ((((((int)glyphdata[(14)]) << 8) + glyphdata [(14) + 1]))-65536)); | |||
2563 | self->glyphs[i].sx1 = S16(B16(glyphdata, 16))((((((int)glyphdata[(16)]) << 8) + glyphdata[(16) + 1]) ) < 32768 ? (((((int)glyphdata[(16)]) << 8) + glyphdata [(16) + 1])) : ((((((int)glyphdata[(16)]) << 8) + glyphdata [(16) + 1]))-65536)); | |||
2564 | self->glyphs[i].sy1 = S16(B16(glyphdata, 18))((((((int)glyphdata[(18)]) << 8) + glyphdata[(18) + 1]) ) < 32768 ? (((((int)glyphdata[(18)]) << 8) + glyphdata [(18) + 1])) : ((((((int)glyphdata[(18)]) << 8) + glyphdata [(18) + 1]))-65536)); | |||
2565 | if (self->glyphs[i].dy0 < y0) { | |||
2566 | y0 = self->glyphs[i].dy0; | |||
2567 | } | |||
2568 | if (self->glyphs[i].dy1 > y1) { | |||
2569 | y1 = self->glyphs[i].dy1; | |||
2570 | } | |||
2571 | glyphdata += 20; | |||
2572 | } | |||
2573 | ||||
2574 | self->baseline = -y0; | |||
2575 | self->ysize = y1 - y0; | |||
2576 | ||||
2577 | /* keep a reference to the bitmap object */ | |||
2578 | Py_INCREF(imagep)_Py_INCREF(((PyObject*)(imagep))); | |||
2579 | self->ref = imagep; | |||
2580 | ||||
2581 | return (PyObject *)self; | |||
2582 | } | |||
2583 | ||||
2584 | static void | |||
2585 | _font_dealloc(ImagingFontObject *self) { | |||
2586 | Py_XDECREF(self->ref)_Py_XDECREF(((PyObject*)(self->ref))); | |||
2587 | PyObject_DelPyObject_Free(self); | |||
2588 | } | |||
2589 | ||||
2590 | static inline int | |||
2591 | textwidth(ImagingFontObject *self, const unsigned char *text) { | |||
2592 | int xsize; | |||
2593 | ||||
2594 | for (xsize = 0; *text; text++) { | |||
2595 | xsize += self->glyphs[*text].dx; | |||
2596 | } | |||
2597 | ||||
2598 | return xsize; | |||
2599 | } | |||
2600 | ||||
2601 | void | |||
2602 | _font_text_asBytes(PyObject *encoded_string, unsigned char **text) { | |||
2603 | /* Allocates *text, returns a 'new reference'. Caller is required to free */ | |||
2604 | ||||
2605 | PyObject *bytes = NULL((void*)0); | |||
2606 | Py_ssize_t len = 0; | |||
2607 | char *buffer; | |||
2608 | ||||
2609 | *text = NULL((void*)0); | |||
2610 | ||||
2611 | if (PyUnicode_CheckExact(encoded_string)((((PyObject*)(encoded_string))->ob_type) == &PyUnicode_Type )) { | |||
2612 | bytes = PyUnicode_AsLatin1String(encoded_string); | |||
2613 | if (!bytes) { | |||
2614 | return; | |||
2615 | } | |||
2616 | PyBytes_AsStringAndSize(bytes, &buffer, &len); | |||
2617 | } else if (PyBytes_Check(encoded_string)((((((PyObject*)(encoded_string))->ob_type))->tp_flags & ((1UL << 27))) != 0)) { | |||
2618 | PyBytes_AsStringAndSize(encoded_string, &buffer, &len); | |||
2619 | } | |||
2620 | ||||
2621 | *text = calloc(len + 1, 1); | |||
2622 | if (*text) { | |||
2623 | memcpy(*text, buffer, len); | |||
2624 | } else { | |||
2625 | ImagingError_MemoryError(); | |||
2626 | } | |||
2627 | if (bytes) { | |||
2628 | Py_DECREF(bytes)_Py_DECREF(((PyObject*)(bytes))); | |||
2629 | } | |||
2630 | ||||
2631 | return; | |||
2632 | } | |||
2633 | ||||
2634 | static PyObject * | |||
2635 | _font_getmask(ImagingFontObject *self, PyObject *args) { | |||
2636 | Imaging im; | |||
2637 | Imaging bitmap; | |||
2638 | int x, b; | |||
2639 | int i = 0; | |||
2640 | int status; | |||
2641 | Glyph *glyph; | |||
2642 | ||||
2643 | PyObject *encoded_string; | |||
2644 | ||||
2645 | unsigned char *text; | |||
2646 | char *mode = ""; | |||
2647 | ||||
2648 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O|s:getmask", &encoded_string, &mode)) { | |||
2649 | return NULL((void*)0); | |||
2650 | } | |||
2651 | ||||
2652 | _font_text_asBytes(encoded_string, &text); | |||
2653 | if (!text) { | |||
2654 | return NULL((void*)0); | |||
2655 | } | |||
2656 | ||||
2657 | im = ImagingNew(self->bitmap->mode, textwidth(self, text), self->ysize); | |||
2658 | if (!im) { | |||
2659 | free(text); | |||
2660 | return ImagingError_MemoryError(); | |||
2661 | } | |||
2662 | ||||
2663 | b = 0; | |||
2664 | (void)ImagingFill(im, &b); | |||
2665 | ||||
2666 | b = self->baseline; | |||
2667 | for (x = 0; text[i]; i++) { | |||
2668 | glyph = &self->glyphs[text[i]]; | |||
2669 | bitmap = | |||
2670 | ImagingCrop(self->bitmap, glyph->sx0, glyph->sy0, glyph->sx1, glyph->sy1); | |||
2671 | if (!bitmap) { | |||
2672 | goto failed; | |||
2673 | } | |||
2674 | status = ImagingPaste( | |||
2675 | im, | |||
2676 | bitmap, | |||
2677 | NULL((void*)0), | |||
2678 | glyph->dx0 + x, | |||
2679 | glyph->dy0 + b, | |||
2680 | glyph->dx1 + x, | |||
2681 | glyph->dy1 + b); | |||
2682 | ImagingDelete(bitmap); | |||
2683 | if (status < 0) { | |||
2684 | goto failed; | |||
2685 | } | |||
2686 | x = x + glyph->dx; | |||
2687 | b = b + glyph->dy; | |||
2688 | } | |||
2689 | free(text); | |||
2690 | return PyImagingNew(im); | |||
2691 | ||||
2692 | failed: | |||
2693 | free(text); | |||
2694 | ImagingDelete(im); | |||
2695 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
2696 | } | |||
2697 | ||||
2698 | static PyObject * | |||
2699 | _font_getsize(ImagingFontObject *self, PyObject *args) { | |||
2700 | unsigned char *text; | |||
2701 | PyObject *encoded_string; | |||
2702 | PyObject *val; | |||
2703 | ||||
2704 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O:getsize", &encoded_string)) { | |||
2705 | return NULL((void*)0); | |||
2706 | } | |||
2707 | ||||
2708 | _font_text_asBytes(encoded_string, &text); | |||
2709 | if (!text) { | |||
2710 | return NULL((void*)0); | |||
2711 | } | |||
2712 | ||||
2713 | val = Py_BuildValue_Py_BuildValue_SizeT("ii", textwidth(self, text), self->ysize); | |||
2714 | free(text); | |||
2715 | return val; | |||
2716 | } | |||
2717 | ||||
2718 | static struct PyMethodDef _font_methods[] = { | |||
2719 | {"getmask", (PyCFunction)_font_getmask, METH_VARARGS0x0001}, | |||
2720 | {"getsize", (PyCFunction)_font_getsize, METH_VARARGS0x0001}, | |||
2721 | {NULL((void*)0), NULL((void*)0)} /* sentinel */ | |||
2722 | }; | |||
2723 | ||||
2724 | /* -------------------------------------------------------------------- */ | |||
2725 | ||||
2726 | static PyObject * | |||
2727 | _draw_new(PyObject *self_, PyObject *args) { | |||
2728 | ImagingDrawObject *self; | |||
2729 | ||||
2730 | ImagingObject *imagep; | |||
2731 | int blend = 0; | |||
2732 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!|i", &Imaging_Type, &imagep, &blend)) { | |||
2733 | return NULL((void*)0); | |||
2734 | } | |||
2735 | ||||
2736 | self = PyObject_New(ImagingDrawObject, &ImagingDraw_Type)( (ImagingDrawObject *) _PyObject_New(&ImagingDraw_Type) ); | |||
2737 | if (self == NULL((void*)0)) { | |||
2738 | return NULL((void*)0); | |||
2739 | } | |||
2740 | ||||
2741 | /* keep a reference to the image object */ | |||
2742 | Py_INCREF(imagep)_Py_INCREF(((PyObject*)(imagep))); | |||
2743 | self->image = imagep; | |||
2744 | ||||
2745 | self->ink[0] = self->ink[1] = self->ink[2] = self->ink[3] = 0; | |||
2746 | ||||
2747 | self->blend = blend; | |||
2748 | ||||
2749 | return (PyObject *)self; | |||
2750 | } | |||
2751 | ||||
2752 | static void | |||
2753 | _draw_dealloc(ImagingDrawObject *self) { | |||
2754 | Py_XDECREF(self->image)_Py_XDECREF(((PyObject*)(self->image))); | |||
2755 | PyObject_DelPyObject_Free(self); | |||
2756 | } | |||
2757 | ||||
2758 | extern Py_ssize_t | |||
2759 | PyPath_Flatten(PyObject *data, double **xy); | |||
2760 | ||||
2761 | static PyObject * | |||
2762 | _draw_ink(ImagingDrawObject *self, PyObject *args) { | |||
2763 | INT32int ink = 0; | |||
2764 | PyObject *color; | |||
2765 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O", &color)) { | |||
2766 | return NULL((void*)0); | |||
2767 | } | |||
2768 | ||||
2769 | if (!getink(color, self->image->image, (char *)&ink)) { | |||
2770 | return NULL((void*)0); | |||
2771 | } | |||
2772 | ||||
2773 | return PyLong_FromLong((int)ink); | |||
2774 | } | |||
2775 | ||||
2776 | static PyObject * | |||
2777 | _draw_arc(ImagingDrawObject *self, PyObject *args) { | |||
2778 | double *xy; | |||
2779 | Py_ssize_t n; | |||
2780 | ||||
2781 | PyObject *data; | |||
2782 | int ink; | |||
2783 | int width = 0; | |||
2784 | float start, end; | |||
2785 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Offi|i", &data, &start, &end, &ink, &width)) { | |||
2786 | return NULL((void*)0); | |||
2787 | } | |||
2788 | ||||
2789 | n = PyPath_Flatten(data, &xy); | |||
2790 | if (n < 0) { | |||
2791 | return NULL((void*)0); | |||
2792 | } | |||
2793 | if (n != 2) { | |||
2794 | PyErr_SetString(PyExc_TypeError, must_be_two_coordinates); | |||
2795 | free(xy); | |||
2796 | return NULL((void*)0); | |||
2797 | } | |||
2798 | ||||
2799 | n = ImagingDrawArc( | |||
2800 | self->image->image, | |||
2801 | (int)xy[0], | |||
2802 | (int)xy[1], | |||
2803 | (int)xy[2], | |||
2804 | (int)xy[3], | |||
2805 | start, | |||
2806 | end, | |||
2807 | &ink, | |||
2808 | width, | |||
2809 | self->blend); | |||
2810 | ||||
2811 | free(xy); | |||
2812 | ||||
2813 | if (n < 0) { | |||
2814 | return NULL((void*)0); | |||
2815 | } | |||
2816 | ||||
2817 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2818 | return Py_None(&_Py_NoneStruct); | |||
2819 | } | |||
2820 | ||||
2821 | static PyObject * | |||
2822 | _draw_bitmap(ImagingDrawObject *self, PyObject *args) { | |||
2823 | double *xy; | |||
2824 | Py_ssize_t n; | |||
2825 | ||||
2826 | PyObject *data; | |||
2827 | ImagingObject *bitmap; | |||
2828 | int ink; | |||
2829 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "OO!i", &data, &Imaging_Type, &bitmap, &ink)) { | |||
2830 | return NULL((void*)0); | |||
2831 | } | |||
2832 | ||||
2833 | n = PyPath_Flatten(data, &xy); | |||
2834 | if (n < 0) { | |||
2835 | return NULL((void*)0); | |||
2836 | } | |||
2837 | if (n != 1) { | |||
2838 | PyErr_SetString( | |||
2839 | PyExc_TypeError, "coordinate list must contain exactly 1 coordinate"); | |||
2840 | free(xy); | |||
2841 | return NULL((void*)0); | |||
2842 | } | |||
2843 | ||||
2844 | n = ImagingDrawBitmap( | |||
2845 | self->image->image, (int)xy[0], (int)xy[1], bitmap->image, &ink, self->blend); | |||
2846 | ||||
2847 | free(xy); | |||
2848 | ||||
2849 | if (n < 0) { | |||
2850 | return NULL((void*)0); | |||
2851 | } | |||
2852 | ||||
2853 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2854 | return Py_None(&_Py_NoneStruct); | |||
2855 | } | |||
2856 | ||||
2857 | static PyObject * | |||
2858 | _draw_chord(ImagingDrawObject *self, PyObject *args) { | |||
2859 | double *xy; | |||
2860 | Py_ssize_t n; | |||
2861 | ||||
2862 | PyObject *data; | |||
2863 | int ink, fill; | |||
2864 | int width = 0; | |||
2865 | float start, end; | |||
2866 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Offii|i", &data, &start, &end, &ink, &fill, &width)) { | |||
2867 | return NULL((void*)0); | |||
2868 | } | |||
2869 | ||||
2870 | n = PyPath_Flatten(data, &xy); | |||
2871 | if (n < 0) { | |||
2872 | return NULL((void*)0); | |||
2873 | } | |||
2874 | if (n != 2) { | |||
2875 | PyErr_SetString(PyExc_TypeError, must_be_two_coordinates); | |||
2876 | free(xy); | |||
2877 | return NULL((void*)0); | |||
2878 | } | |||
2879 | ||||
2880 | n = ImagingDrawChord( | |||
2881 | self->image->image, | |||
2882 | (int)xy[0], | |||
2883 | (int)xy[1], | |||
2884 | (int)xy[2], | |||
2885 | (int)xy[3], | |||
2886 | start, | |||
2887 | end, | |||
2888 | &ink, | |||
2889 | fill, | |||
2890 | width, | |||
2891 | self->blend); | |||
2892 | ||||
2893 | free(xy); | |||
2894 | ||||
2895 | if (n < 0) { | |||
2896 | return NULL((void*)0); | |||
2897 | } | |||
2898 | ||||
2899 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2900 | return Py_None(&_Py_NoneStruct); | |||
2901 | } | |||
2902 | ||||
2903 | static PyObject * | |||
2904 | _draw_ellipse(ImagingDrawObject *self, PyObject *args) { | |||
2905 | double *xy; | |||
2906 | Py_ssize_t n; | |||
2907 | ||||
2908 | PyObject *data; | |||
2909 | int ink; | |||
2910 | int fill = 0; | |||
2911 | int width = 0; | |||
2912 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oi|ii", &data, &ink, &fill, &width)) { | |||
2913 | return NULL((void*)0); | |||
2914 | } | |||
2915 | ||||
2916 | n = PyPath_Flatten(data, &xy); | |||
2917 | if (n < 0) { | |||
2918 | return NULL((void*)0); | |||
2919 | } | |||
2920 | if (n != 2) { | |||
2921 | PyErr_SetString(PyExc_TypeError, must_be_two_coordinates); | |||
2922 | free(xy); | |||
2923 | return NULL((void*)0); | |||
2924 | } | |||
2925 | ||||
2926 | n = ImagingDrawEllipse( | |||
2927 | self->image->image, | |||
2928 | (int)xy[0], | |||
2929 | (int)xy[1], | |||
2930 | (int)xy[2], | |||
2931 | (int)xy[3], | |||
2932 | &ink, | |||
2933 | fill, | |||
2934 | width, | |||
2935 | self->blend); | |||
2936 | ||||
2937 | free(xy); | |||
2938 | ||||
2939 | if (n < 0) { | |||
2940 | return NULL((void*)0); | |||
2941 | } | |||
2942 | ||||
2943 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
2944 | return Py_None(&_Py_NoneStruct); | |||
2945 | } | |||
2946 | ||||
2947 | static PyObject * | |||
2948 | _draw_lines(ImagingDrawObject *self, PyObject *args) { | |||
2949 | double *xy; | |||
2950 | Py_ssize_t i, n; | |||
2951 | ||||
2952 | PyObject *data; | |||
2953 | int ink; | |||
2954 | int width = 0; | |||
2955 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oi|i", &data, &ink, &width)) { | |||
2956 | return NULL((void*)0); | |||
2957 | } | |||
2958 | ||||
2959 | n = PyPath_Flatten(data, &xy); | |||
2960 | if (n < 0) { | |||
2961 | return NULL((void*)0); | |||
2962 | } | |||
2963 | ||||
2964 | if (width <= 1) { | |||
2965 | double *p = NULL((void*)0); | |||
2966 | for (i = 0; i < n - 1; i++) { | |||
2967 | p = &xy[i + i]; | |||
2968 | if (ImagingDrawLine( | |||
2969 | self->image->image, | |||
2970 | (int)p[0], | |||
2971 | (int)p[1], | |||
2972 | (int)p[2], | |||
2973 | (int)p[3], | |||
2974 | &ink, | |||
2975 | self->blend) < 0) { | |||
2976 | free(xy); | |||
2977 | return NULL((void*)0); | |||
2978 | } | |||
2979 | } | |||
2980 | if (p) { /* draw last point */ | |||
2981 | ImagingDrawPoint( | |||
2982 | self->image->image, (int)p[2], (int)p[3], &ink, self->blend); | |||
2983 | } | |||
2984 | } else { | |||
2985 | for (i = 0; i < n - 1; i++) { | |||
2986 | double *p = &xy[i + i]; | |||
2987 | if (ImagingDrawWideLine( | |||
2988 | self->image->image, | |||
2989 | (int)p[0], | |||
2990 | (int)p[1], | |||
2991 | (int)p[2], | |||
2992 | (int)p[3], | |||
2993 | &ink, | |||
2994 | width, | |||
2995 | self->blend) < 0) { | |||
2996 | free(xy); | |||
2997 | return NULL((void*)0); | |||
2998 | } | |||
2999 | } | |||
3000 | } | |||
3001 | ||||
3002 | free(xy); | |||
3003 | ||||
3004 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3005 | return Py_None(&_Py_NoneStruct); | |||
3006 | } | |||
3007 | ||||
3008 | static PyObject * | |||
3009 | _draw_points(ImagingDrawObject *self, PyObject *args) { | |||
3010 | double *xy; | |||
3011 | Py_ssize_t i, n; | |||
3012 | ||||
3013 | PyObject *data; | |||
3014 | int ink; | |||
3015 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oi", &data, &ink)) { | |||
3016 | return NULL((void*)0); | |||
3017 | } | |||
3018 | ||||
3019 | n = PyPath_Flatten(data, &xy); | |||
3020 | if (n < 0) { | |||
3021 | return NULL((void*)0); | |||
3022 | } | |||
3023 | ||||
3024 | for (i = 0; i < n; i++) { | |||
3025 | double *p = &xy[i + i]; | |||
3026 | if (ImagingDrawPoint( | |||
3027 | self->image->image, (int)p[0], (int)p[1], &ink, self->blend) < 0) { | |||
3028 | free(xy); | |||
3029 | return NULL((void*)0); | |||
3030 | } | |||
3031 | } | |||
3032 | ||||
3033 | free(xy); | |||
3034 | ||||
3035 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3036 | return Py_None(&_Py_NoneStruct); | |||
3037 | } | |||
3038 | ||||
3039 | #ifdef WITH_ARROW | |||
3040 | ||||
3041 | /* from outline.c */ | |||
3042 | extern ImagingOutline | |||
3043 | PyOutline_AsOutline(PyObject *outline); | |||
3044 | ||||
3045 | static PyObject * | |||
3046 | _draw_outline(ImagingDrawObject *self, PyObject *args) { | |||
3047 | ImagingOutline outline; | |||
3048 | ||||
3049 | PyObject *outline_; | |||
3050 | int ink; | |||
3051 | int fill = 0; | |||
3052 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oi|i", &outline_, &ink, &fill)) { | |||
3053 | return NULL((void*)0); | |||
3054 | } | |||
3055 | ||||
3056 | outline = PyOutline_AsOutline(outline_); | |||
3057 | if (!outline) { | |||
3058 | PyErr_SetString(PyExc_TypeError, "expected outline object"); | |||
3059 | return NULL((void*)0); | |||
3060 | } | |||
3061 | ||||
3062 | if (ImagingDrawOutline(self->image->image, outline, &ink, fill, self->blend) < 0) { | |||
3063 | return NULL((void*)0); | |||
3064 | } | |||
3065 | ||||
3066 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3067 | return Py_None(&_Py_NoneStruct); | |||
3068 | } | |||
3069 | ||||
3070 | #endif | |||
3071 | ||||
3072 | static PyObject * | |||
3073 | _draw_pieslice(ImagingDrawObject *self, PyObject *args) { | |||
3074 | double *xy; | |||
3075 | Py_ssize_t n; | |||
3076 | ||||
3077 | PyObject *data; | |||
3078 | int ink, fill; | |||
3079 | int width = 0; | |||
3080 | float start, end; | |||
3081 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Offii|i", &data, &start, &end, &ink, &fill, &width)) { | |||
3082 | return NULL((void*)0); | |||
3083 | } | |||
3084 | ||||
3085 | n = PyPath_Flatten(data, &xy); | |||
3086 | if (n < 0) { | |||
3087 | return NULL((void*)0); | |||
3088 | } | |||
3089 | if (n != 2) { | |||
3090 | PyErr_SetString(PyExc_TypeError, must_be_two_coordinates); | |||
3091 | free(xy); | |||
3092 | return NULL((void*)0); | |||
3093 | } | |||
3094 | ||||
3095 | n = ImagingDrawPieslice( | |||
3096 | self->image->image, | |||
3097 | (int)xy[0], | |||
3098 | (int)xy[1], | |||
3099 | (int)xy[2], | |||
3100 | (int)xy[3], | |||
3101 | start, | |||
3102 | end, | |||
3103 | &ink, | |||
3104 | fill, | |||
3105 | width, | |||
3106 | self->blend); | |||
3107 | ||||
3108 | free(xy); | |||
3109 | ||||
3110 | if (n < 0) { | |||
3111 | return NULL((void*)0); | |||
3112 | } | |||
3113 | ||||
3114 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3115 | return Py_None(&_Py_NoneStruct); | |||
3116 | } | |||
3117 | ||||
3118 | static PyObject * | |||
3119 | _draw_polygon(ImagingDrawObject *self, PyObject *args) { | |||
3120 | double *xy; | |||
3121 | int *ixy; | |||
3122 | Py_ssize_t n, i; | |||
3123 | ||||
3124 | PyObject *data; | |||
3125 | int ink; | |||
3126 | int fill = 0; | |||
3127 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oi|i", &data, &ink, &fill)) { | |||
3128 | return NULL((void*)0); | |||
3129 | } | |||
3130 | ||||
3131 | n = PyPath_Flatten(data, &xy); | |||
3132 | if (n < 0) { | |||
3133 | return NULL((void*)0); | |||
3134 | } | |||
3135 | if (n < 2) { | |||
3136 | PyErr_SetString( | |||
3137 | PyExc_TypeError, "coordinate list must contain at least 2 coordinates"); | |||
3138 | free(xy); | |||
3139 | return NULL((void*)0); | |||
3140 | } | |||
3141 | ||||
3142 | /* Copy list of vertices to array */ | |||
3143 | ixy = (int *)calloc(n, 2 * sizeof(int)); | |||
3144 | if (ixy == NULL((void*)0)) { | |||
3145 | free(xy); | |||
3146 | return ImagingError_MemoryError(); | |||
3147 | } | |||
3148 | ||||
3149 | for (i = 0; i < n; i++) { | |||
3150 | ixy[i + i] = (int)xy[i + i]; | |||
3151 | ixy[i + i + 1] = (int)xy[i + i + 1]; | |||
3152 | } | |||
3153 | ||||
3154 | free(xy); | |||
3155 | ||||
3156 | if (ImagingDrawPolygon(self->image->image, n, ixy, &ink, fill, self->blend) < 0) { | |||
3157 | free(ixy); | |||
3158 | return NULL((void*)0); | |||
3159 | } | |||
3160 | ||||
3161 | free(ixy); | |||
3162 | ||||
3163 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3164 | return Py_None(&_Py_NoneStruct); | |||
3165 | } | |||
3166 | ||||
3167 | static PyObject * | |||
3168 | _draw_rectangle(ImagingDrawObject *self, PyObject *args) { | |||
3169 | double *xy; | |||
3170 | Py_ssize_t n; | |||
3171 | ||||
3172 | PyObject *data; | |||
3173 | int ink; | |||
3174 | int fill = 0; | |||
3175 | int width = 0; | |||
3176 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "Oi|ii", &data, &ink, &fill, &width)) { | |||
3177 | return NULL((void*)0); | |||
3178 | } | |||
3179 | ||||
3180 | n = PyPath_Flatten(data, &xy); | |||
3181 | if (n < 0) { | |||
3182 | return NULL((void*)0); | |||
3183 | } | |||
3184 | if (n != 2) { | |||
3185 | PyErr_SetString(PyExc_TypeError, must_be_two_coordinates); | |||
3186 | free(xy); | |||
3187 | return NULL((void*)0); | |||
3188 | } | |||
3189 | ||||
3190 | n = ImagingDrawRectangle( | |||
3191 | self->image->image, | |||
3192 | (int)xy[0], | |||
3193 | (int)xy[1], | |||
3194 | (int)xy[2], | |||
3195 | (int)xy[3], | |||
3196 | &ink, | |||
3197 | fill, | |||
3198 | width, | |||
3199 | self->blend); | |||
3200 | ||||
3201 | free(xy); | |||
3202 | ||||
3203 | if (n < 0) { | |||
3204 | return NULL((void*)0); | |||
3205 | } | |||
3206 | ||||
3207 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3208 | return Py_None(&_Py_NoneStruct); | |||
3209 | } | |||
3210 | ||||
3211 | static struct PyMethodDef _draw_methods[] = { | |||
3212 | #ifdef WITH_IMAGEDRAW | |||
3213 | /* Graphics (ImageDraw) */ | |||
3214 | {"draw_lines", (PyCFunction)_draw_lines, METH_VARARGS0x0001}, | |||
3215 | #ifdef WITH_ARROW | |||
3216 | {"draw_outline", (PyCFunction)_draw_outline, METH_VARARGS0x0001}, | |||
3217 | #endif | |||
3218 | {"draw_polygon", (PyCFunction)_draw_polygon, METH_VARARGS0x0001}, | |||
3219 | {"draw_rectangle", (PyCFunction)_draw_rectangle, METH_VARARGS0x0001}, | |||
3220 | {"draw_points", (PyCFunction)_draw_points, METH_VARARGS0x0001}, | |||
3221 | {"draw_arc", (PyCFunction)_draw_arc, METH_VARARGS0x0001}, | |||
3222 | {"draw_bitmap", (PyCFunction)_draw_bitmap, METH_VARARGS0x0001}, | |||
3223 | {"draw_chord", (PyCFunction)_draw_chord, METH_VARARGS0x0001}, | |||
3224 | {"draw_ellipse", (PyCFunction)_draw_ellipse, METH_VARARGS0x0001}, | |||
3225 | {"draw_pieslice", (PyCFunction)_draw_pieslice, METH_VARARGS0x0001}, | |||
3226 | {"draw_ink", (PyCFunction)_draw_ink, METH_VARARGS0x0001}, | |||
3227 | #endif | |||
3228 | {NULL((void*)0), NULL((void*)0)} /* sentinel */ | |||
3229 | }; | |||
3230 | ||||
3231 | #endif | |||
3232 | ||||
3233 | static PyObject * | |||
3234 | pixel_access_new(ImagingObject *imagep, PyObject *args) { | |||
3235 | PixelAccessObject *self; | |||
3236 | ||||
3237 | int readonly = 0; | |||
3238 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|i", &readonly)) { | |||
3239 | return NULL((void*)0); | |||
3240 | } | |||
3241 | ||||
3242 | self = PyObject_New(PixelAccessObject, &PixelAccess_Type)( (PixelAccessObject *) _PyObject_New(&PixelAccess_Type) ); | |||
3243 | if (self == NULL((void*)0)) { | |||
3244 | return NULL((void*)0); | |||
3245 | } | |||
3246 | ||||
3247 | /* keep a reference to the image object */ | |||
3248 | Py_INCREF(imagep)_Py_INCREF(((PyObject*)(imagep))); | |||
3249 | self->image = imagep; | |||
3250 | ||||
3251 | self->readonly = readonly; | |||
3252 | ||||
3253 | return (PyObject *)self; | |||
3254 | } | |||
3255 | ||||
3256 | static void | |||
3257 | pixel_access_dealloc(PixelAccessObject *self) { | |||
3258 | Py_XDECREF(self->image)_Py_XDECREF(((PyObject*)(self->image))); | |||
3259 | PyObject_DelPyObject_Free(self); | |||
3260 | } | |||
3261 | ||||
3262 | static PyObject * | |||
3263 | pixel_access_getitem(PixelAccessObject *self, PyObject *xy) { | |||
3264 | int x, y; | |||
3265 | if (_getxy(xy, &x, &y)) { | |||
3266 | return NULL((void*)0); | |||
3267 | } | |||
3268 | ||||
3269 | return getpixel(self->image->image, self->image->access, x, y); | |||
3270 | } | |||
3271 | ||||
3272 | static int | |||
3273 | pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color) { | |||
3274 | Imaging im = self->image->image; | |||
3275 | char ink[4]; | |||
3276 | int x, y; | |||
3277 | ||||
3278 | if (self->readonly) { | |||
3279 | (void)ImagingError_ValueError(readonly); | |||
3280 | return -1; | |||
3281 | } | |||
3282 | ||||
3283 | if (_getxy(xy, &x, &y)) { | |||
3284 | return -1; | |||
3285 | } | |||
3286 | ||||
3287 | if (x < 0) { | |||
3288 | x = im->xsize + x; | |||
3289 | } | |||
3290 | if (y < 0) { | |||
3291 | y = im->ysize + y; | |||
3292 | } | |||
3293 | ||||
3294 | if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) { | |||
3295 | PyErr_SetString(PyExc_IndexError, outside_image); | |||
3296 | return -1; | |||
3297 | } | |||
3298 | ||||
3299 | if (!color) { /* FIXME: raise exception? */ | |||
3300 | return 0; | |||
3301 | } | |||
3302 | ||||
3303 | if (!getink(color, im, ink)) { | |||
3304 | return -1; | |||
3305 | } | |||
3306 | ||||
3307 | self->image->access->put_pixel(im, x, y, ink); | |||
3308 | ||||
3309 | return 0; | |||
3310 | } | |||
3311 | ||||
3312 | /* -------------------------------------------------------------------- */ | |||
3313 | /* EFFECTS (experimental) */ | |||
3314 | /* -------------------------------------------------------------------- */ | |||
3315 | ||||
3316 | #ifdef WITH_EFFECTS | |||
3317 | ||||
3318 | static PyObject * | |||
3319 | _effect_mandelbrot(ImagingObject *self, PyObject *args) { | |||
3320 | int xsize = 512; | |||
3321 | int ysize = 512; | |||
3322 | double extent[4]; | |||
3323 | int quality = 100; | |||
3324 | ||||
3325 | extent[0] = -3; | |||
3326 | extent[1] = -2.5; | |||
3327 | extent[2] = 2; | |||
3328 | extent[3] = 2.5; | |||
3329 | ||||
3330 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT( | |||
3331 | args, | |||
3332 | "|(ii)(dddd)i", | |||
3333 | &xsize, | |||
3334 | &ysize, | |||
3335 | &extent[0], | |||
3336 | &extent[1], | |||
3337 | &extent[2], | |||
3338 | &extent[3], | |||
3339 | &quality)) { | |||
3340 | return NULL((void*)0); | |||
3341 | } | |||
3342 | ||||
3343 | return PyImagingNew(ImagingEffectMandelbrot(xsize, ysize, extent, quality)); | |||
3344 | } | |||
3345 | ||||
3346 | static PyObject * | |||
3347 | _effect_noise(ImagingObject *self, PyObject *args) { | |||
3348 | int xsize, ysize; | |||
3349 | float sigma = 128; | |||
3350 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "(ii)|f", &xsize, &ysize, &sigma)) { | |||
3351 | return NULL((void*)0); | |||
3352 | } | |||
3353 | ||||
3354 | return PyImagingNew(ImagingEffectNoise(xsize, ysize, sigma)); | |||
3355 | } | |||
3356 | ||||
3357 | static PyObject * | |||
3358 | _effect_spread(ImagingObject *self, PyObject *args) { | |||
3359 | int dist; | |||
3360 | ||||
3361 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i", &dist)) { | |||
3362 | return NULL((void*)0); | |||
3363 | } | |||
3364 | ||||
3365 | return PyImagingNew(ImagingEffectSpread(self->image, dist)); | |||
3366 | } | |||
3367 | ||||
3368 | #endif | |||
3369 | ||||
3370 | /* -------------------------------------------------------------------- */ | |||
3371 | /* UTILITIES */ | |||
3372 | /* -------------------------------------------------------------------- */ | |||
3373 | ||||
3374 | static PyObject * | |||
3375 | _getcodecstatus(PyObject *self, PyObject *args) { | |||
3376 | int status; | |||
3377 | char *msg; | |||
3378 | ||||
3379 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i", &status)) { | |||
3380 | return NULL((void*)0); | |||
3381 | } | |||
3382 | ||||
3383 | switch (status) { | |||
3384 | case IMAGING_CODEC_OVERRUN-1: | |||
3385 | msg = "buffer overrun"; | |||
3386 | break; | |||
3387 | case IMAGING_CODEC_BROKEN-2: | |||
3388 | msg = "broken data stream"; | |||
3389 | break; | |||
3390 | case IMAGING_CODEC_UNKNOWN-3: | |||
3391 | msg = "unrecognized data stream contents"; | |||
3392 | break; | |||
3393 | case IMAGING_CODEC_CONFIG-8: | |||
3394 | msg = "codec configuration error"; | |||
3395 | break; | |||
3396 | case IMAGING_CODEC_MEMORY-9: | |||
3397 | msg = "out of memory"; | |||
3398 | break; | |||
3399 | default: | |||
3400 | Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (& _Py_NoneStruct); | |||
3401 | } | |||
3402 | ||||
3403 | return PyUnicode_FromString(msg); | |||
3404 | } | |||
3405 | ||||
3406 | /* -------------------------------------------------------------------- */ | |||
3407 | /* DEBUGGING HELPERS */ | |||
3408 | /* -------------------------------------------------------------------- */ | |||
3409 | ||||
3410 | static PyObject * | |||
3411 | _save_ppm(ImagingObject *self, PyObject *args) { | |||
3412 | char *filename; | |||
3413 | ||||
3414 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s", &filename)) { | |||
3415 | return NULL((void*)0); | |||
3416 | } | |||
3417 | ||||
3418 | if (!ImagingSavePPM(self->image, filename)) { | |||
3419 | return NULL((void*)0); | |||
3420 | } | |||
3421 | ||||
3422 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3423 | return Py_None(&_Py_NoneStruct); | |||
3424 | } | |||
3425 | ||||
3426 | /* -------------------------------------------------------------------- */ | |||
3427 | ||||
3428 | /* methods */ | |||
3429 | ||||
3430 | static struct PyMethodDef methods[] = { | |||
3431 | ||||
3432 | /* Put commonly used methods first */ | |||
3433 | {"getpixel", (PyCFunction)_getpixel, METH_VARARGS0x0001}, | |||
3434 | {"putpixel", (PyCFunction)_putpixel, METH_VARARGS0x0001}, | |||
3435 | ||||
3436 | {"pixel_access", (PyCFunction)pixel_access_new, METH_VARARGS0x0001}, | |||
3437 | ||||
3438 | /* Standard processing methods (Image) */ | |||
3439 | {"color_lut_3d", (PyCFunction)_color_lut_3d, METH_VARARGS0x0001}, | |||
3440 | {"convert", (PyCFunction)_convert, METH_VARARGS0x0001}, | |||
3441 | {"convert2", (PyCFunction)_convert2, METH_VARARGS0x0001}, | |||
3442 | {"convert_matrix", (PyCFunction)_convert_matrix, METH_VARARGS0x0001}, | |||
3443 | {"convert_transparent", (PyCFunction)_convert_transparent, METH_VARARGS0x0001}, | |||
3444 | {"copy", (PyCFunction)_copy, METH_VARARGS0x0001}, | |||
3445 | {"crop", (PyCFunction)_crop, METH_VARARGS0x0001}, | |||
3446 | {"expand", (PyCFunction)_expand_image, METH_VARARGS0x0001}, | |||
3447 | {"filter", (PyCFunction)_filter, METH_VARARGS0x0001}, | |||
3448 | {"histogram", (PyCFunction)_histogram, METH_VARARGS0x0001}, | |||
3449 | {"entropy", (PyCFunction)_entropy, METH_VARARGS0x0001}, | |||
3450 | #ifdef WITH_MODEFILTER | |||
3451 | {"modefilter", (PyCFunction)_modefilter, METH_VARARGS0x0001}, | |||
3452 | #endif | |||
3453 | {"offset", (PyCFunction)_offset, METH_VARARGS0x0001}, | |||
3454 | {"paste", (PyCFunction)_paste, METH_VARARGS0x0001}, | |||
3455 | {"point", (PyCFunction)_point, METH_VARARGS0x0001}, | |||
3456 | {"point_transform", (PyCFunction)_point_transform, METH_VARARGS0x0001}, | |||
3457 | {"putdata", (PyCFunction)_putdata, METH_VARARGS0x0001}, | |||
3458 | #ifdef WITH_QUANTIZE | |||
3459 | {"quantize", (PyCFunction)_quantize, METH_VARARGS0x0001}, | |||
3460 | #endif | |||
3461 | #ifdef WITH_RANKFILTER | |||
3462 | {"rankfilter", (PyCFunction)_rankfilter, METH_VARARGS0x0001}, | |||
3463 | #endif | |||
3464 | {"resize", (PyCFunction)_resize, METH_VARARGS0x0001}, | |||
3465 | {"reduce", (PyCFunction)_reduce, METH_VARARGS0x0001}, | |||
3466 | {"transpose", (PyCFunction)_transpose, METH_VARARGS0x0001}, | |||
3467 | {"transform2", (PyCFunction)_transform2, METH_VARARGS0x0001}, | |||
3468 | ||||
3469 | {"isblock", (PyCFunction)_isblock, METH_NOARGS0x0004}, | |||
3470 | ||||
3471 | {"getbbox", (PyCFunction)_getbbox, METH_NOARGS0x0004}, | |||
3472 | {"getcolors", (PyCFunction)_getcolors, METH_VARARGS0x0001}, | |||
3473 | {"getextrema", (PyCFunction)_getextrema, METH_NOARGS0x0004}, | |||
3474 | {"getprojection", (PyCFunction)_getprojection, METH_NOARGS0x0004}, | |||
3475 | ||||
3476 | {"getband", (PyCFunction)_getband, METH_VARARGS0x0001}, | |||
3477 | {"putband", (PyCFunction)_putband, METH_VARARGS0x0001}, | |||
3478 | {"split", (PyCFunction)_split, METH_NOARGS0x0004}, | |||
3479 | {"fillband", (PyCFunction)_fillband, METH_VARARGS0x0001}, | |||
3480 | ||||
3481 | {"setmode", (PyCFunction)im_setmode, METH_VARARGS0x0001}, | |||
3482 | ||||
3483 | {"getpalette", (PyCFunction)_getpalette, METH_VARARGS0x0001}, | |||
3484 | {"getpalettemode", (PyCFunction)_getpalettemode, METH_NOARGS0x0004}, | |||
3485 | {"putpalette", (PyCFunction)_putpalette, METH_VARARGS0x0001}, | |||
3486 | {"putpalettealpha", (PyCFunction)_putpalettealpha, METH_VARARGS0x0001}, | |||
3487 | {"putpalettealphas", (PyCFunction)_putpalettealphas, METH_VARARGS0x0001}, | |||
3488 | ||||
3489 | #ifdef WITH_IMAGECHOPS | |||
3490 | /* Channel operations (ImageChops) */ | |||
3491 | {"chop_invert", (PyCFunction)_chop_invert, METH_NOARGS0x0004}, | |||
3492 | {"chop_lighter", (PyCFunction)_chop_lighter, METH_VARARGS0x0001}, | |||
3493 | {"chop_darker", (PyCFunction)_chop_darker, METH_VARARGS0x0001}, | |||
3494 | {"chop_difference", (PyCFunction)_chop_difference, METH_VARARGS0x0001}, | |||
3495 | {"chop_multiply", (PyCFunction)_chop_multiply, METH_VARARGS0x0001}, | |||
3496 | {"chop_screen", (PyCFunction)_chop_screen, METH_VARARGS0x0001}, | |||
3497 | {"chop_add", (PyCFunction)_chop_add, METH_VARARGS0x0001}, | |||
3498 | {"chop_subtract", (PyCFunction)_chop_subtract, METH_VARARGS0x0001}, | |||
3499 | {"chop_add_modulo", (PyCFunction)_chop_add_modulo, METH_VARARGS0x0001}, | |||
3500 | {"chop_subtract_modulo", (PyCFunction)_chop_subtract_modulo, METH_VARARGS0x0001}, | |||
3501 | {"chop_and", (PyCFunction)_chop_and, METH_VARARGS0x0001}, | |||
3502 | {"chop_or", (PyCFunction)_chop_or, METH_VARARGS0x0001}, | |||
3503 | {"chop_xor", (PyCFunction)_chop_xor, METH_VARARGS0x0001}, | |||
3504 | {"chop_soft_light", (PyCFunction)_chop_soft_light, METH_VARARGS0x0001}, | |||
3505 | {"chop_hard_light", (PyCFunction)_chop_hard_light, METH_VARARGS0x0001}, | |||
3506 | {"chop_overlay", (PyCFunction)_chop_overlay, METH_VARARGS0x0001}, | |||
3507 | ||||
3508 | #endif | |||
3509 | ||||
3510 | #ifdef WITH_UNSHARPMASK | |||
3511 | /* Kevin Cazabon's unsharpmask extension */ | |||
3512 | {"gaussian_blur", (PyCFunction)_gaussian_blur, METH_VARARGS0x0001}, | |||
3513 | {"unsharp_mask", (PyCFunction)_unsharp_mask, METH_VARARGS0x0001}, | |||
3514 | #endif | |||
3515 | ||||
3516 | {"box_blur", (PyCFunction)_box_blur, METH_VARARGS0x0001}, | |||
3517 | ||||
3518 | #ifdef WITH_EFFECTS | |||
3519 | /* Special effects */ | |||
3520 | {"effect_spread", (PyCFunction)_effect_spread, METH_VARARGS0x0001}, | |||
3521 | #endif | |||
3522 | ||||
3523 | /* Misc. */ | |||
3524 | {"new_block", (PyCFunction)_new_block, METH_VARARGS0x0001}, | |||
3525 | ||||
3526 | {"save_ppm", (PyCFunction)_save_ppm, METH_VARARGS0x0001}, | |||
3527 | ||||
3528 | {NULL((void*)0), NULL((void*)0)} /* sentinel */ | |||
3529 | }; | |||
3530 | ||||
3531 | /* attributes */ | |||
3532 | ||||
3533 | static PyObject * | |||
3534 | _getattr_mode(ImagingObject *self, void *closure) { | |||
3535 | return PyUnicode_FromString(self->image->mode); | |||
3536 | } | |||
3537 | ||||
3538 | static PyObject * | |||
3539 | _getattr_size(ImagingObject *self, void *closure) { | |||
3540 | return Py_BuildValue_Py_BuildValue_SizeT("ii", self->image->xsize, self->image->ysize); | |||
3541 | } | |||
3542 | ||||
3543 | static PyObject * | |||
3544 | _getattr_bands(ImagingObject *self, void *closure) { | |||
3545 | return PyLong_FromLong(self->image->bands); | |||
3546 | } | |||
3547 | ||||
3548 | static PyObject * | |||
3549 | _getattr_id(ImagingObject *self, void *closure) { | |||
3550 | return PyLong_FromSsize_t((Py_ssize_t)self->image); | |||
3551 | } | |||
3552 | ||||
3553 | static PyObject * | |||
3554 | _getattr_ptr(ImagingObject *self, void *closure) { | |||
3555 | return PyCapsule_New(self->image, IMAGING_MAGIC"PIL Imaging", NULL((void*)0)); | |||
3556 | } | |||
3557 | ||||
3558 | static PyObject * | |||
3559 | _getattr_unsafe_ptrs(ImagingObject *self, void *closure) { | |||
3560 | return Py_BuildValue_Py_BuildValue_SizeT( | |||
3561 | "(sn)(sn)(sn)", | |||
3562 | "image8", | |||
3563 | self->image->image8, | |||
3564 | "image32", | |||
3565 | self->image->image32, | |||
3566 | "image", | |||
3567 | self->image->image); | |||
3568 | }; | |||
3569 | ||||
3570 | static struct PyGetSetDef getsetters[] = { | |||
3571 | {"mode", (getter)_getattr_mode}, | |||
3572 | {"size", (getter)_getattr_size}, | |||
3573 | {"bands", (getter)_getattr_bands}, | |||
3574 | {"id", (getter)_getattr_id}, | |||
3575 | {"ptr", (getter)_getattr_ptr}, | |||
3576 | {"unsafe_ptrs", (getter)_getattr_unsafe_ptrs}, | |||
3577 | {NULL((void*)0)}}; | |||
3578 | ||||
3579 | /* basic sequence semantics */ | |||
3580 | ||||
3581 | static Py_ssize_t | |||
3582 | image_length(ImagingObject *self) { | |||
3583 | Imaging im = self->image; | |||
3584 | ||||
3585 | return (Py_ssize_t)im->xsize * im->ysize; | |||
3586 | } | |||
3587 | ||||
3588 | static PyObject * | |||
3589 | image_item(ImagingObject *self, Py_ssize_t i) { | |||
3590 | int x, y; | |||
3591 | Imaging im = self->image; | |||
3592 | ||||
3593 | if (im->xsize > 0) { | |||
3594 | x = i % im->xsize; | |||
3595 | y = i / im->xsize; | |||
3596 | } else { | |||
3597 | x = y = 0; /* leave it to getpixel to raise an exception */ | |||
3598 | } | |||
3599 | ||||
3600 | return getpixel(im, self->access, x, y); | |||
3601 | } | |||
3602 | ||||
3603 | static PySequenceMethods image_as_sequence = { | |||
3604 | (lenfunc)image_length, /*sq_length*/ | |||
3605 | (binaryfunc)NULL((void*)0), /*sq_concat*/ | |||
3606 | (ssizeargfunc)NULL((void*)0), /*sq_repeat*/ | |||
3607 | (ssizeargfunc)image_item, /*sq_item*/ | |||
3608 | (ssizessizeargfunc)NULL((void*)0), /*sq_slice*/ | |||
3609 | (ssizeobjargproc)NULL((void*)0), /*sq_ass_item*/ | |||
3610 | (ssizessizeobjargproc)NULL((void*)0), /*sq_ass_slice*/ | |||
3611 | }; | |||
3612 | ||||
3613 | /* type description */ | |||
3614 | ||||
3615 | static PyTypeObject Imaging_Type = { | |||
3616 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, "ImagingCore", /*tp_name*/ | |||
3617 | sizeof(ImagingObject), /*tp_size*/ | |||
3618 | 0, /*tp_itemsize*/ | |||
3619 | /* methods */ | |||
3620 | (destructor)_dealloc, /*tp_dealloc*/ | |||
3621 | 0, /*tp_print*/ | |||
3622 | 0, /*tp_getattr*/ | |||
3623 | 0, /*tp_setattr*/ | |||
3624 | 0, /*tp_compare*/ | |||
3625 | 0, /*tp_repr*/ | |||
3626 | 0, /*tp_as_number */ | |||
3627 | &image_as_sequence, /*tp_as_sequence */ | |||
3628 | 0, /*tp_as_mapping */ | |||
3629 | 0, /*tp_hash*/ | |||
3630 | 0, /*tp_call*/ | |||
3631 | 0, /*tp_str*/ | |||
3632 | 0, /*tp_getattro*/ | |||
3633 | 0, /*tp_setattro*/ | |||
3634 | 0, /*tp_as_buffer*/ | |||
3635 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /*tp_flags*/ | |||
3636 | 0, /*tp_doc*/ | |||
3637 | 0, /*tp_traverse*/ | |||
3638 | 0, /*tp_clear*/ | |||
3639 | 0, /*tp_richcompare*/ | |||
3640 | 0, /*tp_weaklistoffset*/ | |||
3641 | 0, /*tp_iter*/ | |||
3642 | 0, /*tp_iternext*/ | |||
3643 | methods, /*tp_methods*/ | |||
3644 | 0, /*tp_members*/ | |||
3645 | getsetters, /*tp_getset*/ | |||
3646 | }; | |||
3647 | ||||
3648 | #ifdef WITH_IMAGEDRAW | |||
3649 | ||||
3650 | static PyTypeObject ImagingFont_Type = { | |||
3651 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, "ImagingFont", /*tp_name*/ | |||
3652 | sizeof(ImagingFontObject), /*tp_size*/ | |||
3653 | 0, /*tp_itemsize*/ | |||
3654 | /* methods */ | |||
3655 | (destructor)_font_dealloc, /*tp_dealloc*/ | |||
3656 | 0, /*tp_print*/ | |||
3657 | 0, /*tp_getattr*/ | |||
3658 | 0, /*tp_setattr*/ | |||
3659 | 0, /*tp_compare*/ | |||
3660 | 0, /*tp_repr*/ | |||
3661 | 0, /*tp_as_number */ | |||
3662 | 0, /*tp_as_sequence */ | |||
3663 | 0, /*tp_as_mapping */ | |||
3664 | 0, /*tp_hash*/ | |||
3665 | 0, /*tp_call*/ | |||
3666 | 0, /*tp_str*/ | |||
3667 | 0, /*tp_getattro*/ | |||
3668 | 0, /*tp_setattro*/ | |||
3669 | 0, /*tp_as_buffer*/ | |||
3670 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /*tp_flags*/ | |||
3671 | 0, /*tp_doc*/ | |||
3672 | 0, /*tp_traverse*/ | |||
3673 | 0, /*tp_clear*/ | |||
3674 | 0, /*tp_richcompare*/ | |||
3675 | 0, /*tp_weaklistoffset*/ | |||
3676 | 0, /*tp_iter*/ | |||
3677 | 0, /*tp_iternext*/ | |||
3678 | _font_methods, /*tp_methods*/ | |||
3679 | 0, /*tp_members*/ | |||
3680 | 0, /*tp_getset*/ | |||
3681 | }; | |||
3682 | ||||
3683 | static PyTypeObject ImagingDraw_Type = { | |||
3684 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, "ImagingDraw", /*tp_name*/ | |||
3685 | sizeof(ImagingDrawObject), /*tp_size*/ | |||
3686 | 0, /*tp_itemsize*/ | |||
3687 | /* methods */ | |||
3688 | (destructor)_draw_dealloc, /*tp_dealloc*/ | |||
3689 | 0, /*tp_print*/ | |||
3690 | 0, /*tp_getattr*/ | |||
3691 | 0, /*tp_setattr*/ | |||
3692 | 0, /*tp_compare*/ | |||
3693 | 0, /*tp_repr*/ | |||
3694 | 0, /*tp_as_number */ | |||
3695 | 0, /*tp_as_sequence */ | |||
3696 | 0, /*tp_as_mapping */ | |||
3697 | 0, /*tp_hash*/ | |||
3698 | 0, /*tp_call*/ | |||
3699 | 0, /*tp_str*/ | |||
3700 | 0, /*tp_getattro*/ | |||
3701 | 0, /*tp_setattro*/ | |||
3702 | 0, /*tp_as_buffer*/ | |||
3703 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /*tp_flags*/ | |||
3704 | 0, /*tp_doc*/ | |||
3705 | 0, /*tp_traverse*/ | |||
3706 | 0, /*tp_clear*/ | |||
3707 | 0, /*tp_richcompare*/ | |||
3708 | 0, /*tp_weaklistoffset*/ | |||
3709 | 0, /*tp_iter*/ | |||
3710 | 0, /*tp_iternext*/ | |||
3711 | _draw_methods, /*tp_methods*/ | |||
3712 | 0, /*tp_members*/ | |||
3713 | 0, /*tp_getset*/ | |||
3714 | }; | |||
3715 | ||||
3716 | #endif | |||
3717 | ||||
3718 | static PyMappingMethods pixel_access_as_mapping = { | |||
3719 | (lenfunc)NULL((void*)0), /*mp_length*/ | |||
3720 | (binaryfunc)pixel_access_getitem, /*mp_subscript*/ | |||
3721 | (objobjargproc)pixel_access_setitem, /*mp_ass_subscript*/ | |||
3722 | }; | |||
3723 | ||||
3724 | /* type description */ | |||
3725 | ||||
3726 | static PyTypeObject PixelAccess_Type = { | |||
3727 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, "PixelAccess", | |||
3728 | sizeof(PixelAccessObject), | |||
3729 | 0, | |||
3730 | /* methods */ | |||
3731 | (destructor)pixel_access_dealloc, /*tp_dealloc*/ | |||
3732 | 0, /*tp_print*/ | |||
3733 | 0, /*tp_getattr*/ | |||
3734 | 0, /*tp_setattr*/ | |||
3735 | 0, /*tp_compare*/ | |||
3736 | 0, /*tp_repr*/ | |||
3737 | 0, /*tp_as_number */ | |||
3738 | 0, /*tp_as_sequence */ | |||
3739 | &pixel_access_as_mapping, /*tp_as_mapping */ | |||
3740 | 0 /*tp_hash*/ | |||
3741 | }; | |||
3742 | ||||
3743 | /* -------------------------------------------------------------------- */ | |||
3744 | ||||
3745 | static PyObject * | |||
3746 | _get_stats(PyObject *self, PyObject *args) { | |||
3747 | PyObject *d; | |||
3748 | ImagingMemoryArena arena = &ImagingDefaultArena; | |||
3749 | ||||
3750 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, ":get_stats")) { | |||
3751 | return NULL((void*)0); | |||
3752 | } | |||
3753 | ||||
3754 | d = PyDict_New(); | |||
3755 | if (!d) { | |||
3756 | return NULL((void*)0); | |||
3757 | } | |||
3758 | PyDict_SetItemString(d, "new_count", PyLong_FromLong(arena->stats_new_count)); | |||
3759 | PyDict_SetItemString( | |||
3760 | d, "allocated_blocks", PyLong_FromLong(arena->stats_allocated_blocks)); | |||
3761 | PyDict_SetItemString( | |||
3762 | d, "reused_blocks", PyLong_FromLong(arena->stats_reused_blocks)); | |||
3763 | PyDict_SetItemString( | |||
3764 | d, "reallocated_blocks", PyLong_FromLong(arena->stats_reallocated_blocks)); | |||
3765 | PyDict_SetItemString(d, "freed_blocks", PyLong_FromLong(arena->stats_freed_blocks)); | |||
3766 | PyDict_SetItemString(d, "blocks_cached", PyLong_FromLong(arena->blocks_cached)); | |||
3767 | return d; | |||
3768 | } | |||
3769 | ||||
3770 | static PyObject * | |||
3771 | _reset_stats(PyObject *self, PyObject *args) { | |||
3772 | ImagingMemoryArena arena = &ImagingDefaultArena; | |||
3773 | ||||
3774 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, ":reset_stats")) { | |||
3775 | return NULL((void*)0); | |||
3776 | } | |||
3777 | ||||
3778 | arena->stats_new_count = 0; | |||
3779 | arena->stats_allocated_blocks = 0; | |||
3780 | arena->stats_reused_blocks = 0; | |||
3781 | arena->stats_reallocated_blocks = 0; | |||
3782 | arena->stats_freed_blocks = 0; | |||
3783 | ||||
3784 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3785 | return Py_None(&_Py_NoneStruct); | |||
3786 | } | |||
3787 | ||||
3788 | static PyObject * | |||
3789 | _get_alignment(PyObject *self, PyObject *args) { | |||
3790 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, ":get_alignment")) { | |||
3791 | return NULL((void*)0); | |||
3792 | } | |||
3793 | ||||
3794 | return PyLong_FromLong(ImagingDefaultArena.alignment); | |||
3795 | } | |||
3796 | ||||
3797 | static PyObject * | |||
3798 | _get_block_size(PyObject *self, PyObject *args) { | |||
3799 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, ":get_block_size")) { | |||
3800 | return NULL((void*)0); | |||
3801 | } | |||
3802 | ||||
3803 | return PyLong_FromLong(ImagingDefaultArena.block_size); | |||
3804 | } | |||
3805 | ||||
3806 | static PyObject * | |||
3807 | _get_blocks_max(PyObject *self, PyObject *args) { | |||
3808 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, ":get_blocks_max")) { | |||
3809 | return NULL((void*)0); | |||
3810 | } | |||
3811 | ||||
3812 | return PyLong_FromLong(ImagingDefaultArena.blocks_max); | |||
3813 | } | |||
3814 | ||||
3815 | static PyObject * | |||
3816 | _set_alignment(PyObject *self, PyObject *args) { | |||
3817 | int alignment; | |||
3818 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i:set_alignment", &alignment)) { | |||
3819 | return NULL((void*)0); | |||
3820 | } | |||
3821 | ||||
3822 | if (alignment < 1 || alignment > 128) { | |||
3823 | PyErr_SetString(PyExc_ValueError, "alignment should be from 1 to 128"); | |||
3824 | return NULL((void*)0); | |||
3825 | } | |||
3826 | /* Is power of two */ | |||
3827 | if (alignment & (alignment - 1)) { | |||
3828 | PyErr_SetString(PyExc_ValueError, "alignment should be power of two"); | |||
3829 | return NULL((void*)0); | |||
3830 | } | |||
3831 | ||||
3832 | ImagingDefaultArena.alignment = alignment; | |||
3833 | ||||
3834 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3835 | return Py_None(&_Py_NoneStruct); | |||
3836 | } | |||
3837 | ||||
3838 | static PyObject * | |||
3839 | _set_block_size(PyObject *self, PyObject *args) { | |||
3840 | int block_size; | |||
3841 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i:set_block_size", &block_size)) { | |||
3842 | return NULL((void*)0); | |||
3843 | } | |||
3844 | ||||
3845 | if (block_size <= 0) { | |||
3846 | PyErr_SetString(PyExc_ValueError, "block_size should be greater than 0"); | |||
3847 | return NULL((void*)0); | |||
3848 | } | |||
3849 | ||||
3850 | if (block_size & 0xfff) { | |||
3851 | PyErr_SetString(PyExc_ValueError, "block_size should be multiple of 4096"); | |||
3852 | return NULL((void*)0); | |||
3853 | } | |||
3854 | ||||
3855 | ImagingDefaultArena.block_size = block_size; | |||
3856 | ||||
3857 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3858 | return Py_None(&_Py_NoneStruct); | |||
3859 | } | |||
3860 | ||||
3861 | static PyObject * | |||
3862 | _set_blocks_max(PyObject *self, PyObject *args) { | |||
3863 | int blocks_max; | |||
3864 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "i:set_blocks_max", &blocks_max)) { | |||
3865 | return NULL((void*)0); | |||
3866 | } | |||
3867 | ||||
3868 | if (blocks_max < 0) { | |||
3869 | PyErr_SetString(PyExc_ValueError, "blocks_max should be greater than 0"); | |||
3870 | return NULL((void*)0); | |||
3871 | } else if ( | |||
3872 | (unsigned long)blocks_max > | |||
3873 | SIZE_MAX(18446744073709551615UL) / sizeof(ImagingDefaultArena.blocks_pool[0])) { | |||
3874 | PyErr_SetString(PyExc_ValueError, "blocks_max is too large"); | |||
3875 | return NULL((void*)0); | |||
3876 | } | |||
3877 | ||||
3878 | if (!ImagingMemorySetBlocksMax(&ImagingDefaultArena, blocks_max)) { | |||
3879 | return ImagingError_MemoryError(); | |||
3880 | } | |||
3881 | ||||
3882 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3883 | return Py_None(&_Py_NoneStruct); | |||
3884 | } | |||
3885 | ||||
3886 | static PyObject * | |||
3887 | _clear_cache(PyObject *self, PyObject *args) { | |||
3888 | int i = 0; | |||
3889 | ||||
3890 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "|i:clear_cache", &i)) { | |||
3891 | return NULL((void*)0); | |||
3892 | } | |||
3893 | ||||
3894 | ImagingMemoryClearCache(&ImagingDefaultArena, i); | |||
3895 | ||||
3896 | Py_INCREF(Py_None)_Py_INCREF(((PyObject*)((&_Py_NoneStruct)))); | |||
3897 | return Py_None(&_Py_NoneStruct); | |||
3898 | } | |||
3899 | ||||
3900 | /* -------------------------------------------------------------------- */ | |||
3901 | ||||
3902 | /* FIXME: this is something of a mess. Should replace this with | |||
3903 | pluggable codecs, but not before PIL 1.2 */ | |||
3904 | ||||
3905 | /* Decoders (in decode.c) */ | |||
3906 | extern PyObject * | |||
3907 | PyImaging_BcnDecoderNew(PyObject *self, PyObject *args); | |||
3908 | extern PyObject * | |||
3909 | PyImaging_BitDecoderNew(PyObject *self, PyObject *args); | |||
3910 | extern PyObject * | |||
3911 | PyImaging_FliDecoderNew(PyObject *self, PyObject *args); | |||
3912 | extern PyObject * | |||
3913 | PyImaging_GifDecoderNew(PyObject *self, PyObject *args); | |||
3914 | extern PyObject * | |||
3915 | PyImaging_HexDecoderNew(PyObject *self, PyObject *args); | |||
3916 | extern PyObject * | |||
3917 | PyImaging_JpegDecoderNew(PyObject *self, PyObject *args); | |||
3918 | extern PyObject * | |||
3919 | PyImaging_Jpeg2KDecoderNew(PyObject *self, PyObject *args); | |||
3920 | extern PyObject * | |||
3921 | PyImaging_LibTiffDecoderNew(PyObject *self, PyObject *args); | |||
3922 | extern PyObject * | |||
3923 | PyImaging_PackbitsDecoderNew(PyObject *self, PyObject *args); | |||
3924 | extern PyObject * | |||
3925 | PyImaging_PcdDecoderNew(PyObject *self, PyObject *args); | |||
3926 | extern PyObject * | |||
3927 | PyImaging_PcxDecoderNew(PyObject *self, PyObject *args); | |||
3928 | extern PyObject * | |||
3929 | PyImaging_RawDecoderNew(PyObject *self, PyObject *args); | |||
3930 | extern PyObject * | |||
3931 | PyImaging_SgiRleDecoderNew(PyObject *self, PyObject *args); | |||
3932 | extern PyObject * | |||
3933 | PyImaging_SunRleDecoderNew(PyObject *self, PyObject *args); | |||
3934 | extern PyObject * | |||
3935 | PyImaging_TgaRleDecoderNew(PyObject *self, PyObject *args); | |||
3936 | extern PyObject * | |||
3937 | PyImaging_XbmDecoderNew(PyObject *self, PyObject *args); | |||
3938 | extern PyObject * | |||
3939 | PyImaging_ZipDecoderNew(PyObject *self, PyObject *args); | |||
3940 | ||||
3941 | /* Encoders (in encode.c) */ | |||
3942 | extern PyObject * | |||
3943 | PyImaging_EpsEncoderNew(PyObject *self, PyObject *args); | |||
3944 | extern PyObject * | |||
3945 | PyImaging_GifEncoderNew(PyObject *self, PyObject *args); | |||
3946 | extern PyObject * | |||
3947 | PyImaging_JpegEncoderNew(PyObject *self, PyObject *args); | |||
3948 | extern PyObject * | |||
3949 | PyImaging_Jpeg2KEncoderNew(PyObject *self, PyObject *args); | |||
3950 | extern PyObject * | |||
3951 | PyImaging_PcxEncoderNew(PyObject *self, PyObject *args); | |||
3952 | extern PyObject * | |||
3953 | PyImaging_RawEncoderNew(PyObject *self, PyObject *args); | |||
3954 | extern PyObject * | |||
3955 | PyImaging_TgaRleEncoderNew(PyObject *self, PyObject *args); | |||
3956 | extern PyObject * | |||
3957 | PyImaging_XbmEncoderNew(PyObject *self, PyObject *args); | |||
3958 | extern PyObject * | |||
3959 | PyImaging_ZipEncoderNew(PyObject *self, PyObject *args); | |||
3960 | extern PyObject * | |||
3961 | PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args); | |||
3962 | ||||
3963 | /* Display support etc (in display.c) */ | |||
3964 | #ifdef _WIN32 | |||
3965 | extern PyObject * | |||
3966 | PyImaging_CreateWindowWin32(PyObject *self, PyObject *args); | |||
3967 | extern PyObject * | |||
3968 | PyImaging_DisplayWin32(PyObject *self, PyObject *args); | |||
3969 | extern PyObject * | |||
3970 | PyImaging_DisplayModeWin32(PyObject *self, PyObject *args); | |||
3971 | extern PyObject * | |||
3972 | PyImaging_GrabScreenWin32(PyObject *self, PyObject *args); | |||
3973 | extern PyObject * | |||
3974 | PyImaging_GrabClipboardWin32(PyObject *self, PyObject *args); | |||
3975 | extern PyObject * | |||
3976 | PyImaging_ListWindowsWin32(PyObject *self, PyObject *args); | |||
3977 | extern PyObject * | |||
3978 | PyImaging_EventLoopWin32(PyObject *self, PyObject *args); | |||
3979 | extern PyObject * | |||
3980 | PyImaging_DrawWmf(PyObject *self, PyObject *args); | |||
3981 | #endif | |||
3982 | #ifdef HAVE_XCB1 | |||
3983 | extern PyObject * | |||
3984 | PyImaging_GrabScreenX11(PyObject *self, PyObject *args); | |||
3985 | #endif | |||
3986 | ||||
3987 | /* Experimental path stuff (in path.c) */ | |||
3988 | extern PyObject * | |||
3989 | PyPath_Create(ImagingObject *self, PyObject *args); | |||
3990 | ||||
3991 | /* Experimental outline stuff (in outline.c) */ | |||
3992 | extern PyObject * | |||
3993 | PyOutline_Create(ImagingObject *self, PyObject *args); | |||
3994 | ||||
3995 | extern PyObject * | |||
3996 | PyImaging_MapBuffer(PyObject *self, PyObject *args); | |||
3997 | ||||
3998 | static PyMethodDef functions[] = { | |||
3999 | ||||
4000 | /* Object factories */ | |||
4001 | {"alpha_composite", (PyCFunction)_alpha_composite, METH_VARARGS0x0001}, | |||
4002 | {"blend", (PyCFunction)_blend, METH_VARARGS0x0001}, | |||
4003 | {"fill", (PyCFunction)_fill, METH_VARARGS0x0001}, | |||
4004 | {"new", (PyCFunction)_new, METH_VARARGS0x0001}, | |||
4005 | {"merge", (PyCFunction)_merge, METH_VARARGS0x0001}, | |||
4006 | ||||
4007 | /* Functions */ | |||
4008 | {"convert", (PyCFunction)_convert2, METH_VARARGS0x0001}, | |||
4009 | ||||
4010 | /* Codecs */ | |||
4011 | {"bcn_decoder", (PyCFunction)PyImaging_BcnDecoderNew, METH_VARARGS0x0001}, | |||
4012 | {"bit_decoder", (PyCFunction)PyImaging_BitDecoderNew, METH_VARARGS0x0001}, | |||
4013 | {"eps_encoder", (PyCFunction)PyImaging_EpsEncoderNew, METH_VARARGS0x0001}, | |||
4014 | {"fli_decoder", (PyCFunction)PyImaging_FliDecoderNew, METH_VARARGS0x0001}, | |||
4015 | {"gif_decoder", (PyCFunction)PyImaging_GifDecoderNew, METH_VARARGS0x0001}, | |||
4016 | {"gif_encoder", (PyCFunction)PyImaging_GifEncoderNew, METH_VARARGS0x0001}, | |||
4017 | {"hex_decoder", (PyCFunction)PyImaging_HexDecoderNew, METH_VARARGS0x0001}, | |||
4018 | {"hex_encoder", (PyCFunction)PyImaging_EpsEncoderNew, METH_VARARGS0x0001}, /* EPS=HEX! */ | |||
4019 | #ifdef HAVE_LIBJPEG1 | |||
4020 | {"jpeg_decoder", (PyCFunction)PyImaging_JpegDecoderNew, METH_VARARGS0x0001}, | |||
4021 | {"jpeg_encoder", (PyCFunction)PyImaging_JpegEncoderNew, METH_VARARGS0x0001}, | |||
4022 | #endif | |||
4023 | #ifdef HAVE_OPENJPEG1 | |||
4024 | {"jpeg2k_decoder", (PyCFunction)PyImaging_Jpeg2KDecoderNew, METH_VARARGS0x0001}, | |||
4025 | {"jpeg2k_encoder", (PyCFunction)PyImaging_Jpeg2KEncoderNew, METH_VARARGS0x0001}, | |||
4026 | #endif | |||
4027 | #ifdef HAVE_LIBTIFF1 | |||
4028 | {"libtiff_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, METH_VARARGS0x0001}, | |||
4029 | {"libtiff_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, METH_VARARGS0x0001}, | |||
4030 | #endif | |||
4031 | {"packbits_decoder", (PyCFunction)PyImaging_PackbitsDecoderNew, METH_VARARGS0x0001}, | |||
4032 | {"pcd_decoder", (PyCFunction)PyImaging_PcdDecoderNew, METH_VARARGS0x0001}, | |||
4033 | {"pcx_decoder", (PyCFunction)PyImaging_PcxDecoderNew, METH_VARARGS0x0001}, | |||
4034 | {"pcx_encoder", (PyCFunction)PyImaging_PcxEncoderNew, METH_VARARGS0x0001}, | |||
4035 | {"raw_decoder", (PyCFunction)PyImaging_RawDecoderNew, METH_VARARGS0x0001}, | |||
4036 | {"raw_encoder", (PyCFunction)PyImaging_RawEncoderNew, METH_VARARGS0x0001}, | |||
4037 | {"sgi_rle_decoder", (PyCFunction)PyImaging_SgiRleDecoderNew, METH_VARARGS0x0001}, | |||
4038 | {"sun_rle_decoder", (PyCFunction)PyImaging_SunRleDecoderNew, METH_VARARGS0x0001}, | |||
4039 | {"tga_rle_decoder", (PyCFunction)PyImaging_TgaRleDecoderNew, METH_VARARGS0x0001}, | |||
4040 | {"tga_rle_encoder", (PyCFunction)PyImaging_TgaRleEncoderNew, METH_VARARGS0x0001}, | |||
4041 | {"xbm_decoder", (PyCFunction)PyImaging_XbmDecoderNew, METH_VARARGS0x0001}, | |||
4042 | {"xbm_encoder", (PyCFunction)PyImaging_XbmEncoderNew, METH_VARARGS0x0001}, | |||
4043 | #ifdef HAVE_LIBZ1 | |||
4044 | {"zip_decoder", (PyCFunction)PyImaging_ZipDecoderNew, METH_VARARGS0x0001}, | |||
4045 | {"zip_encoder", (PyCFunction)PyImaging_ZipEncoderNew, METH_VARARGS0x0001}, | |||
4046 | #endif | |||
4047 | ||||
4048 | /* Memory mapping */ | |||
4049 | #ifdef WITH_MAPPING | |||
4050 | {"map_buffer", (PyCFunction)PyImaging_MapBuffer, METH_VARARGS0x0001}, | |||
4051 | #endif | |||
4052 | ||||
4053 | /* Display support */ | |||
4054 | #ifdef _WIN32 | |||
4055 | {"display", (PyCFunction)PyImaging_DisplayWin32, METH_VARARGS0x0001}, | |||
4056 | {"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, METH_VARARGS0x0001}, | |||
4057 | {"grabscreen_win32", (PyCFunction)PyImaging_GrabScreenWin32, METH_VARARGS0x0001}, | |||
4058 | {"grabclipboard_win32", (PyCFunction)PyImaging_GrabClipboardWin32, METH_VARARGS0x0001}, | |||
4059 | {"createwindow", (PyCFunction)PyImaging_CreateWindowWin32, METH_VARARGS0x0001}, | |||
4060 | {"eventloop", (PyCFunction)PyImaging_EventLoopWin32, METH_VARARGS0x0001}, | |||
4061 | {"listwindows", (PyCFunction)PyImaging_ListWindowsWin32, METH_VARARGS0x0001}, | |||
4062 | {"drawwmf", (PyCFunction)PyImaging_DrawWmf, METH_VARARGS0x0001}, | |||
4063 | #endif | |||
4064 | #ifdef HAVE_XCB1 | |||
4065 | {"grabscreen_x11", (PyCFunction)PyImaging_GrabScreenX11, METH_VARARGS0x0001}, | |||
4066 | #endif | |||
4067 | ||||
4068 | /* Utilities */ | |||
4069 | {"getcodecstatus", (PyCFunction)_getcodecstatus, METH_VARARGS0x0001}, | |||
4070 | ||||
4071 | /* Special effects (experimental) */ | |||
4072 | #ifdef WITH_EFFECTS | |||
4073 | {"effect_mandelbrot", (PyCFunction)_effect_mandelbrot, METH_VARARGS0x0001}, | |||
4074 | {"effect_noise", (PyCFunction)_effect_noise, METH_VARARGS0x0001}, | |||
4075 | {"linear_gradient", (PyCFunction)_linear_gradient, METH_VARARGS0x0001}, | |||
4076 | {"radial_gradient", (PyCFunction)_radial_gradient, METH_VARARGS0x0001}, | |||
4077 | {"wedge", (PyCFunction)_linear_gradient, METH_VARARGS0x0001}, /* Compatibility */ | |||
4078 | #endif | |||
4079 | ||||
4080 | /* Drawing support stuff */ | |||
4081 | #ifdef WITH_IMAGEDRAW | |||
4082 | {"font", (PyCFunction)_font_new, METH_VARARGS0x0001}, | |||
4083 | {"draw", (PyCFunction)_draw_new, METH_VARARGS0x0001}, | |||
4084 | #endif | |||
4085 | ||||
4086 | /* Experimental path stuff */ | |||
4087 | #ifdef WITH_IMAGEPATH | |||
4088 | {"path", (PyCFunction)PyPath_Create, METH_VARARGS0x0001}, | |||
4089 | #endif | |||
4090 | ||||
4091 | /* Experimental arrow graphics stuff */ | |||
4092 | #ifdef WITH_ARROW | |||
4093 | {"outline", (PyCFunction)PyOutline_Create, METH_VARARGS0x0001}, | |||
4094 | #endif | |||
4095 | ||||
4096 | /* Resource management */ | |||
4097 | {"get_stats", (PyCFunction)_get_stats, METH_VARARGS0x0001}, | |||
4098 | {"reset_stats", (PyCFunction)_reset_stats, METH_VARARGS0x0001}, | |||
4099 | {"get_alignment", (PyCFunction)_get_alignment, METH_VARARGS0x0001}, | |||
4100 | {"get_block_size", (PyCFunction)_get_block_size, METH_VARARGS0x0001}, | |||
4101 | {"get_blocks_max", (PyCFunction)_get_blocks_max, METH_VARARGS0x0001}, | |||
4102 | {"set_alignment", (PyCFunction)_set_alignment, METH_VARARGS0x0001}, | |||
4103 | {"set_block_size", (PyCFunction)_set_block_size, METH_VARARGS0x0001}, | |||
4104 | {"set_blocks_max", (PyCFunction)_set_blocks_max, METH_VARARGS0x0001}, | |||
4105 | {"clear_cache", (PyCFunction)_clear_cache, METH_VARARGS0x0001}, | |||
4106 | ||||
4107 | {NULL((void*)0), NULL((void*)0)} /* sentinel */ | |||
4108 | }; | |||
4109 | ||||
4110 | static int | |||
4111 | setup_module(PyObject *m) { | |||
4112 | PyObject *d = PyModule_GetDict(m); | |||
4113 | const char *version = (char *)PILLOW_VERSION"8.4.0.dev0"; | |||
4114 | ||||
4115 | /* Ready object types */ | |||
4116 | if (PyType_Ready(&Imaging_Type) < 0) { | |||
4117 | return -1; | |||
4118 | } | |||
4119 | ||||
4120 | #ifdef WITH_IMAGEDRAW | |||
4121 | if (PyType_Ready(&ImagingFont_Type) < 0) { | |||
4122 | return -1; | |||
4123 | } | |||
4124 | ||||
4125 | if (PyType_Ready(&ImagingDraw_Type) < 0) { | |||
4126 | return -1; | |||
4127 | } | |||
4128 | #endif | |||
4129 | if (PyType_Ready(&PixelAccess_Type) < 0) { | |||
4130 | return -1; | |||
4131 | } | |||
4132 | ||||
4133 | ImagingAccessInit(); | |||
4134 | ||||
4135 | #ifdef HAVE_LIBJPEG1 | |||
4136 | { | |||
4137 | extern const char *ImagingJpegVersion(void); | |||
4138 | PyDict_SetItemString( | |||
4139 | d, "jpeglib_version", PyUnicode_FromString(ImagingJpegVersion())); | |||
4140 | } | |||
4141 | #endif | |||
4142 | ||||
4143 | #ifdef HAVE_OPENJPEG1 | |||
4144 | { | |||
4145 | extern const char *ImagingJpeg2KVersion(void); | |||
4146 | PyDict_SetItemString( | |||
4147 | d, "jp2klib_version", PyUnicode_FromString(ImagingJpeg2KVersion())); | |||
4148 | } | |||
4149 | #endif | |||
4150 | ||||
4151 | PyObject *have_libjpegturbo; | |||
4152 | #ifdef LIBJPEG_TURBO_VERSION2.0.3 | |||
4153 | have_libjpegturbo = Py_True((PyObject *) &_Py_TrueStruct); | |||
4154 | #define tostr1(a) #a | |||
4155 | #define tostr(a) tostr1(a) | |||
4156 | PyDict_SetItemString( | |||
4157 | d, "libjpeg_turbo_version", PyUnicode_FromString(tostr(LIBJPEG_TURBO_VERSION2.0.3))); | |||
4158 | #undef tostr | |||
4159 | #undef tostr1 | |||
4160 | #else | |||
4161 | have_libjpegturbo = Py_False((PyObject *) &_Py_FalseStruct); | |||
4162 | #endif | |||
4163 | Py_INCREF(have_libjpegturbo)_Py_INCREF(((PyObject*)(have_libjpegturbo))); | |||
4164 | PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", have_libjpegturbo); | |||
4165 | ||||
4166 | PyObject *have_libimagequant; | |||
4167 | #ifdef HAVE_LIBIMAGEQUANT1 | |||
4168 | have_libimagequant = Py_True((PyObject *) &_Py_TrueStruct); | |||
4169 | { | |||
4170 | extern const char *ImagingImageQuantVersion(void); | |||
4171 | PyDict_SetItemString( | |||
4172 | d, "imagequant_version", PyUnicode_FromString(ImagingImageQuantVersion())); | |||
| ||||
4173 | } | |||
4174 | #else | |||
4175 | have_libimagequant = Py_False((PyObject *) &_Py_FalseStruct); | |||
4176 | #endif | |||
4177 | Py_INCREF(have_libimagequant)_Py_INCREF(((PyObject*)(have_libimagequant))); | |||
4178 | PyModule_AddObject(m, "HAVE_LIBIMAGEQUANT", have_libimagequant); | |||
4179 | ||||
4180 | #ifdef HAVE_LIBZ1 | |||
4181 | /* zip encoding strategies */ | |||
4182 | PyModule_AddIntConstant(m, "DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY0); | |||
4183 | PyModule_AddIntConstant(m, "FILTERED", Z_FILTERED1); | |||
4184 | PyModule_AddIntConstant(m, "HUFFMAN_ONLY", Z_HUFFMAN_ONLY2); | |||
4185 | PyModule_AddIntConstant(m, "RLE", Z_RLE3); | |||
4186 | PyModule_AddIntConstant(m, "FIXED", Z_FIXED4); | |||
4187 | { | |||
4188 | extern const char *ImagingZipVersion(void); | |||
4189 | PyDict_SetItemString( | |||
4190 | d, "zlib_version", PyUnicode_FromString(ImagingZipVersion())); | |||
4191 | } | |||
4192 | #endif | |||
4193 | ||||
4194 | #ifdef HAVE_LIBTIFF1 | |||
4195 | { | |||
4196 | extern const char *ImagingTiffVersion(void); | |||
4197 | PyDict_SetItemString( | |||
4198 | d, "libtiff_version", PyUnicode_FromString(ImagingTiffVersion())); | |||
4199 | ||||
4200 | // Test for libtiff 4.0 or later, excluding libtiff 3.9.6 and 3.9.7 | |||
4201 | PyObject *support_custom_tags; | |||
4202 | #if TIFFLIB_VERSION20191103 >= 20111221 && TIFFLIB_VERSION20191103 != 20120218 && \ | |||
4203 | TIFFLIB_VERSION20191103 != 20120922 | |||
4204 | support_custom_tags = Py_True((PyObject *) &_Py_TrueStruct); | |||
4205 | #else | |||
4206 | support_custom_tags = Py_False((PyObject *) &_Py_FalseStruct); | |||
4207 | #endif | |||
4208 | PyDict_SetItemString(d, "libtiff_support_custom_tags", support_custom_tags); | |||
4209 | } | |||
4210 | #endif | |||
4211 | ||||
4212 | PyObject *have_xcb; | |||
4213 | #ifdef HAVE_XCB1 | |||
4214 | have_xcb = Py_True((PyObject *) &_Py_TrueStruct); | |||
4215 | #else | |||
4216 | have_xcb = Py_False((PyObject *) &_Py_FalseStruct); | |||
4217 | #endif | |||
4218 | Py_INCREF(have_xcb)_Py_INCREF(((PyObject*)(have_xcb))); | |||
4219 | PyModule_AddObject(m, "HAVE_XCB", have_xcb); | |||
4220 | ||||
4221 | PyDict_SetItemString(d, "PILLOW_VERSION", PyUnicode_FromString(version)); | |||
4222 | ||||
4223 | return 0; | |||
4224 | } | |||
4225 | ||||
4226 | PyMODINIT_FUNCPyObject* | |||
4227 | PyInit__imaging(void) { | |||
4228 | PyObject *m; | |||
4229 | ||||
4230 | static PyModuleDef module_def = { | |||
4231 | PyModuleDef_HEAD_INIT{ { 1, ((void*)0) }, ((void*)0), 0, ((void*)0), }, | |||
4232 | "_imaging", /* m_name */ | |||
4233 | NULL((void*)0), /* m_doc */ | |||
4234 | -1, /* m_size */ | |||
4235 | functions, /* m_methods */ | |||
4236 | }; | |||
4237 | ||||
4238 | m = PyModule_Create(&module_def)PyModule_Create2(&module_def, 1013); | |||
4239 | ||||
4240 | if (setup_module(m) < 0) { | |||
| ||||
4241 | return NULL((void*)0); | |||
4242 | } | |||
4243 | ||||
4244 | return m; | |||
4245 | } |
1 | #ifndef PyUnicode_FromString |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject *PyUnicode_FromString(const char *u) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API PyUnicode_FromString is defined as a macro." |
10 | #endif |