~ubuntu-branches/ubuntu/wily/python-imaging/wily

« back to all changes in this revision

Viewing changes to .pc/git-updates.diff/_imaging.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-01-31 20:49:20 UTC
  • mfrom: (27.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130131204920-b5zshy6vgfvdionl
Tags: 1.1.7+1.7.8-1ubuntu1
Rewrite build dependencies to allow cross builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
75
#include "Python.h"
 
76
 
 
77
#include "Imaging.h"
 
78
 
 
79
 
 
80
/* Configuration stuff. Feel free to undef things you don't need. */
 
81
#define WITH_IMAGECHOPS /* ImageChops support */
 
82
#define WITH_IMAGEDRAW /* ImageDraw support */
 
83
#define WITH_MAPPING /* use memory mapping to read some file formats */
 
84
#define WITH_IMAGEPATH /* ImagePath stuff */
 
85
#define WITH_ARROW /* arrow graphics stuff (experimental) */
 
86
#define WITH_EFFECTS /* special effects */
 
87
#define WITH_QUANTIZE /* quantization support */
 
88
#define WITH_RANKFILTER /* rank filter */
 
89
#define WITH_MODEFILTER /* mode filter */
 
90
#define WITH_THREADING /* "friendly" threading support */
 
91
#define WITH_UNSHARPMASK /* Kevin Cazabon's unsharpmask module */
 
92
 
 
93
#define WITH_DEBUG /* extra debugging interfaces */
 
94
 
 
95
/* PIL Plus extensions */
 
96
#undef  WITH_CRACKCODE /* pil plus */
 
97
 
 
98
#undef  VERBOSE
 
99
 
 
100
#define CLIP(x) ((x) <= 0 ? 0 : (x) < 256 ? (x) : 255)
 
101
 
 
102
#define B16(p, i) ((((int)p[(i)]) << 8) + p[(i)+1])
 
103
#define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)])
 
104
#define S16(v) ((v) < 32768 ? (v) : ((v) - 65536))
 
105
 
 
106
#if PY_VERSION_HEX < 0x01060000
 
107
#define PyObject_New PyObject_NEW
 
108
#define PyObject_Del PyMem_DEL
 
109
#endif
 
110
 
 
111
#if PY_VERSION_HEX < 0x02050000
 
112
#define Py_ssize_t int
 
113
#define ssizeargfunc intargfunc
 
114
#define ssizessizeargfunc intintargfunc
 
115
#define ssizeobjargproc intobjargproc
 
116
#define ssizessizeobjargproc intintobjargproc
 
117
#endif
 
118
 
 
119
/* -------------------------------------------------------------------- */
 
120
/* OBJECT ADMINISTRATION                                                */
 
121
/* -------------------------------------------------------------------- */
 
122
 
 
123
typedef struct {
 
124
    PyObject_HEAD
 
125
    Imaging image;
 
126
    ImagingAccess access;
 
127
} ImagingObject;
 
128
 
 
129
staticforward PyTypeObject Imaging_Type;
 
130
 
 
131
#ifdef WITH_IMAGEDRAW
 
132
 
 
133
typedef struct
 
134
{
 
135
    /* to write a character, cut out sxy from glyph data, place
 
136
       at current position plus dxy, and advance by (dx, dy) */
 
137
    int dx, dy;
 
138
    int dx0, dy0, dx1, dy1;
 
139
    int sx0, sy0, sx1, sy1;
 
140
} Glyph;
 
141
 
 
142
typedef struct {
 
143
    PyObject_HEAD
 
144
    ImagingObject* ref;
 
145
    Imaging bitmap;
 
146
    int ysize;
 
147
    int baseline;
 
148
    Glyph glyphs[256];
 
149
} ImagingFontObject;
 
150
 
 
151
staticforward PyTypeObject ImagingFont_Type;
 
152
 
 
153
typedef struct {
 
154
    PyObject_HEAD
 
155
    ImagingObject* image;
 
156
    UINT8 ink[4];
 
157
    int blend;
 
158
} ImagingDrawObject;
 
159
 
 
160
staticforward PyTypeObject ImagingDraw_Type;
 
161
 
 
162
#endif
 
163
 
 
164
typedef struct {
 
165
    PyObject_HEAD
 
166
    ImagingObject* image;
 
167
    int readonly;
 
168
} PixelAccessObject;
 
169
 
 
170
staticforward PyTypeObject PixelAccess_Type;
 
171
 
 
172
PyObject* 
 
173
PyImagingNew(Imaging imOut)
 
174
{
 
175
    ImagingObject* imagep;
 
176
 
 
177
    if (!imOut)
 
178
        return NULL;
 
179
 
 
180
    imagep = PyObject_New(ImagingObject, &Imaging_Type);
 
181
    if (imagep == NULL) {
 
182
        ImagingDelete(imOut);
 
183
        return NULL;
 
184
    }
 
185
 
 
186
#ifdef VERBOSE
 
187
    printf("imaging %p allocated\n", imagep);
 
188
#endif
 
189
 
 
190
    imagep->image = imOut;
 
191
    imagep->access = ImagingAccessNew(imOut);
 
192
 
 
193
    return (PyObject*) imagep;
 
194
}
 
195
 
 
196
static void
 
197
_dealloc(ImagingObject* imagep)
 
198
{
 
199
 
 
200
#ifdef VERBOSE
 
201
    printf("imaging %p deleted\n", imagep);
 
202
#endif
 
203
 
 
204
    if (imagep->access)
 
205
      ImagingAccessDelete(imagep->image, imagep->access);
 
206
    ImagingDelete(imagep->image);
 
207
    PyObject_Del(imagep);
 
208
}
 
209
 
 
210
#define PyImaging_Check(op) ((op)->ob_type == &Imaging_Type)
 
211
 
 
212
Imaging PyImaging_AsImaging(PyObject *op)
 
213
{
 
214
    if (!PyImaging_Check(op)) {
 
215
        PyErr_BadInternalCall();
 
216
        return NULL;
 
217
    }
 
218
 
 
219
    return ((ImagingObject *)op)->image;
 
220
}
 
221
 
 
222
 
 
223
/* -------------------------------------------------------------------- */
 
224
/* THREAD HANDLING                                                      */
 
225
/* -------------------------------------------------------------------- */
 
226
 
 
227
void ImagingSectionEnter(ImagingSectionCookie* cookie)
 
228
{
 
229
#ifdef WITH_THREADING
 
230
    *cookie = (PyThreadState *) PyEval_SaveThread();
 
231
#endif
 
232
}
 
233
 
 
234
void ImagingSectionLeave(ImagingSectionCookie* cookie)
 
235
{
 
236
#ifdef WITH_THREADING
 
237
    PyEval_RestoreThread((PyThreadState*) *cookie);
 
238
#endif
 
239
}
 
240
 
 
241
/* -------------------------------------------------------------------- */
 
242
/* BUFFER HANDLING                                                      */
 
243
/* -------------------------------------------------------------------- */
 
244
/* Python compatibility API */
 
245
 
 
246
#if PY_VERSION_HEX < 0x02020000
 
247
 
 
248
int PyImaging_CheckBuffer(PyObject *buffer)
 
249
{
 
250
    PyBufferProcs *procs = buffer->ob_type->tp_as_buffer;
 
251
    if (procs && procs->bf_getreadbuffer && procs->bf_getsegcount &&
 
252
        procs->bf_getsegcount(buffer, NULL) == 1)
 
253
        return 1;
 
254
    return 0;
 
255
}
 
256
 
 
257
int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr)
 
258
{
 
259
    PyBufferProcs *procs = buffer->ob_type->tp_as_buffer;
 
260
    return procs->bf_getreadbuffer(buffer, 0, ptr);
 
261
}
 
262
 
 
263
#else
 
264
 
 
265
int PyImaging_CheckBuffer(PyObject* buffer)
 
266
{
 
267
    return PyObject_CheckReadBuffer(buffer);
 
268
}
 
269
 
 
270
int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr)
 
271
{
 
272
    /* must call check_buffer first! */
 
273
#if PY_VERSION_HEX < 0x02050000
 
274
    int n = 0;
 
275
#else
 
276
    Py_ssize_t n = 0;
 
277
#endif
 
278
    PyObject_AsReadBuffer(buffer, ptr, &n);
 
279
    return (int) n;
 
280
}
 
281
 
 
282
#endif
 
283
 
 
284
/* -------------------------------------------------------------------- */
 
285
/* EXCEPTION REROUTING                                                  */
 
286
/* -------------------------------------------------------------------- */
 
287
 
 
288
/* error messages */
 
289
static const char* must_be_sequence = "argument must be a sequence";
 
290
static const char* wrong_mode = "unrecognized image mode";
 
291
static const char* wrong_raw_mode = "unrecognized raw mode";
 
292
static const char* outside_image = "image index out of range";
 
293
static const char* outside_palette = "palette index out of range";
 
294
static const char* no_palette = "image has no palette";
 
295
static const char* readonly = "image is readonly";
 
296
/* static const char* no_content = "image has no content"; */
 
297
 
 
298
void *
 
299
ImagingError_IOError(void)
 
300
{
 
301
    PyErr_SetString(PyExc_IOError, "error when accessing file");
 
302
    return NULL;
 
303
}
 
304
 
 
305
void *
 
306
ImagingError_MemoryError(void)
 
307
{
 
308
    return PyErr_NoMemory();
 
309
}
 
310
 
 
311
void *
 
312
ImagingError_Mismatch(void)
 
313
{
 
314
    PyErr_SetString(PyExc_ValueError, "images do not match");
 
315
    return NULL;
 
316
}
 
317
 
 
318
void *
 
319
ImagingError_ModeError(void)
 
320
{
 
321
    PyErr_SetString(PyExc_ValueError, "image has wrong mode");
 
322
    return NULL;
 
323
}
 
324
 
 
325
void *
 
326
ImagingError_ValueError(const char *message)
 
327
{
 
328
    PyErr_SetString(
 
329
        PyExc_ValueError,
 
330
        (message) ? (char*) message : "unrecognized argument value"
 
331
        );
 
332
    return NULL;
 
333
}
 
334
 
 
335
void
 
336
ImagingError_Clear(void)
 
337
{
 
338
    PyErr_Clear();
 
339
}
 
340
 
 
341
/* -------------------------------------------------------------------- */
 
342
/* HELPERS                                                              */
 
343
/* -------------------------------------------------------------------- */
 
344
 
 
345
static int
 
346
getbands(const char* mode)
 
347
{
 
348
    Imaging im;
 
349
    int bands;
 
350
 
 
351
    /* FIXME: add primitive to libImaging to avoid extra allocation */
 
352
    im = ImagingNew(mode, 0, 0);
 
353
    if (!im)
 
354
        return -1;
 
355
 
 
356
    bands = im->bands;
 
357
 
 
358
    ImagingDelete(im);
 
359
 
 
360
    return bands;
 
361
}
 
362
 
 
363
#define TYPE_UINT8 (0x100|sizeof(UINT8))
 
364
#define TYPE_INT32 (0x200|sizeof(INT32))
 
365
#define TYPE_FLOAT32 (0x300|sizeof(FLOAT32))
 
366
#define TYPE_DOUBLE (0x400|sizeof(double))
 
367
 
 
368
static void*
 
369
getlist(PyObject* arg, int* length, const char* wrong_length, int type)
 
370
{
 
371
    int i, n;
 
372
    void* list;
 
373
 
 
374
    if (!PySequence_Check(arg)) {
 
375
        PyErr_SetString(PyExc_TypeError, must_be_sequence);
 
376
        return NULL;
 
377
    }
 
378
 
 
379
    n = PyObject_Length(arg);
 
380
    if (length && wrong_length && n != *length) {
 
381
        PyErr_SetString(PyExc_ValueError, wrong_length);
 
382
        return NULL;
 
383
    }
 
384
 
 
385
    list = malloc(n * (type & 0xff));
 
386
    if (!list)
 
387
        return PyErr_NoMemory();
 
388
 
 
389
    switch (type) {
 
390
    case TYPE_UINT8:
 
391
        if (PyList_Check(arg)) {
 
392
            for (i = 0; i < n; i++) {
 
393
                PyObject *op = PyList_GET_ITEM(arg, i);
 
394
                int temp = PyInt_AsLong(op);
 
395
                ((UINT8*)list)[i] = CLIP(temp);
 
396
            }
 
397
        } else {
 
398
            for (i = 0; i < n; i++) {
 
399
                PyObject *op = PySequence_GetItem(arg, i);
 
400
                int temp = PyInt_AsLong(op);
 
401
                Py_XDECREF(op);
 
402
                ((UINT8*)list)[i] = CLIP(temp);
 
403
            }
 
404
        }
 
405
        break;
 
406
    case TYPE_INT32:
 
407
        if (PyList_Check(arg)) {
 
408
            for (i = 0; i < n; i++) {
 
409
                PyObject *op = PyList_GET_ITEM(arg, i);
 
410
                int temp = PyInt_AsLong(op);
 
411
                ((INT32*)list)[i] = temp;
 
412
            }
 
413
        } else {
 
414
            for (i = 0; i < n; i++) {
 
415
                PyObject *op = PySequence_GetItem(arg, i);
 
416
                int temp = PyInt_AsLong(op);
 
417
                Py_XDECREF(op);
 
418
                ((INT32*)list)[i] = temp;
 
419
            }
 
420
        }
 
421
        break;
 
422
    case TYPE_FLOAT32:
 
423
        if (PyList_Check(arg)) {
 
424
            for (i = 0; i < n; i++) {
 
425
                PyObject *op = PyList_GET_ITEM(arg, i);
 
426
                double temp = PyFloat_AsDouble(op);
 
427
                ((FLOAT32*)list)[i] = (FLOAT32) temp;
 
428
            }
 
429
        } else {
 
430
            for (i = 0; i < n; i++) {
 
431
                PyObject *op = PySequence_GetItem(arg, i);
 
432
                double temp = PyFloat_AsDouble(op);
 
433
                Py_XDECREF(op);
 
434
                ((FLOAT32*)list)[i] = (FLOAT32) temp;
 
435
            }
 
436
        }
 
437
        break;
 
438
    case TYPE_DOUBLE:
 
439
        if (PyList_Check(arg)) {
 
440
            for (i = 0; i < n; i++) {
 
441
                PyObject *op = PyList_GET_ITEM(arg, i);
 
442
                double temp = PyFloat_AsDouble(op);
 
443
                ((double*)list)[i] = temp;
 
444
            }
 
445
        } else {
 
446
            for (i = 0; i < n; i++) {
 
447
                PyObject *op = PySequence_GetItem(arg, i);
 
448
                double temp = PyFloat_AsDouble(op);
 
449
                Py_XDECREF(op);
 
450
                ((double*)list)[i] = temp;
 
451
            }
 
452
        }
 
453
        break;
 
454
    }
 
455
 
 
456
    if (length)
 
457
        *length = n;
 
458
 
 
459
    PyErr_Clear();
 
460
 
 
461
    return list;
 
462
}
 
463
 
 
464
static inline PyObject*
 
465
getpixel(Imaging im, ImagingAccess access, int x, int y)
 
466
{
 
467
    union {
 
468
      UINT8 b[4];
 
469
      INT16 h;
 
470
      INT32 i;
 
471
      FLOAT32 f;
 
472
    } pixel;
 
473
 
 
474
    if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
 
475
        PyErr_SetString(PyExc_IndexError, outside_image);
 
476
        return NULL;
 
477
    }
 
478
 
 
479
    access->get_pixel(im, x, y, &pixel);
 
480
 
 
481
    switch (im->type) {
 
482
    case IMAGING_TYPE_UINT8:
 
483
      switch (im->bands) {
 
484
      case 1:
 
485
        return PyInt_FromLong(pixel.b[0]);
 
486
      case 2:
 
487
        return Py_BuildValue("ii", pixel.b[0], pixel.b[1]);
 
488
      case 3:
 
489
        return Py_BuildValue("iii", pixel.b[0], pixel.b[1], pixel.b[2]);
 
490
      case 4:
 
491
        return Py_BuildValue("iiii", pixel.b[0], pixel.b[1], pixel.b[2], pixel.b[3]);
 
492
      }
 
493
      break;
 
494
    case IMAGING_TYPE_INT32:
 
495
      return PyInt_FromLong(pixel.i);
 
496
    case IMAGING_TYPE_FLOAT32:
 
497
      return PyFloat_FromDouble(pixel.f);
 
498
    case IMAGING_TYPE_SPECIAL:
 
499
      if (strncmp(im->mode, "I;16", 4) == 0)
 
500
        return PyInt_FromLong(pixel.h);
 
501
      break;
 
502
    }
 
503
 
 
504
    /* unknown type */
 
505
    Py_INCREF(Py_None);
 
506
    return Py_None;
 
507
}
 
508
 
 
509
static char*
 
510
getink(PyObject* color, Imaging im, char* ink)
 
511
{
 
512
    int r, g, b, a;
 
513
    double f;
 
514
 
 
515
    /* fill ink buffer (four bytes) with something that can
 
516
       be cast to either UINT8 or INT32 */
 
517
 
 
518
    switch (im->type) {
 
519
    case IMAGING_TYPE_UINT8:
 
520
        /* unsigned integer */
 
521
        if (im->bands == 1) {
 
522
            /* unsigned integer, single layer */
 
523
            r = PyInt_AsLong(color);
 
524
            if (r == -1 && PyErr_Occurred())
 
525
                return NULL;
 
526
            ink[0] = CLIP(r);
 
527
            ink[1] = ink[2] = ink[3] = 0;
 
528
        } else {
 
529
            a = 255;
 
530
            if (PyInt_Check(color)) {
 
531
                r = PyInt_AS_LONG(color);
 
532
                /* compatibility: ABGR */
 
533
                a = (UINT8) (r >> 24);
 
534
                b = (UINT8) (r >> 16);
 
535
                g = (UINT8) (r >> 8);
 
536
                r = (UINT8) r;
 
537
            } else {
 
538
                if (im->bands == 2) {
 
539
                    if (!PyArg_ParseTuple(color, "i|i", &r, &a))
 
540
                        return NULL;
 
541
                    g = b = r;
 
542
                } else {
 
543
                    if (!PyArg_ParseTuple(color, "iii|i", &r, &g, &b, &a))
 
544
                        return NULL;
 
545
                }
 
546
            }
 
547
            ink[0] = CLIP(r);
 
548
            ink[1] = CLIP(g);
 
549
            ink[2] = CLIP(b);
 
550
            ink[3] = CLIP(a);
 
551
        }
 
552
        return ink;
 
553
    case IMAGING_TYPE_INT32:
 
554
        /* signed integer */
 
555
        r = PyInt_AsLong(color);
 
556
        if (r == -1 && PyErr_Occurred())
 
557
            return NULL;
 
558
        *(INT32*) ink = r;
 
559
        return ink;
 
560
    case IMAGING_TYPE_FLOAT32:
 
561
        /* floating point */
 
562
        f = PyFloat_AsDouble(color);
 
563
        if (f == -1.0 && PyErr_Occurred())
 
564
            return NULL;
 
565
        *(FLOAT32*) ink = (FLOAT32) f;
 
566
        return ink;
 
567
    case IMAGING_TYPE_SPECIAL:
 
568
        if (strncmp(im->mode, "I;16", 4) == 0) {
 
569
            r = PyInt_AsLong(color);
 
570
            if (r == -1 && PyErr_Occurred())
 
571
                return NULL;
 
572
            ink[0] = (UINT8) r;
 
573
            ink[1] = (UINT8) (r >> 8);
 
574
            ink[2] = ink[3] = 0;
 
575
            return ink;
 
576
        }
 
577
    }
 
578
 
 
579
    PyErr_SetString(PyExc_ValueError, wrong_mode);
 
580
    return NULL;
 
581
}
 
582
 
 
583
/* -------------------------------------------------------------------- */
 
584
/* FACTORIES                                                            */
 
585
/* -------------------------------------------------------------------- */
 
586
 
 
587
static PyObject* 
 
588
_fill(PyObject* self, PyObject* args)
 
589
{
 
590
    char* mode;
 
591
    int xsize, ysize;
 
592
    PyObject* color;
 
593
    char buffer[4];
 
594
    Imaging im;
 
595
    
 
596
    xsize = ysize = 256;
 
597
    color = NULL;
 
598
 
 
599
    if (!PyArg_ParseTuple(args, "s|(ii)O", &mode, &xsize, &ysize, &color))
 
600
        return NULL;
 
601
 
 
602
    im = ImagingNew(mode, xsize, ysize);
 
603
    if (!im)
 
604
        return NULL;
 
605
 
 
606
    if (color) {
 
607
        if (!getink(color, im, buffer)) {
 
608
            ImagingDelete(im);
 
609
            return NULL;
 
610
        }
 
611
    } else
 
612
        buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0;
 
613
 
 
614
    (void) ImagingFill(im, buffer);
 
615
 
 
616
    return PyImagingNew(im);
 
617
}
 
618
 
 
619
static PyObject* 
 
620
_new(PyObject* self, PyObject* args)
 
621
{
 
622
    char* mode;
 
623
    int xsize, ysize;
 
624
 
 
625
    if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize))
 
626
        return NULL;
 
627
 
 
628
    return PyImagingNew(ImagingNew(mode, xsize, ysize));
 
629
}
 
630
 
 
631
static PyObject* 
 
632
_new_array(PyObject* self, PyObject* args)
 
633
{
 
634
    char* mode;
 
635
    int xsize, ysize;
 
636
 
 
637
    if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize))
 
638
        return NULL;
 
639
 
 
640
    return PyImagingNew(ImagingNewArray(mode, xsize, ysize));
 
641
}
 
642
 
 
643
static PyObject* 
 
644
_new_block(PyObject* self, PyObject* args)
 
645
{
 
646
    char* mode;
 
647
    int xsize, ysize;
 
648
 
 
649
    if (!PyArg_ParseTuple(args, "s(ii)", &mode, &xsize, &ysize))
 
650
        return NULL;
 
651
 
 
652
    return PyImagingNew(ImagingNewBlock(mode, xsize, ysize));
 
653
}
 
654
 
 
655
static PyObject* 
 
656
_getcount(PyObject* self, PyObject* args)
 
657
{
 
658
    if (!PyArg_ParseTuple(args, ":getcount"))
 
659
        return NULL;
 
660
 
 
661
    return PyInt_FromLong(ImagingNewCount);
 
662
}
 
663
 
 
664
static PyObject* 
 
665
_linear_gradient(PyObject* self, PyObject* args)
 
666
{
 
667
    char* mode;
 
668
 
 
669
    if (!PyArg_ParseTuple(args, "s", &mode))
 
670
        return NULL;
 
671
 
 
672
    return PyImagingNew(ImagingFillLinearGradient(mode));
 
673
}
 
674
 
 
675
static PyObject* 
 
676
_radial_gradient(PyObject* self, PyObject* args)
 
677
{
 
678
    char* mode;
 
679
 
 
680
    if (!PyArg_ParseTuple(args, "s", &mode))
 
681
        return NULL;
 
682
 
 
683
    return PyImagingNew(ImagingFillRadialGradient(mode));
 
684
}
 
685
 
 
686
static PyObject* 
 
687
_open_ppm(PyObject* self, PyObject* args)
 
688
{
 
689
    char* filename;
 
690
 
 
691
    if (!PyArg_ParseTuple(args, "s", &filename))
 
692
        return NULL;
 
693
 
 
694
    return PyImagingNew(ImagingOpenPPM(filename));
 
695
}
 
696
 
 
697
static PyObject* 
 
698
_blend(ImagingObject* self, PyObject* args)
 
699
{
 
700
    ImagingObject* imagep1;
 
701
    ImagingObject* imagep2;
 
702
    double alpha;
 
703
    
 
704
    alpha = 0.5;
 
705
    if (!PyArg_ParseTuple(args, "O!O!|d",
 
706
                          &Imaging_Type, &imagep1,
 
707
                          &Imaging_Type, &imagep2,
 
708
                          &alpha))
 
709
        return NULL;
 
710
 
 
711
    return PyImagingNew(ImagingBlend(imagep1->image, imagep2->image,
 
712
                                     (float) alpha));
 
713
}
 
714
 
 
715
/* -------------------------------------------------------------------- */
 
716
/* METHODS                                                              */
 
717
/* -------------------------------------------------------------------- */
 
718
 
 
719
static PyObject* 
 
720
_convert(ImagingObject* self, PyObject* args)
 
721
{
 
722
    char* mode;
 
723
    int dither = 0;
 
724
    ImagingObject *paletteimage = NULL;
 
725
 
 
726
    if (!PyArg_ParseTuple(args, "s|iO", &mode, &dither, &paletteimage))
 
727
        return NULL;
 
728
    if (paletteimage != NULL) {
 
729
      if (!PyImaging_Check(paletteimage)) {
 
730
        PyObject_Print((PyObject *)paletteimage, stderr, 0);
 
731
        PyErr_SetString(PyExc_ValueError, "palette argument must be image with mode 'P'");
 
732
        return NULL;
 
733
      }
 
734
      if (paletteimage->image->palette == NULL) {
 
735
        PyErr_SetString(PyExc_ValueError, "null palette");
 
736
        return NULL;
 
737
      }
 
738
    }
 
739
 
 
740
    return PyImagingNew(ImagingConvert(self->image, mode, paletteimage ? paletteimage->image->palette : NULL, dither));
 
741
}
 
742
 
 
743
static PyObject* 
 
744
_convert2(ImagingObject* self, PyObject* args)
 
745
{
 
746
    ImagingObject* imagep1;
 
747
    ImagingObject* imagep2;
 
748
    if (!PyArg_ParseTuple(args, "O!O!",
 
749
                          &Imaging_Type, &imagep1,
 
750
                          &Imaging_Type, &imagep2))
 
751
        return NULL;
 
752
 
 
753
    if (!ImagingConvert2(imagep1->image, imagep2->image))
 
754
        return NULL;
 
755
 
 
756
    Py_INCREF(Py_None);
 
757
    return Py_None;
 
758
}
 
759
 
 
760
static PyObject* 
 
761
_convert_matrix(ImagingObject* self, PyObject* args)
 
762
{
 
763
    char* mode;
 
764
    float m[12];
 
765
    if (!PyArg_ParseTuple(args, "s(ffff)", &mode, m+0, m+1, m+2, m+3)) {
 
766
        PyErr_Clear();
 
767
        if (!PyArg_ParseTuple(args, "s(ffffffffffff)", &mode,
 
768
                              m+0, m+1, m+2, m+3,
 
769
                              m+4, m+5, m+6, m+7,
 
770
                              m+8, m+9, m+10, m+11))
 
771
            return NULL;
 
772
    }
 
773
 
 
774
    return PyImagingNew(ImagingConvertMatrix(self->image, mode, m));
 
775
}
 
776
 
 
777
static PyObject* 
 
778
_copy(ImagingObject* self, PyObject* args)
 
779
{
 
780
    if (!PyArg_ParseTuple(args, ""))
 
781
        return NULL;
 
782
 
 
783
    return PyImagingNew(ImagingCopy(self->image));
 
784
}
 
785
 
 
786
static PyObject* 
 
787
_copy2(ImagingObject* self, PyObject* args)
 
788
{
 
789
    ImagingObject* imagep1;
 
790
    ImagingObject* imagep2;
 
791
    if (!PyArg_ParseTuple(args, "O!O!",
 
792
                          &Imaging_Type, &imagep1,
 
793
                          &Imaging_Type, &imagep2))
 
794
        return NULL;
 
795
 
 
796
    if (!ImagingCopy2(imagep1->image, imagep2->image))
 
797
        return NULL;
 
798
 
 
799
    Py_INCREF(Py_None);
 
800
    return Py_None;
 
801
}
 
802
 
 
803
static PyObject* 
 
804
_crop(ImagingObject* self, PyObject* args)
 
805
{
 
806
    int x0, y0, x1, y1;
 
807
    if (!PyArg_ParseTuple(args, "(iiii)", &x0, &y0, &x1, &y1))
 
808
        return NULL;
 
809
 
 
810
    return PyImagingNew(ImagingCrop(self->image, x0, y0, x1, y1));
 
811
}
 
812
 
 
813
static PyObject* 
 
814
_expand(ImagingObject* self, PyObject* args)
 
815
{
 
816
    int x, y;
 
817
    int mode = 0;
 
818
    if (!PyArg_ParseTuple(args, "ii|i", &x, &y, &mode))
 
819
        return NULL;
 
820
 
 
821
    return PyImagingNew(ImagingExpand(self->image, x, y, mode));
 
822
}
 
823
 
 
824
static PyObject* 
 
825
_filter(ImagingObject* self, PyObject* args)
 
826
{
 
827
    PyObject* imOut;
 
828
    int kernelsize;
 
829
    FLOAT32* kerneldata;
 
830
 
 
831
    int xsize, ysize;
 
832
    float divisor, offset;
 
833
    PyObject* kernel = NULL;
 
834
    if (!PyArg_ParseTuple(args, "(ii)ffO", &xsize, &ysize,
 
835
                         &divisor, &offset, &kernel))
 
836
        return NULL;
 
837
    
 
838
    /* get user-defined kernel */
 
839
    kerneldata = getlist(kernel, &kernelsize, NULL, TYPE_FLOAT32);
 
840
    if (!kerneldata)
 
841
        return NULL;
 
842
    if (kernelsize != xsize * ysize) {
 
843
        free(kerneldata);
 
844
        return ImagingError_ValueError("bad kernel size");
 
845
    }
 
846
 
 
847
    imOut = PyImagingNew(
 
848
        ImagingFilter(self->image, xsize, ysize, kerneldata, offset, divisor)
 
849
        );
 
850
 
 
851
    free(kerneldata);
 
852
 
 
853
    return imOut;
 
854
}
 
855
 
 
856
#ifdef WITH_UNSHARPMASK
 
857
static PyObject* 
 
858
_gaussian_blur(ImagingObject* self, PyObject* args)
 
859
{
 
860
    Imaging imIn;
 
861
    Imaging imOut;
 
862
 
 
863
    float radius = 0;
 
864
    if (!PyArg_ParseTuple(args, "f", &radius))
 
865
        return NULL;
 
866
 
 
867
    imIn = self->image;
 
868
    imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
 
869
    if (!imOut)
 
870
        return NULL;
 
871
 
 
872
    if (!ImagingGaussianBlur(imIn, imOut, radius))
 
873
        return NULL;
 
874
 
 
875
    return PyImagingNew(imOut);
 
876
}
 
877
#endif
 
878
 
 
879
static PyObject* 
 
880
_getpalette(ImagingObject* self, PyObject* args)
 
881
{
 
882
    PyObject* palette;
 
883
    int palettesize = 256;
 
884
    int bits;
 
885
    ImagingShuffler pack;
 
886
 
 
887
    char* mode = "RGB";
 
888
    char* rawmode = "RGB";
 
889
    if (!PyArg_ParseTuple(args, "|ss", &mode, &rawmode))
 
890
        return NULL;
 
891
 
 
892
    if (!self->image->palette) {
 
893
        PyErr_SetString(PyExc_ValueError, no_palette);
 
894
        return NULL;
 
895
    }
 
896
 
 
897
    pack = ImagingFindPacker(mode, rawmode, &bits);
 
898
    if (!pack) {
 
899
        PyErr_SetString(PyExc_ValueError, wrong_raw_mode);
 
900
        return NULL;
 
901
    }
 
902
 
 
903
    palette = PyString_FromStringAndSize(NULL, palettesize * bits / 8);
 
904
    if (!palette)
 
905
        return NULL;
 
906
 
 
907
    pack((UINT8*) PyString_AsString(palette),
 
908
         self->image->palette->palette, palettesize);
 
909
 
 
910
    return palette;
 
911
}
 
912
 
 
913
static inline int
 
914
_getxy(PyObject* xy, int* x, int *y)
 
915
{
 
916
    PyObject* value;
 
917
 
 
918
    if (!PyTuple_Check(xy) || PyTuple_GET_SIZE(xy) != 2)
 
919
        goto badarg;
 
920
        
 
921
    value = PyTuple_GET_ITEM(xy, 0);
 
922
    if (PyInt_Check(value))
 
923
        *x = PyInt_AS_LONG(value);
 
924
    else if (PyFloat_Check(value))
 
925
        *x = (int) PyFloat_AS_DOUBLE(value);
 
926
    else
 
927
        goto badval;
 
928
 
 
929
    value = PyTuple_GET_ITEM(xy, 1);
 
930
    if (PyInt_Check(value))
 
931
        *y = PyInt_AS_LONG(value);
 
932
    else if (PyFloat_Check(value))
 
933
        *y = (int) PyFloat_AS_DOUBLE(value);
 
934
    else
 
935
        goto badval;
 
936
 
 
937
    return 0;
 
938
 
 
939
  badarg:
 
940
    PyErr_SetString(
 
941
        PyExc_TypeError,
 
942
        "argument must be sequence of length 2"
 
943
        );
 
944
    return -1;
 
945
 
 
946
  badval:
 
947
    PyErr_SetString(
 
948
        PyExc_TypeError,
 
949
        "an integer is required"
 
950
        );
 
951
    return -1;
 
952
}
 
953
 
 
954
static PyObject* 
 
955
_getpixel(ImagingObject* self, PyObject* args)
 
956
{
 
957
    PyObject* xy;
 
958
    int x, y;
 
959
 
 
960
    if (PyTuple_GET_SIZE(args) != 1) {
 
961
        PyErr_SetString(
 
962
            PyExc_TypeError,
 
963
            "argument 1 must be sequence of length 2"
 
964
            );
 
965
        return NULL;
 
966
    }
 
967
 
 
968
    xy = PyTuple_GET_ITEM(args, 0);
 
969
 
 
970
    if (_getxy(xy, &x, &y))
 
971
        return NULL;
 
972
 
 
973
    if (self->access == NULL) {
 
974
        Py_INCREF(Py_None);
 
975
        return Py_None;
 
976
    }
 
977
 
 
978
    return getpixel(self->image, self->access, x, y);
 
979
}
 
980
 
 
981
static PyObject*
 
982
_histogram(ImagingObject* self, PyObject* args)
 
983
{
 
984
    ImagingHistogram h;
 
985
    PyObject* list;
 
986
    int i;
 
987
    union {
 
988
        UINT8 u[2];
 
989
        INT32 i[2];
 
990
        FLOAT32 f[2];
 
991
    } extrema;
 
992
    void* ep;
 
993
    int i0, i1;
 
994
    double f0, f1;
 
995
 
 
996
    PyObject* extremap = NULL;
 
997
    ImagingObject* maskp = NULL;
 
998
    if (!PyArg_ParseTuple(args, "|OO!", &extremap, &Imaging_Type, &maskp))
 
999
        return NULL;
 
1000
 
 
1001
    if (extremap) {
 
1002
        ep = &extrema;
 
1003
        switch (self->image->type) {
 
1004
        case IMAGING_TYPE_UINT8:
 
1005
            if (!PyArg_ParseTuple(extremap, "ii", &i0, &i1))
 
1006
                return NULL;
 
1007
            /* FIXME: clip */
 
1008
            extrema.u[0] = i0;
 
1009
            extrema.u[1] = i1;
 
1010
            break;
 
1011
        case IMAGING_TYPE_INT32:
 
1012
            if (!PyArg_ParseTuple(extremap, "ii", &i0, &i1))
 
1013
                return NULL;
 
1014
            extrema.i[0] = i0;
 
1015
            extrema.i[1] = i1;
 
1016
            break;
 
1017
        case IMAGING_TYPE_FLOAT32:
 
1018
            if (!PyArg_ParseTuple(extremap, "dd", &f0, &f1))
 
1019
                return NULL;
 
1020
            extrema.f[0] = (FLOAT32) f0;
 
1021
            extrema.f[1] = (FLOAT32) f1;
 
1022
            break;
 
1023
        default:
 
1024
            ep = NULL;
 
1025
            break;
 
1026
        }
 
1027
    } else
 
1028
        ep = NULL;
 
1029
 
 
1030
    h = ImagingGetHistogram(self->image, (maskp) ? maskp->image : NULL, ep);
 
1031
 
 
1032
    if (!h)
 
1033
        return NULL;
 
1034
 
 
1035
    /* Build an integer list containing the histogram */
 
1036
    list = PyList_New(h->bands * 256);
 
1037
    for (i = 0; i < h->bands * 256; i++) {
 
1038
        PyObject* item;
 
1039
        item = PyInt_FromLong(h->histogram[i]);
 
1040
        if (item == NULL) {
 
1041
            Py_DECREF(list);
 
1042
            list = NULL;
 
1043
            break;
 
1044
        }
 
1045
        PyList_SetItem(list, i, item);
 
1046
    }
 
1047
 
 
1048
    ImagingHistogramDelete(h);
 
1049
 
 
1050
    return list;
 
1051
}
 
1052
 
 
1053
#ifdef WITH_MODEFILTER
 
1054
static PyObject* 
 
1055
_modefilter(ImagingObject* self, PyObject* args)
 
1056
{
 
1057
    int size;
 
1058
    if (!PyArg_ParseTuple(args, "i", &size))
 
1059
        return NULL;
 
1060
 
 
1061
    return PyImagingNew(ImagingModeFilter(self->image, size));
 
1062
}
 
1063
#endif
 
1064
 
 
1065
static PyObject* 
 
1066
_offset(ImagingObject* self, PyObject* args)
 
1067
{
 
1068
    int xoffset, yoffset;
 
1069
    if (!PyArg_ParseTuple(args, "ii", &xoffset, &yoffset))
 
1070
        return NULL;
 
1071
 
 
1072
    return PyImagingNew(ImagingOffset(self->image, xoffset, yoffset));
 
1073
}
 
1074
 
 
1075
static PyObject* 
 
1076
_paste(ImagingObject* self, PyObject* args)
 
1077
{
 
1078
    int status;
 
1079
    char ink[4];
 
1080
 
 
1081
    PyObject* source;
 
1082
    int x0, y0, x1, y1;
 
1083
    ImagingObject* maskp = NULL;
 
1084
    if (!PyArg_ParseTuple(args, "O(iiii)|O!",
 
1085
                          &source,
 
1086
                          &x0, &y0, &x1, &y1,
 
1087
                          &Imaging_Type, &maskp))
 
1088
        return NULL;
 
1089
 
 
1090
    if (PyImaging_Check(source))
 
1091
        status = ImagingPaste(
 
1092
            self->image, PyImaging_AsImaging(source),
 
1093
            (maskp) ? maskp->image : NULL,
 
1094
            x0, y0, x1, y1
 
1095
            );
 
1096
 
 
1097
    else {
 
1098
        if (!getink(source, self->image, ink))
 
1099
            return NULL;
 
1100
        status = ImagingFill2(
 
1101
            self->image, ink,
 
1102
            (maskp) ? maskp->image : NULL,
 
1103
            x0, y0, x1, y1
 
1104
            );
 
1105
    }
 
1106
 
 
1107
    if (status < 0)
 
1108
        return NULL;
 
1109
 
 
1110
    Py_INCREF(Py_None);
 
1111
    return Py_None;
 
1112
}
 
1113
 
 
1114
static PyObject*
 
1115
_point(ImagingObject* self, PyObject* args)
 
1116
{
 
1117
    static const char* wrong_number = "wrong number of lut entries";
 
1118
 
 
1119
    int n, i;
 
1120
    int bands;
 
1121
    Imaging im;
 
1122
 
 
1123
    PyObject* list;
 
1124
    char* mode;
 
1125
    if (!PyArg_ParseTuple(args, "Oz", &list, &mode))
 
1126
        return NULL;
 
1127
 
 
1128
    if (mode && !strcmp(mode, "F")) {
 
1129
        FLOAT32* data;
 
1130
 
 
1131
        /* map from 8-bit data to floating point */
 
1132
        n = 256;
 
1133
        data = getlist(list, &n, wrong_number, TYPE_FLOAT32);
 
1134
        if (!data)
 
1135
            return NULL;
 
1136
        im = ImagingPoint(self->image, mode, (void*) data);
 
1137
        free(data);
 
1138
 
 
1139
    } else if (!strcmp(self->image->mode, "I") && mode && !strcmp(mode, "L")) {
 
1140
        UINT8* data;
 
1141
 
 
1142
        /* map from 16-bit subset of 32-bit data to 8-bit */
 
1143
        /* FIXME: support arbitrary number of entries (requires API change) */
 
1144
        n = 65536;
 
1145
        data = getlist(list, &n, wrong_number, TYPE_UINT8);
 
1146
        if (!data)
 
1147
            return NULL;
 
1148
        im = ImagingPoint(self->image, mode, (void*) data);
 
1149
        free(data);
 
1150
 
 
1151
    } else {
 
1152
        INT32* data;
 
1153
        UINT8 lut[1024];
 
1154
 
 
1155
        if (mode) {
 
1156
            bands = getbands(mode);
 
1157
            if (bands < 0)
 
1158
                return NULL;
 
1159
        } else
 
1160
            bands = self->image->bands;
 
1161
 
 
1162
        /* map to integer data */
 
1163
        n = 256 * bands;
 
1164
        data = getlist(list, &n, wrong_number, TYPE_INT32);
 
1165
        if (!data)
 
1166
            return NULL;
 
1167
 
 
1168
        if (mode && !strcmp(mode, "I"))
 
1169
            im = ImagingPoint(self->image, mode, (void*) data);
 
1170
        else if (mode && bands > 1) {
 
1171
            for (i = 0; i < 256; i++) {
 
1172
                lut[i*4] = CLIP(data[i]);
 
1173
                lut[i*4+1] = CLIP(data[i+256]);
 
1174
                lut[i*4+2] = CLIP(data[i+512]);
 
1175
                if (n > 768)
 
1176
                    lut[i*4+3] = CLIP(data[i+768]);
 
1177
            }
 
1178
            im = ImagingPoint(self->image, mode, (void*) lut);
 
1179
        } else {
 
1180
            /* map individual bands */
 
1181
            for (i = 0; i < n; i++)
 
1182
                lut[i] = CLIP(data[i]);
 
1183
            im = ImagingPoint(self->image, mode, (void*) lut);
 
1184
        }
 
1185
        free(data);
 
1186
    }
 
1187
 
 
1188
    return PyImagingNew(im);
 
1189
}
 
1190
 
 
1191
static PyObject*
 
1192
_point_transform(ImagingObject* self, PyObject* args)
 
1193
{
 
1194
    double scale = 1.0;
 
1195
    double offset = 0.0;
 
1196
    if (!PyArg_ParseTuple(args, "|dd", &scale, &offset))
 
1197
        return NULL;
 
1198
 
 
1199
    return PyImagingNew(ImagingPointTransform(self->image, scale, offset));
 
1200
}
 
1201
 
 
1202
static PyObject*
 
1203
_putdata(ImagingObject* self, PyObject* args)
 
1204
{
 
1205
    Imaging image;
 
1206
    int n, i, x, y;
 
1207
 
 
1208
    PyObject* data;
 
1209
    double scale = 1.0;
 
1210
    double offset = 0.0;
 
1211
    if (!PyArg_ParseTuple(args, "O|dd", &data, &scale, &offset))
 
1212
        return NULL;
 
1213
 
 
1214
    if (!PySequence_Check(data)) {
 
1215
        PyErr_SetString(PyExc_TypeError, must_be_sequence);
 
1216
        return NULL;
 
1217
    }
 
1218
 
 
1219
    image = self->image;
 
1220
 
 
1221
    n = PyObject_Length(data);
 
1222
    if (n > (int) (image->xsize * image->ysize)) {
 
1223
        PyErr_SetString(PyExc_TypeError, "too many data entries");
 
1224
        return NULL;
 
1225
    }
 
1226
 
 
1227
    if (image->image8) {
 
1228
        if (PyString_Check(data)) {
 
1229
            unsigned char* p;
 
1230
            p = (unsigned char*) PyString_AS_STRING((PyStringObject*) data);
 
1231
            if (scale == 1.0 && offset == 0.0)
 
1232
                /* Plain string data */
 
1233
                for (i = y = 0; i < n; i += image->xsize, y++) {
 
1234
                    x = n - i;
 
1235
                    if (x > (int) image->xsize)
 
1236
                        x = image->xsize;
 
1237
                    memcpy(image->image8[y], p+i, x);
 
1238
                }
 
1239
            else 
 
1240
                /* Scaled and clipped string data */
 
1241
                for (i = x = y = 0; i < n; i++) {
 
1242
                    image->image8[y][x] = CLIP((int) (p[i] * scale + offset));
 
1243
                    if (++x >= (int) image->xsize)
 
1244
                        x = 0, y++;
 
1245
                }
 
1246
        } else {
 
1247
            if (scale == 1.0 && offset == 0.0) {
 
1248
                /* Clipped data */
 
1249
                if (PyList_Check(data)) {
 
1250
                    for (i = x = y = 0; i < n; i++) {
 
1251
                        PyObject *op = PyList_GET_ITEM(data, i);
 
1252
                        image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op));
 
1253
                        if (++x >= (int) image->xsize)
 
1254
                            x = 0, y++;
 
1255
                    }
 
1256
                } else {
 
1257
                    for (i = x = y = 0; i < n; i++) {
 
1258
                        PyObject *op = PySequence_GetItem(data, i);
 
1259
                        image->image8[y][x] = (UINT8) CLIP(PyInt_AsLong(op));
 
1260
                        Py_XDECREF(op);
 
1261
                        if (++x >= (int) image->xsize)
 
1262
                            x = 0, y++;
 
1263
                    }
 
1264
                }
 
1265
            } else {
 
1266
                if (PyList_Check(data)) {
 
1267
                    /* Scaled and clipped data */
 
1268
                    for (i = x = y = 0; i < n; i++) {
 
1269
                        PyObject *op = PyList_GET_ITEM(data, i);
 
1270
                        image->image8[y][x] = CLIP(
 
1271
                            (int) (PyFloat_AsDouble(op) * scale + offset));
 
1272
                        if (++x >= (int) image->xsize)
 
1273
                            x = 0, y++;
 
1274
                    }
 
1275
                } else {
 
1276
                    for (i = x = y = 0; i < n; i++) {
 
1277
                        PyObject *op = PySequence_GetItem(data, i);
 
1278
                        image->image8[y][x] = CLIP(
 
1279
                            (int) (PyFloat_AsDouble(op) * scale + offset));
 
1280
                        Py_XDECREF(op);
 
1281
                        if (++x >= (int) image->xsize)
 
1282
                            x = 0, y++;
 
1283
                    }
 
1284
                }
 
1285
            }
 
1286
            PyErr_Clear(); /* Avoid weird exceptions */
 
1287
        }
 
1288
    } else {
 
1289
        /* 32-bit images */
 
1290
        switch (image->type) {
 
1291
        case IMAGING_TYPE_INT32:
 
1292
            for (i = x = y = 0; i < n; i++) {
 
1293
                PyObject *op = PySequence_GetItem(data, i);
 
1294
                IMAGING_PIXEL_INT32(image, x, y) =
 
1295
                    (INT32) (PyFloat_AsDouble(op) * scale + offset);
 
1296
                Py_XDECREF(op);
 
1297
                if (++x >= (int) image->xsize)
 
1298
                    x = 0, y++;
 
1299
            }
 
1300
            PyErr_Clear(); /* Avoid weird exceptions */
 
1301
            break;
 
1302
        case IMAGING_TYPE_FLOAT32:
 
1303
            for (i = x = y = 0; i < n; i++) {
 
1304
                PyObject *op = PySequence_GetItem(data, i);
 
1305
                IMAGING_PIXEL_FLOAT32(image, x, y) =
 
1306
                    (FLOAT32) (PyFloat_AsDouble(op) * scale + offset);
 
1307
                Py_XDECREF(op);
 
1308
                if (++x >= (int) image->xsize)
 
1309
                    x = 0, y++;
 
1310
            }
 
1311
            PyErr_Clear(); /* Avoid weird exceptions */
 
1312
            break;
 
1313
        default:
 
1314
            for (i = x = y = 0; i < n; i++) {
 
1315
                char ink[4];
 
1316
                PyObject *op = PySequence_GetItem(data, i);
 
1317
                if (!op || !getink(op, image, ink)) {
 
1318
                    Py_DECREF(op);
 
1319
                    return NULL;
 
1320
                }
 
1321
                /* FIXME: what about scale and offset? */
 
1322
                image->image32[y][x] = *((INT32*) ink);
 
1323
                Py_XDECREF(op);
 
1324
                if (++x >= (int) image->xsize)
 
1325
                    x = 0, y++;
 
1326
            }
 
1327
            PyErr_Clear(); /* Avoid weird exceptions */
 
1328
            break;
 
1329
        }
 
1330
    }
 
1331
 
 
1332
    Py_INCREF(Py_None);
 
1333
    return Py_None;
 
1334
}
 
1335
 
 
1336
#ifdef WITH_QUANTIZE
 
1337
 
 
1338
#include "Quant.h"
 
1339
static PyObject* 
 
1340
_quantize(ImagingObject* self, PyObject* args)
 
1341
{
 
1342
    int colours = 256;
 
1343
    int method = 0;
 
1344
    int kmeans = 0;
 
1345
    if (!PyArg_ParseTuple(args, "|iii", &colours, &method, &kmeans))
 
1346
        return NULL;
 
1347
 
 
1348
    if (!self->image->xsize || !self->image->ysize) {
 
1349
        /* no content; return an empty image */
 
1350
        return PyImagingNew(
 
1351
            ImagingNew("P", self->image->xsize, self->image->ysize)
 
1352
            );
 
1353
    }
 
1354
 
 
1355
    return PyImagingNew(ImagingQuantize(self->image, colours, method, kmeans));
 
1356
}
 
1357
#endif
 
1358
 
 
1359
static PyObject* 
 
1360
_putpalette(ImagingObject* self, PyObject* args)
 
1361
{
 
1362
    ImagingShuffler unpack;
 
1363
    int bits;
 
1364
 
 
1365
    char* rawmode;
 
1366
    UINT8* palette;
 
1367
    int palettesize;
 
1368
    if (!PyArg_ParseTuple(args, "ss#", &rawmode, &palette, &palettesize))
 
1369
        return NULL;
 
1370
 
 
1371
    if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) {
 
1372
        PyErr_SetString(PyExc_ValueError, wrong_mode);
 
1373
        return NULL;
 
1374
    }
 
1375
 
 
1376
    unpack = ImagingFindUnpacker("RGB", rawmode, &bits);
 
1377
    if (!unpack) {
 
1378
        PyErr_SetString(PyExc_ValueError, wrong_raw_mode);
 
1379
        return NULL;
 
1380
    }
 
1381
 
 
1382
    ImagingPaletteDelete(self->image->palette);
 
1383
 
 
1384
    strcpy(self->image->mode, "P");
 
1385
 
 
1386
    self->image->palette = ImagingPaletteNew("RGB");
 
1387
 
 
1388
    unpack(self->image->palette->palette, palette, palettesize * 8 / bits);
 
1389
 
 
1390
    Py_INCREF(Py_None);
 
1391
    return Py_None;
 
1392
}
 
1393
 
 
1394
static PyObject* 
 
1395
_putpalettealpha(ImagingObject* self, PyObject* args)
 
1396
{
 
1397
    int index;
 
1398
    int alpha = 0;
 
1399
    if (!PyArg_ParseTuple(args, "i|i", &index, &alpha))
 
1400
        return NULL;
 
1401
 
 
1402
    if (!self->image->palette) {
 
1403
        PyErr_SetString(PyExc_ValueError, no_palette);
 
1404
        return NULL;
 
1405
    }
 
1406
 
 
1407
    if (index < 0 || index >= 256) {
 
1408
        PyErr_SetString(PyExc_ValueError, outside_palette);
 
1409
        return NULL;
 
1410
    }
 
1411
 
 
1412
    strcpy(self->image->palette->mode, "RGBA");
 
1413
    self->image->palette->palette[index*4+3] = (UINT8) alpha;
 
1414
 
 
1415
    Py_INCREF(Py_None);
 
1416
    return Py_None;
 
1417
}
 
1418
 
 
1419
static PyObject* 
 
1420
_putpixel(ImagingObject* self, PyObject* args)
 
1421
{
 
1422
    Imaging im;
 
1423
    char ink[4];
 
1424
 
 
1425
    int x, y;
 
1426
    PyObject* color;
 
1427
    if (!PyArg_ParseTuple(args, "(ii)O", &x, &y, &color))
 
1428
        return NULL;
 
1429
 
 
1430
    im = self->image;
 
1431
    
 
1432
    if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
 
1433
        PyErr_SetString(PyExc_IndexError, outside_image);
 
1434
        return NULL;
 
1435
    }
 
1436
 
 
1437
    if (!getink(color, im, ink))
 
1438
        return NULL;
 
1439
 
 
1440
    if (self->access)
 
1441
        self->access->put_pixel(im, x, y, ink);
 
1442
 
 
1443
    Py_INCREF(Py_None);
 
1444
    return Py_None;
 
1445
}
 
1446
 
 
1447
#ifdef WITH_RANKFILTER
 
1448
static PyObject* 
 
1449
_rankfilter(ImagingObject* self, PyObject* args)
 
1450
{
 
1451
    int size, rank;
 
1452
    if (!PyArg_ParseTuple(args, "ii", &size, &rank))
 
1453
        return NULL;
 
1454
 
 
1455
    return PyImagingNew(ImagingRankFilter(self->image, size, rank));
 
1456
}
 
1457
#endif
 
1458
 
 
1459
static PyObject* 
 
1460
_resize(ImagingObject* self, PyObject* args)
 
1461
{
 
1462
    Imaging imIn;
 
1463
    Imaging imOut;
 
1464
 
 
1465
    int xsize, ysize;
 
1466
    int filter = IMAGING_TRANSFORM_NEAREST;
 
1467
    if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter))
 
1468
        return NULL;
 
1469
 
 
1470
    imIn = self->image;
 
1471
 
 
1472
    imOut = ImagingNew(imIn->mode, xsize, ysize);
 
1473
    if (imOut)
 
1474
        (void) ImagingResize(imOut, imIn, filter);
 
1475
    
 
1476
    return PyImagingNew(imOut);
 
1477
}
 
1478
 
 
1479
static PyObject* 
 
1480
_rotate(ImagingObject* self, PyObject* args)
 
1481
{
 
1482
    Imaging imOut;
 
1483
    Imaging imIn;
 
1484
    
 
1485
    double theta;
 
1486
    int filter = IMAGING_TRANSFORM_NEAREST;
 
1487
    if (!PyArg_ParseTuple(args, "d|i", &theta, &filter))
 
1488
        return NULL;
 
1489
 
 
1490
    imIn = self->image;
 
1491
 
 
1492
    theta = fmod(theta, 360.0);
 
1493
    if (theta < 0.0)
 
1494
        theta += 360;
 
1495
 
 
1496
    if (filter && imIn->type != IMAGING_TYPE_SPECIAL) {
 
1497
        /* Rotate with resampling filter */
 
1498
        imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
 
1499
        (void) ImagingRotate(imOut, imIn, theta, filter);
 
1500
    } else if (theta == 90.0 || theta == 270.0) {
 
1501
        /* Use fast version */
 
1502
        imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize);
 
1503
        if (imOut) {
 
1504
            if (theta == 90.0)
 
1505
                (void) ImagingRotate90(imOut, imIn);
 
1506
            else
 
1507
                (void) ImagingRotate270(imOut, imIn);
 
1508
        }
 
1509
    } else {
 
1510
        imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
 
1511
        if (imOut) {
 
1512
            if (theta == 0.0)
 
1513
                /* No rotation: simply copy the input image */
 
1514
                (void) ImagingCopy2(imOut, imIn);
 
1515
            else if (theta == 180.0)
 
1516
                /* Use fast version */
 
1517
                (void) ImagingRotate180(imOut, imIn);
 
1518
            else
 
1519
                /* Use ordinary version */
 
1520
                (void) ImagingRotate(imOut, imIn, theta, 0);
 
1521
        }
 
1522
    }
 
1523
 
 
1524
    return PyImagingNew(imOut);
 
1525
}
 
1526
 
 
1527
#define IS_RGB(mode)\
 
1528
    (!strcmp(mode, "RGB") || !strcmp(mode, "RGBA") || !strcmp(mode, "RGBX"))
 
1529
 
 
1530
static PyObject* 
 
1531
im_setmode(ImagingObject* self, PyObject* args)
 
1532
{
 
1533
    /* attempt to modify the mode of an image in place */
 
1534
 
 
1535
    Imaging im;
 
1536
 
 
1537
    char* mode;
 
1538
    int modelen;
 
1539
    if (!PyArg_ParseTuple(args, "s#:setmode", &mode, &modelen))
 
1540
        return NULL;
 
1541
 
 
1542
    im = self->image;
 
1543
 
 
1544
    /* move all logic in here to the libImaging primitive */
 
1545
 
 
1546
    if (!strcmp(im->mode, mode)) {
 
1547
        ; /* same mode; always succeeds */
 
1548
    } else if (IS_RGB(im->mode) && IS_RGB(mode)) {
 
1549
        /* color to color */
 
1550
        strcpy(im->mode, mode);
 
1551
        im->bands = modelen;
 
1552
        if (!strcmp(mode, "RGBA"))
 
1553
            (void) ImagingFillBand(im, 3, 255);
 
1554
    } else {
 
1555
        /* trying doing an in-place conversion */
 
1556
        if (!ImagingConvertInPlace(im, mode))
 
1557
            return NULL;
 
1558
    }
 
1559
 
 
1560
    if (self->access)
 
1561
        ImagingAccessDelete(im, self->access);
 
1562
    self->access = ImagingAccessNew(im);
 
1563
 
 
1564
    Py_INCREF(Py_None);
 
1565
    return Py_None;
 
1566
}
 
1567
 
 
1568
static PyObject* 
 
1569
_stretch(ImagingObject* self, PyObject* args)
 
1570
{
 
1571
    Imaging imIn;
 
1572
    Imaging imTemp;
 
1573
    Imaging imOut;
 
1574
 
 
1575
    int xsize, ysize;
 
1576
    int filter = IMAGING_TRANSFORM_NEAREST;
 
1577
    if (!PyArg_ParseTuple(args, "(ii)|i", &xsize, &ysize, &filter))
 
1578
        return NULL;
 
1579
 
 
1580
    imIn = self->image;
 
1581
 
 
1582
    /* two-pass resize: minimize size of intermediate image */
 
1583
    if (imIn->xsize * ysize < xsize * imIn->ysize)
 
1584
        imTemp = ImagingNew(imIn->mode, imIn->xsize, ysize);
 
1585
    else 
 
1586
        imTemp = ImagingNew(imIn->mode, xsize, imIn->ysize);
 
1587
    if (!imTemp)
 
1588
        return NULL;
 
1589
 
 
1590
    /* first pass */
 
1591
    if (!ImagingStretch(imTemp, imIn, filter)) {
 
1592
        ImagingDelete(imTemp);
 
1593
        return NULL;
 
1594
    }
 
1595
 
 
1596
    imOut = ImagingNew(imIn->mode, xsize, ysize);
 
1597
    if (!imOut) {
 
1598
        ImagingDelete(imTemp);
 
1599
        return NULL;
 
1600
    }
 
1601
 
 
1602
    /* second pass */
 
1603
    if (!ImagingStretch(imOut, imTemp, filter)) {
 
1604
        ImagingDelete(imOut);
 
1605
        ImagingDelete(imTemp);
 
1606
        return NULL;
 
1607
    }
 
1608
 
 
1609
    ImagingDelete(imTemp);
 
1610
    
 
1611
    return PyImagingNew(imOut);
 
1612
}
 
1613
 
 
1614
static PyObject* 
 
1615
_transform2(ImagingObject* self, PyObject* args)
 
1616
{
 
1617
    static const char* wrong_number = "wrong number of matrix entries";
 
1618
 
 
1619
    Imaging imIn;
 
1620
    Imaging imOut;
 
1621
    int n;
 
1622
    double *a;
 
1623
 
 
1624
    ImagingObject* imagep;
 
1625
    int x0, y0, x1, y1;
 
1626
    int method;
 
1627
    PyObject* data;
 
1628
    int filter = IMAGING_TRANSFORM_NEAREST;
 
1629
    int fill = 1;
 
1630
    if (!PyArg_ParseTuple(args, "(iiii)O!iO|ii",
 
1631
                          &x0, &y0, &x1, &y1,
 
1632
                          &Imaging_Type, &imagep,
 
1633
                          &method, &data,
 
1634
                          &filter, &fill))
 
1635
        return NULL;
 
1636
 
 
1637
    switch (method) {
 
1638
    case IMAGING_TRANSFORM_AFFINE:
 
1639
        n = 6;
 
1640
        break;
 
1641
    case IMAGING_TRANSFORM_PERSPECTIVE:
 
1642
        n = 8;
 
1643
        break;
 
1644
    case IMAGING_TRANSFORM_QUAD:
 
1645
        n = 8;
 
1646
        break;
 
1647
    default:
 
1648
        n = -1; /* force error */
 
1649
    }
 
1650
 
 
1651
    a = getlist(data, &n, wrong_number, TYPE_DOUBLE);
 
1652
    if (!a)
 
1653
        return NULL;
 
1654
 
 
1655
    imOut = self->image;
 
1656
    imIn = imagep->image;
 
1657
 
 
1658
    /* FIXME: move transform dispatcher into libImaging */
 
1659
 
 
1660
    switch (method) {
 
1661
    case IMAGING_TRANSFORM_AFFINE:
 
1662
        imOut = ImagingTransformAffine(
 
1663
            imOut, imIn, x0, y0, x1, y1, a, filter, 1
 
1664
            );
 
1665
        break;
 
1666
    case IMAGING_TRANSFORM_PERSPECTIVE:
 
1667
        imOut = ImagingTransformPerspective(
 
1668
            imOut, imIn, x0, y0, x1, y1, a, filter, 1
 
1669
            );
 
1670
        break;
 
1671
    case IMAGING_TRANSFORM_QUAD:
 
1672
        imOut = ImagingTransformQuad(
 
1673
            imOut, imIn, x0, y0, x1, y1, a, filter, 1
 
1674
            );
 
1675
        break;
 
1676
    default:
 
1677
        (void) ImagingError_ValueError("bad transform method");
 
1678
    }
 
1679
 
 
1680
    free(a);
 
1681
 
 
1682
    if (!imOut)
 
1683
        return NULL;
 
1684
 
 
1685
    Py_INCREF(Py_None);
 
1686
    return Py_None;
 
1687
}
 
1688
 
 
1689
static PyObject* 
 
1690
_transpose(ImagingObject* self, PyObject* args)
 
1691
{
 
1692
    Imaging imIn;
 
1693
    Imaging imOut;
 
1694
 
 
1695
    int op;
 
1696
    if (!PyArg_ParseTuple(args, "i", &op))
 
1697
        return NULL;
 
1698
 
 
1699
    imIn = self->image;
 
1700
    
 
1701
    switch (op) {
 
1702
    case 0: /* flip left right */
 
1703
    case 1: /* flip top bottom */
 
1704
    case 3: /* rotate 180 */
 
1705
        imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
 
1706
        break;
 
1707
    case 2: /* rotate 90 */
 
1708
    case 4: /* rotate 270 */
 
1709
        imOut = ImagingNew(imIn->mode, imIn->ysize, imIn->xsize);
 
1710
        break;
 
1711
    default:
 
1712
        PyErr_SetString(PyExc_ValueError, "No such transpose operation");
 
1713
        return NULL;
 
1714
    }
 
1715
 
 
1716
    if (imOut)
 
1717
        switch (op) {
 
1718
        case 0:
 
1719
            (void) ImagingFlipLeftRight(imOut, imIn);
 
1720
            break;
 
1721
        case 1:
 
1722
            (void) ImagingFlipTopBottom(imOut, imIn);
 
1723
            break;
 
1724
        case 2:
 
1725
            (void) ImagingRotate90(imOut, imIn);
 
1726
            break;
 
1727
        case 3:
 
1728
            (void) ImagingRotate180(imOut, imIn);
 
1729
            break;
 
1730
        case 4:
 
1731
            (void) ImagingRotate270(imOut, imIn);
 
1732
            break;
 
1733
        }
 
1734
 
 
1735
    return PyImagingNew(imOut);
 
1736
}
 
1737
 
 
1738
#ifdef WITH_UNSHARPMASK
 
1739
static PyObject* 
 
1740
_unsharp_mask(ImagingObject* self, PyObject* args)
 
1741
{
 
1742
    Imaging imIn;
 
1743
    Imaging imOut;
 
1744
 
 
1745
    float radius;
 
1746
    int percent, threshold;
 
1747
    if (!PyArg_ParseTuple(args, "fii", &radius, &percent, &threshold))
 
1748
        return NULL;
 
1749
 
 
1750
 
 
1751
    imIn = self->image;
 
1752
    imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
 
1753
    if (!imOut)
 
1754
        return NULL;
 
1755
 
 
1756
    if (!ImagingUnsharpMask(imIn, imOut, radius, percent, threshold))
 
1757
        return NULL;
 
1758
 
 
1759
    return PyImagingNew(imOut);
 
1760
}
 
1761
#endif
 
1762
 
 
1763
/* -------------------------------------------------------------------- */
 
1764
 
 
1765
static PyObject* 
 
1766
_isblock(ImagingObject* self, PyObject* args)
 
1767
{
 
1768
    return PyInt_FromLong((long) self->image->block);
 
1769
}
 
1770
 
 
1771
static PyObject* 
 
1772
_getbbox(ImagingObject* self, PyObject* args)
 
1773
{
 
1774
    int bbox[4];
 
1775
    if (!ImagingGetBBox(self->image, bbox)) {
 
1776
        Py_INCREF(Py_None);
 
1777
        return Py_None;
 
1778
    }
 
1779
 
 
1780
    return Py_BuildValue("iiii", bbox[0], bbox[1], bbox[2], bbox[3]);
 
1781
}
 
1782
 
 
1783
static PyObject* 
 
1784
_getcolors(ImagingObject* self, PyObject* args)
 
1785
{
 
1786
    ImagingColorItem* items;
 
1787
    int i, colors;
 
1788
    PyObject* out;
 
1789
 
 
1790
    int maxcolors = 256;
 
1791
    if (!PyArg_ParseTuple(args, "i:getcolors", &maxcolors))
 
1792
        return NULL;
 
1793
 
 
1794
    items = ImagingGetColors(self->image, maxcolors, &colors);
 
1795
    if (!items)
 
1796
        return NULL;
 
1797
 
 
1798
    if (colors > maxcolors) {
 
1799
        out = Py_None;
 
1800
        Py_INCREF(out);
 
1801
    } else {
 
1802
        out = PyList_New(colors);
 
1803
        for (i = 0; i < colors; i++) {
 
1804
            ImagingColorItem* v = &items[i];
 
1805
            PyObject* item = Py_BuildValue(
 
1806
                "iN", v->count, getpixel(self->image, self->access, v->x, v->y)
 
1807
                );
 
1808
            PyList_SetItem(out, i, item);
 
1809
        }
 
1810
    }
 
1811
 
 
1812
    free(items);
 
1813
 
 
1814
    return out;
 
1815
}
 
1816
 
 
1817
static PyObject* 
 
1818
_getextrema(ImagingObject* self, PyObject* args)
 
1819
{
 
1820
    union {
 
1821
        UINT8 u[2];
 
1822
        INT32 i[2];
 
1823
        FLOAT32 f[2];
 
1824
    } extrema;
 
1825
    int status;
 
1826
    
 
1827
    status = ImagingGetExtrema(self->image, &extrema);
 
1828
    if (status < 0)
 
1829
        return NULL;
 
1830
 
 
1831
    if (status)
 
1832
        switch (self->image->type) {
 
1833
        case IMAGING_TYPE_UINT8:
 
1834
            return Py_BuildValue("ii", extrema.u[0], extrema.u[1]);
 
1835
        case IMAGING_TYPE_INT32:
 
1836
            return Py_BuildValue("ii", extrema.i[0], extrema.i[1]);
 
1837
        case IMAGING_TYPE_FLOAT32:
 
1838
            return Py_BuildValue("dd", extrema.f[0], extrema.f[1]);
 
1839
        }
 
1840
 
 
1841
    Py_INCREF(Py_None);
 
1842
    return Py_None;
 
1843
}
 
1844
 
 
1845
static PyObject* 
 
1846
_getprojection(ImagingObject* self, PyObject* args)
 
1847
{
 
1848
    unsigned char* xprofile;
 
1849
    unsigned char* yprofile;
 
1850
    PyObject* result;
 
1851
 
 
1852
    xprofile = malloc(self->image->xsize);
 
1853
    yprofile = malloc(self->image->ysize);
 
1854
 
 
1855
    if (xprofile == NULL || yprofile == NULL) {
 
1856
        free(xprofile);
 
1857
        free(yprofile);
 
1858
        return PyErr_NoMemory();
 
1859
    }
 
1860
 
 
1861
    ImagingGetProjection(self->image, (unsigned char *)xprofile, (unsigned char *)yprofile);
 
1862
 
 
1863
    result = Py_BuildValue("s#s#", xprofile, self->image->xsize,
 
1864
                           yprofile, self->image->ysize);
 
1865
 
 
1866
    free(xprofile);
 
1867
    free(yprofile);
 
1868
 
 
1869
    return result;
 
1870
}
 
1871
 
 
1872
/* -------------------------------------------------------------------- */
 
1873
 
 
1874
static PyObject* 
 
1875
_getband(ImagingObject* self, PyObject* args)
 
1876
{
 
1877
    int band;
 
1878
 
 
1879
    if (!PyArg_ParseTuple(args, "i", &band))
 
1880
        return NULL;
 
1881
 
 
1882
    return PyImagingNew(ImagingGetBand(self->image, band));
 
1883
}
 
1884
 
 
1885
static PyObject* 
 
1886
_fillband(ImagingObject* self, PyObject* args)
 
1887
{
 
1888
    int band;
 
1889
    int color;
 
1890
 
 
1891
    if (!PyArg_ParseTuple(args, "ii", &band, &color))
 
1892
        return NULL;
 
1893
 
 
1894
    if (!ImagingFillBand(self->image, band, color))
 
1895
        return NULL;
 
1896
    
 
1897
    Py_INCREF(Py_None);
 
1898
    return Py_None;
 
1899
}
 
1900
 
 
1901
static PyObject* 
 
1902
_putband(ImagingObject* self, PyObject* args)
 
1903
{
 
1904
    ImagingObject* imagep;
 
1905
    int band;
 
1906
    if (!PyArg_ParseTuple(args, "O!i",
 
1907
                          &Imaging_Type, &imagep,
 
1908
                          &band))
 
1909
        return NULL;
 
1910
 
 
1911
    if (!ImagingPutBand(self->image, imagep->image, band))
 
1912
        return NULL;
 
1913
 
 
1914
    Py_INCREF(Py_None);
 
1915
    return Py_None;
 
1916
}
 
1917
 
 
1918
/* -------------------------------------------------------------------- */
 
1919
 
 
1920
#ifdef WITH_IMAGECHOPS
 
1921
 
 
1922
static PyObject* 
 
1923
_chop_invert(ImagingObject* self, PyObject* args)
 
1924
{
 
1925
    return PyImagingNew(ImagingNegative(self->image));
 
1926
}
 
1927
 
 
1928
static PyObject* 
 
1929
_chop_lighter(ImagingObject* self, PyObject* args)
 
1930
{
 
1931
    ImagingObject* imagep;
 
1932
 
 
1933
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
1934
        return NULL;
 
1935
 
 
1936
    return PyImagingNew(ImagingChopLighter(self->image, imagep->image));
 
1937
}
 
1938
 
 
1939
static PyObject* 
 
1940
_chop_darker(ImagingObject* self, PyObject* args)
 
1941
{
 
1942
    ImagingObject* imagep;
 
1943
 
 
1944
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
1945
        return NULL;
 
1946
 
 
1947
    return PyImagingNew(ImagingChopDarker(self->image, imagep->image));
 
1948
}
 
1949
 
 
1950
static PyObject* 
 
1951
_chop_difference(ImagingObject* self, PyObject* args)
 
1952
{
 
1953
    ImagingObject* imagep;
 
1954
 
 
1955
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
1956
        return NULL;
 
1957
 
 
1958
    return PyImagingNew(ImagingChopDifference(self->image, imagep->image));
 
1959
}
 
1960
 
 
1961
static PyObject* 
 
1962
_chop_multiply(ImagingObject* self, PyObject* args)
 
1963
{
 
1964
    ImagingObject* imagep;
 
1965
 
 
1966
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
1967
        return NULL;
 
1968
 
 
1969
    return PyImagingNew(ImagingChopMultiply(self->image, imagep->image));
 
1970
}
 
1971
 
 
1972
static PyObject* 
 
1973
_chop_screen(ImagingObject* self, PyObject* args)
 
1974
{
 
1975
    ImagingObject* imagep;
 
1976
 
 
1977
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
1978
        return NULL;
 
1979
 
 
1980
    return PyImagingNew(ImagingChopScreen(self->image, imagep->image));
 
1981
}
 
1982
 
 
1983
static PyObject* 
 
1984
_chop_add(ImagingObject* self, PyObject* args)
 
1985
{
 
1986
    ImagingObject* imagep;
 
1987
    float scale;
 
1988
    int offset;
 
1989
 
 
1990
    scale = 1.0;
 
1991
    offset = 0;
 
1992
 
 
1993
    if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep,
 
1994
                          &scale, &offset))
 
1995
        return NULL;
 
1996
 
 
1997
    return PyImagingNew(ImagingChopAdd(self->image, imagep->image,
 
1998
                                       scale, offset));
 
1999
}
 
2000
 
 
2001
static PyObject* 
 
2002
_chop_subtract(ImagingObject* self, PyObject* args)
 
2003
{
 
2004
    ImagingObject* imagep;
 
2005
    float scale;
 
2006
    int offset;
 
2007
 
 
2008
    scale = 1.0;
 
2009
    offset = 0;
 
2010
 
 
2011
    if (!PyArg_ParseTuple(args, "O!|fi", &Imaging_Type, &imagep,
 
2012
                          &scale, &offset))
 
2013
        return NULL;
 
2014
 
 
2015
    return PyImagingNew(ImagingChopSubtract(self->image, imagep->image,
 
2016
                                            scale, offset));
 
2017
}
 
2018
 
 
2019
static PyObject* 
 
2020
_chop_and(ImagingObject* self, PyObject* args)
 
2021
{
 
2022
    ImagingObject* imagep;
 
2023
 
 
2024
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
2025
        return NULL;
 
2026
 
 
2027
    return PyImagingNew(ImagingChopAnd(self->image, imagep->image));
 
2028
}
 
2029
 
 
2030
static PyObject* 
 
2031
_chop_or(ImagingObject* self, PyObject* args)
 
2032
{
 
2033
    ImagingObject* imagep;
 
2034
 
 
2035
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
2036
        return NULL;
 
2037
 
 
2038
    return PyImagingNew(ImagingChopOr(self->image, imagep->image));
 
2039
}
 
2040
 
 
2041
static PyObject* 
 
2042
_chop_xor(ImagingObject* self, PyObject* args)
 
2043
{
 
2044
    ImagingObject* imagep;
 
2045
 
 
2046
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
2047
        return NULL;
 
2048
 
 
2049
    return PyImagingNew(ImagingChopXor(self->image, imagep->image));
 
2050
}
 
2051
 
 
2052
static PyObject* 
 
2053
_chop_add_modulo(ImagingObject* self, PyObject* args)
 
2054
{
 
2055
    ImagingObject* imagep;
 
2056
 
 
2057
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
2058
        return NULL;
 
2059
 
 
2060
    return PyImagingNew(ImagingChopAddModulo(self->image, imagep->image));
 
2061
}
 
2062
 
 
2063
static PyObject* 
 
2064
_chop_subtract_modulo(ImagingObject* self, PyObject* args)
 
2065
{
 
2066
    ImagingObject* imagep;
 
2067
 
 
2068
    if (!PyArg_ParseTuple(args, "O!", &Imaging_Type, &imagep))
 
2069
        return NULL;
 
2070
 
 
2071
    return PyImagingNew(ImagingChopSubtractModulo(self->image, imagep->image));
 
2072
}
 
2073
 
 
2074
#endif
 
2075
 
 
2076
 
 
2077
/* -------------------------------------------------------------------- */
 
2078
 
 
2079
#ifdef WITH_IMAGEDRAW
 
2080
 
 
2081
static PyObject*
 
2082
_font_new(PyObject* self_, PyObject* args)
 
2083
{
 
2084
    ImagingFontObject *self;
 
2085
    int i, y0, y1;
 
2086
    static const char* wrong_length = "descriptor table has wrong size";
 
2087
 
 
2088
    ImagingObject* imagep;
 
2089
    unsigned char* glyphdata;
 
2090
    int glyphdata_length;
 
2091
    if (!PyArg_ParseTuple(args, "O!s#",
 
2092
                          &Imaging_Type, &imagep,
 
2093
                          &glyphdata, &glyphdata_length))
 
2094
        return NULL;
 
2095
 
 
2096
    if (glyphdata_length != 256 * 20) {
 
2097
        PyErr_SetString(PyExc_ValueError, wrong_length);
 
2098
        return NULL;
 
2099
    }
 
2100
 
 
2101
    self = PyObject_New(ImagingFontObject, &ImagingFont_Type);
 
2102
    if (self == NULL)
 
2103
        return NULL;
 
2104
 
 
2105
    /* glyph bitmap */
 
2106
    self->bitmap = imagep->image;
 
2107
 
 
2108
    y0 = y1 = 0;
 
2109
 
 
2110
    /* glyph glyphs */
 
2111
    for (i = 0; i < 256; i++) {
 
2112
        self->glyphs[i].dx = S16(B16(glyphdata, 0));
 
2113
        self->glyphs[i].dy = S16(B16(glyphdata, 2));
 
2114
        self->glyphs[i].dx0 = S16(B16(glyphdata, 4));
 
2115
        self->glyphs[i].dy0 = S16(B16(glyphdata, 6));
 
2116
        self->glyphs[i].dx1 = S16(B16(glyphdata, 8));
 
2117
        self->glyphs[i].dy1 = S16(B16(glyphdata, 10));
 
2118
        self->glyphs[i].sx0 = S16(B16(glyphdata, 12));
 
2119
        self->glyphs[i].sy0 = S16(B16(glyphdata, 14));
 
2120
        self->glyphs[i].sx1 = S16(B16(glyphdata, 16));
 
2121
        self->glyphs[i].sy1 = S16(B16(glyphdata, 18));
 
2122
        if (self->glyphs[i].dy0 < y0)
 
2123
            y0 = self->glyphs[i].dy0;
 
2124
        if (self->glyphs[i].dy1 > y1)
 
2125
            y1 = self->glyphs[i].dy1;
 
2126
        glyphdata += 20;
 
2127
    }
 
2128
 
 
2129
    self->baseline = -y0;
 
2130
    self->ysize = y1 - y0;
 
2131
 
 
2132
    /* keep a reference to the bitmap object */
 
2133
    Py_INCREF(imagep);
 
2134
    self->ref = imagep;
 
2135
 
 
2136
    return (PyObject*) self;
 
2137
}
 
2138
 
 
2139
static void
 
2140
_font_dealloc(ImagingFontObject* self)
 
2141
{
 
2142
    Py_XDECREF(self->ref);
 
2143
    PyObject_Del(self);
 
2144
}
 
2145
 
 
2146
static inline int
 
2147
textwidth(ImagingFontObject* self, const unsigned char* text)
 
2148
{
 
2149
    int xsize;
 
2150
 
 
2151
    for (xsize = 0; *text; text++)
 
2152
        xsize += self->glyphs[*text].dx;
 
2153
 
 
2154
    return xsize;
 
2155
}
 
2156
 
 
2157
static PyObject*
 
2158
_font_getmask(ImagingFontObject* self, PyObject* args)
 
2159
{
 
2160
    Imaging im;
 
2161
    Imaging bitmap;
 
2162
    int x, b;
 
2163
    int status;
 
2164
    Glyph* glyph;
 
2165
 
 
2166
    unsigned char* text;
 
2167
    char* mode = "";
 
2168
    if (!PyArg_ParseTuple(args, "s|s:getmask", &text, &mode))
 
2169
        return NULL;
 
2170
 
 
2171
    im = ImagingNew(self->bitmap->mode, textwidth(self, text), self->ysize);
 
2172
    if (!im)
 
2173
        return NULL;
 
2174
 
 
2175
    b = 0;
 
2176
    (void) ImagingFill(im, &b);
 
2177
 
 
2178
    b = self->baseline;
 
2179
    for (x = 0; *text; text++) {
 
2180
        glyph = &self->glyphs[*text];
 
2181
        bitmap = ImagingCrop(
 
2182
            self->bitmap,
 
2183
            glyph->sx0, glyph->sy0, glyph->sx1, glyph->sy1
 
2184
            );
 
2185
        if (!bitmap)
 
2186
            goto failed;
 
2187
        status = ImagingPaste(
 
2188
            im, bitmap, NULL,
 
2189
            glyph->dx0+x, glyph->dy0+b, glyph->dx1+x, glyph->dy1+b
 
2190
            );
 
2191
        ImagingDelete(bitmap);
 
2192
        if (status < 0)
 
2193
            goto failed;
 
2194
        x = x + glyph->dx;
 
2195
        b = b + glyph->dy;
 
2196
    }
 
2197
 
 
2198
    return PyImagingNew(im);
 
2199
 
 
2200
  failed:
 
2201
    ImagingDelete(im);
 
2202
    return NULL;
 
2203
}
 
2204
 
 
2205
static PyObject*
 
2206
_font_getsize(ImagingFontObject* self, PyObject* args)
 
2207
{
 
2208
    unsigned char* text;
 
2209
    if (!PyArg_ParseTuple(args, "s:getsize", &text))
 
2210
        return NULL;
 
2211
 
 
2212
    return Py_BuildValue("ii", textwidth(self, text), self->ysize);
 
2213
}
 
2214
 
 
2215
static struct PyMethodDef _font_methods[] = {
 
2216
    {"getmask", (PyCFunction)_font_getmask, 1},
 
2217
    {"getsize", (PyCFunction)_font_getsize, 1},
 
2218
    {NULL, NULL} /* sentinel */
 
2219
};
 
2220
 
 
2221
static PyObject*  
 
2222
_font_getattr(ImagingFontObject* self, char* name)
 
2223
{
 
2224
    return Py_FindMethod(_font_methods, (PyObject*) self, name);
 
2225
}
 
2226
 
 
2227
/* -------------------------------------------------------------------- */
 
2228
 
 
2229
static PyObject*
 
2230
_draw_new(PyObject* self_, PyObject* args)
 
2231
{
 
2232
    ImagingDrawObject *self;
 
2233
 
 
2234
    ImagingObject* imagep;
 
2235
    int blend = 0;
 
2236
    if (!PyArg_ParseTuple(args, "O!|i", &Imaging_Type, &imagep, &blend))
 
2237
        return NULL;
 
2238
 
 
2239
    self = PyObject_New(ImagingDrawObject, &ImagingDraw_Type);
 
2240
    if (self == NULL)
 
2241
        return NULL;
 
2242
 
 
2243
    /* keep a reference to the image object */
 
2244
    Py_INCREF(imagep);
 
2245
    self->image = imagep;
 
2246
 
 
2247
    self->ink[0] = self->ink[1] = self->ink[2] = self->ink[3] = 0;
 
2248
 
 
2249
    self->blend = blend;
 
2250
 
 
2251
    return (PyObject*) self;
 
2252
}
 
2253
 
 
2254
static void
 
2255
_draw_dealloc(ImagingDrawObject* self)
 
2256
{
 
2257
    Py_XDECREF(self->image);
 
2258
    PyObject_Del(self);
 
2259
}
 
2260
 
 
2261
extern int PyPath_Flatten(PyObject* data, double **xy);
 
2262
 
 
2263
static PyObject* 
 
2264
_draw_ink(ImagingDrawObject* self, PyObject* args)
 
2265
{
 
2266
    INT32 ink = 0;
 
2267
    PyObject* color;
 
2268
    char* mode = NULL; /* not used in this release */
 
2269
    if (!PyArg_ParseTuple(args, "O|s", &color, &mode))
 
2270
        return NULL;
 
2271
 
 
2272
    if (!getink(color, self->image->image, (char*) &ink))
 
2273
        return NULL;
 
2274
 
 
2275
    return PyInt_FromLong((int) ink);
 
2276
}
 
2277
 
 
2278
static PyObject* 
 
2279
_draw_arc(ImagingDrawObject* self, PyObject* args)
 
2280
{
 
2281
    int x0, y0, x1, y1;
 
2282
    int ink;
 
2283
    int start, end;
 
2284
    int op = 0;
 
2285
    if (!PyArg_ParseTuple(args, "(iiii)iii|i",
 
2286
                          &x0, &y0, &x1, &y1,
 
2287
                          &start, &end, &ink))
 
2288
        return NULL;
 
2289
 
 
2290
    if (ImagingDrawArc(self->image->image, x0, y0, x1, y1, start, end,
 
2291
                       &ink, op) < 0)
 
2292
        return NULL;
 
2293
 
 
2294
    Py_INCREF(Py_None);
 
2295
    return Py_None;
 
2296
}
 
2297
 
 
2298
static PyObject* 
 
2299
_draw_bitmap(ImagingDrawObject* self, PyObject* args)
 
2300
{
 
2301
    double *xy;
 
2302
    int n;
 
2303
 
 
2304
    PyObject *data;
 
2305
    ImagingObject* bitmap;
 
2306
    int ink;
 
2307
    if (!PyArg_ParseTuple(args, "OO!i", &data, &Imaging_Type, &bitmap, &ink))
 
2308
        return NULL;
 
2309
 
 
2310
    n = PyPath_Flatten(data, &xy);
 
2311
    if (n < 0)
 
2312
        return NULL;
 
2313
    if (n != 1) {
 
2314
        PyErr_SetString(
 
2315
            PyExc_TypeError,
 
2316
            "coordinate list must contain exactly 1 coordinate"
 
2317
            );
 
2318
        return NULL;
 
2319
    }
 
2320
 
 
2321
    n = ImagingDrawBitmap(
 
2322
        self->image->image, (int) xy[0], (int) xy[1], bitmap->image,
 
2323
        &ink, self->blend
 
2324
        );
 
2325
 
 
2326
    free(xy);
 
2327
 
 
2328
    if (n < 0)
 
2329
        return NULL;
 
2330
 
 
2331
    Py_INCREF(Py_None);
 
2332
    return Py_None;
 
2333
}
 
2334
 
 
2335
static PyObject* 
 
2336
_draw_chord(ImagingDrawObject* self, PyObject* args)
 
2337
{
 
2338
    int x0, y0, x1, y1;
 
2339
    int ink, fill;
 
2340
    int start, end;
 
2341
    if (!PyArg_ParseTuple(args, "(iiii)iiii",
 
2342
                          &x0, &y0, &x1, &y1, &start, &end, &ink, &fill))
 
2343
        return NULL;
 
2344
 
 
2345
    if (ImagingDrawChord(self->image->image, x0, y0, x1, y1,
 
2346
                         start, end, &ink, fill, self->blend) < 0)
 
2347
        return NULL;
 
2348
 
 
2349
    Py_INCREF(Py_None);
 
2350
    return Py_None;
 
2351
}
 
2352
 
 
2353
static PyObject* 
 
2354
_draw_ellipse(ImagingDrawObject* self, PyObject* args)
 
2355
{
 
2356
    double* xy;
 
2357
    int n;
 
2358
 
 
2359
    PyObject* data;
 
2360
    int ink;
 
2361
    int fill = 0;
 
2362
    if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill))
 
2363
        return NULL;
 
2364
 
 
2365
    n = PyPath_Flatten(data, &xy);
 
2366
    if (n < 0)
 
2367
        return NULL;
 
2368
    if (n != 2) {
 
2369
        PyErr_SetString(
 
2370
            PyExc_TypeError,
 
2371
            "coordinate list must contain exactly 2 coordinates"
 
2372
            );
 
2373
        return NULL;
 
2374
    }
 
2375
 
 
2376
    n = ImagingDrawEllipse(
 
2377
        self->image->image, (int) xy[0], (int) xy[1], (int) xy[2], (int) xy[3],
 
2378
        &ink, fill, self->blend
 
2379
        );
 
2380
    
 
2381
    free(xy);
 
2382
 
 
2383
    if (n < 0)
 
2384
        return NULL;
 
2385
 
 
2386
    Py_INCREF(Py_None);
 
2387
    return Py_None;
 
2388
}
 
2389
 
 
2390
static PyObject* 
 
2391
_draw_line(ImagingDrawObject* self, PyObject* args)
 
2392
{
 
2393
    int x0, y0, x1, y1;
 
2394
    int ink;
 
2395
    if (!PyArg_ParseTuple(args, "(ii)(ii)i", &x0, &y0, &x1, &y1, &ink))
 
2396
        return NULL;
 
2397
 
 
2398
    if (ImagingDrawLine(self->image->image, x0, y0, x1, y1,
 
2399
                        &ink, self->blend) < 0)
 
2400
        return NULL;
 
2401
 
 
2402
    Py_INCREF(Py_None);
 
2403
    return Py_None;
 
2404
}
 
2405
 
 
2406
static PyObject* 
 
2407
_draw_lines(ImagingDrawObject* self, PyObject* args)
 
2408
{
 
2409
    double *xy;
 
2410
    int i, n;
 
2411
 
 
2412
    PyObject *data;
 
2413
    int ink;
 
2414
    int width = 0;
 
2415
    if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &width))
 
2416
        return NULL;
 
2417
 
 
2418
    n = PyPath_Flatten(data, &xy);
 
2419
    if (n < 0)
 
2420
        return NULL;
 
2421
 
 
2422
    if (width <= 1) {
 
2423
        double *p = NULL;
 
2424
        for (i = 0; i < n-1; i++) {
 
2425
            p = &xy[i+i];
 
2426
            if (ImagingDrawLine(
 
2427
                    self->image->image,
 
2428
                    (int) p[0], (int) p[1], (int) p[2], (int) p[3],
 
2429
                    &ink, self->blend) < 0) {
 
2430
                free(xy);
 
2431
                return NULL;
 
2432
            }
 
2433
        }
 
2434
        if (p) /* draw last point */
 
2435
            ImagingDrawPoint(
 
2436
                    self->image->image,
 
2437
                    (int) p[2], (int) p[3],
 
2438
                    &ink, self->blend
 
2439
                );
 
2440
    } else {
 
2441
        for (i = 0; i < n-1; i++) {
 
2442
            double *p = &xy[i+i];
 
2443
            if (ImagingDrawWideLine(
 
2444
                    self->image->image,
 
2445
                    (int) p[0], (int) p[1], (int) p[2], (int) p[3],
 
2446
                    &ink, width, self->blend) < 0) {
 
2447
                free(xy);
 
2448
                return NULL;
 
2449
            }
 
2450
        }
 
2451
    }
 
2452
 
 
2453
    free(xy);
 
2454
 
 
2455
    Py_INCREF(Py_None);
 
2456
    return Py_None;
 
2457
}
 
2458
 
 
2459
static PyObject* 
 
2460
_draw_point(ImagingDrawObject* self, PyObject* args)
 
2461
{
 
2462
    int x, y;
 
2463
    int ink;
 
2464
    if (!PyArg_ParseTuple(args, "(ii)i", &x, &y, &ink))
 
2465
        return NULL;
 
2466
 
 
2467
    if (ImagingDrawPoint(self->image->image, x, y, &ink, self->blend) < 0)
 
2468
        return NULL;
 
2469
 
 
2470
    Py_INCREF(Py_None);
 
2471
    return Py_None;
 
2472
}
 
2473
 
 
2474
static PyObject* 
 
2475
_draw_points(ImagingDrawObject* self, PyObject* args)
 
2476
{
 
2477
    double *xy;
 
2478
    int i, n;
 
2479
 
 
2480
    PyObject *data;
 
2481
    int ink;
 
2482
    if (!PyArg_ParseTuple(args, "Oi", &data, &ink))
 
2483
        return NULL;
 
2484
 
 
2485
    n = PyPath_Flatten(data, &xy);
 
2486
    if (n < 0)
 
2487
        return NULL;
 
2488
 
 
2489
    for (i = 0; i < n; i++) {
 
2490
        double *p = &xy[i+i];
 
2491
        if (ImagingDrawPoint(self->image->image, (int) p[0], (int) p[1],
 
2492
                             &ink, self->blend) < 0) {
 
2493
            free(xy);
 
2494
            return NULL;
 
2495
        }
 
2496
    }
 
2497
 
 
2498
    free(xy);
 
2499
 
 
2500
    Py_INCREF(Py_None);
 
2501
    return Py_None;
 
2502
}
 
2503
 
 
2504
#ifdef  WITH_ARROW
 
2505
 
 
2506
/* from outline.c */
 
2507
extern ImagingOutline PyOutline_AsOutline(PyObject* outline);
 
2508
 
 
2509
static PyObject* 
 
2510
_draw_outline(ImagingDrawObject* self, PyObject* args)
 
2511
{
 
2512
    ImagingOutline outline;
 
2513
 
 
2514
    PyObject* outline_;
 
2515
    int ink;
 
2516
    int fill = 0;
 
2517
    if (!PyArg_ParseTuple(args, "Oi|i", &outline_, &ink, &fill))
 
2518
        return NULL;
 
2519
 
 
2520
    outline = PyOutline_AsOutline(outline_);
 
2521
    if (!outline) {
 
2522
        PyErr_SetString(PyExc_TypeError, "expected outline object");
 
2523
        return NULL;
 
2524
    }
 
2525
 
 
2526
    if (ImagingDrawOutline(self->image->image, outline,
 
2527
                           &ink, fill, self->blend) < 0)
 
2528
        return NULL;
 
2529
 
 
2530
    Py_INCREF(Py_None);
 
2531
    return Py_None;
 
2532
}
 
2533
 
 
2534
#endif
 
2535
 
 
2536
static PyObject* 
 
2537
_draw_pieslice(ImagingDrawObject* self, PyObject* args)
 
2538
{
 
2539
    int x0, y0, x1, y1;
 
2540
    int ink, fill;
 
2541
    int start, end;
 
2542
    if (!PyArg_ParseTuple(args, "(iiii)iiii",
 
2543
                          &x0, &y0, &x1, &y1, &start, &end, &ink, &fill))
 
2544
        return NULL;
 
2545
 
 
2546
    if (ImagingDrawPieslice(self->image->image, x0, y0, x1, y1,
 
2547
                            start, end, &ink, fill, self->blend) < 0)
 
2548
        return NULL;
 
2549
 
 
2550
    Py_INCREF(Py_None);
 
2551
    return Py_None;
 
2552
}
 
2553
 
 
2554
static PyObject* 
 
2555
_draw_polygon(ImagingDrawObject* self, PyObject* args)
 
2556
{
 
2557
    double *xy;
 
2558
    int *ixy;
 
2559
    int n, i;
 
2560
 
 
2561
    PyObject* data;
 
2562
    int ink;
 
2563
    int fill = 0;
 
2564
    if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill))
 
2565
        return NULL;
 
2566
 
 
2567
    n = PyPath_Flatten(data, &xy);
 
2568
    if (n < 0)
 
2569
        return NULL;
 
2570
    if (n < 2) {
 
2571
        PyErr_SetString(
 
2572
            PyExc_TypeError,
 
2573
            "coordinate list must contain at least 2 coordinates"
 
2574
            );
 
2575
        return NULL;
 
2576
    }
 
2577
 
 
2578
    /* Copy list of vertices to array */
 
2579
    ixy = (int*) malloc(n * 2 * sizeof(int));
 
2580
 
 
2581
    for (i = 0; i < n; i++) {
 
2582
        ixy[i+i] = (int) xy[i+i];
 
2583
        ixy[i+i+1] = (int) xy[i+i+1];
 
2584
    }
 
2585
 
 
2586
    free(xy);
 
2587
 
 
2588
    if (ImagingDrawPolygon(self->image->image, n, ixy,
 
2589
                           &ink, fill, self->blend) < 0) {
 
2590
        free(ixy);
 
2591
        return NULL;
 
2592
    }
 
2593
 
 
2594
    free(ixy);
 
2595
 
 
2596
    Py_INCREF(Py_None);
 
2597
    return Py_None;
 
2598
}
 
2599
 
 
2600
static PyObject* 
 
2601
_draw_rectangle(ImagingDrawObject* self, PyObject* args)
 
2602
{
 
2603
    double* xy;
 
2604
    int n;
 
2605
 
 
2606
    PyObject* data;
 
2607
    int ink;
 
2608
    int fill = 0;
 
2609
    if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill))
 
2610
        return NULL;
 
2611
 
 
2612
    n = PyPath_Flatten(data, &xy);
 
2613
    if (n < 0)
 
2614
        return NULL;
 
2615
    if (n != 2) {
 
2616
        PyErr_SetString(
 
2617
            PyExc_TypeError,
 
2618
            "coordinate list must contain exactly 2 coordinates"
 
2619
            );
 
2620
        return NULL;
 
2621
    }
 
2622
 
 
2623
    n = ImagingDrawRectangle(
 
2624
        self->image->image, (int) xy[0], (int) xy[1],
 
2625
        (int) xy[2], (int) xy[3], &ink, fill, self->blend
 
2626
        );
 
2627
    
 
2628
    free(xy);
 
2629
 
 
2630
    if (n < 0)
 
2631
        return NULL;
 
2632
 
 
2633
    Py_INCREF(Py_None);
 
2634
    return Py_None;
 
2635
}
 
2636
 
 
2637
static struct PyMethodDef _draw_methods[] = {
 
2638
#ifdef WITH_IMAGEDRAW
 
2639
    /* Graphics (ImageDraw) */
 
2640
    {"draw_line", (PyCFunction)_draw_line, 1},
 
2641
    {"draw_lines", (PyCFunction)_draw_lines, 1},
 
2642
#ifdef WITH_ARROW
 
2643
    {"draw_outline", (PyCFunction)_draw_outline, 1},
 
2644
#endif
 
2645
    {"draw_polygon", (PyCFunction)_draw_polygon, 1},
 
2646
    {"draw_rectangle", (PyCFunction)_draw_rectangle, 1},
 
2647
    {"draw_point", (PyCFunction)_draw_point, 1},
 
2648
    {"draw_points", (PyCFunction)_draw_points, 1},
 
2649
    {"draw_arc", (PyCFunction)_draw_arc, 1},
 
2650
    {"draw_bitmap", (PyCFunction)_draw_bitmap, 1},
 
2651
    {"draw_chord", (PyCFunction)_draw_chord, 1},
 
2652
    {"draw_ellipse", (PyCFunction)_draw_ellipse, 1},
 
2653
    {"draw_pieslice", (PyCFunction)_draw_pieslice, 1},
 
2654
    {"draw_ink", (PyCFunction)_draw_ink, 1},
 
2655
#endif
 
2656
    {NULL, NULL} /* sentinel */
 
2657
};
 
2658
 
 
2659
static PyObject*  
 
2660
_draw_getattr(ImagingDrawObject* self, char* name)
 
2661
{
 
2662
    return Py_FindMethod(_draw_methods, (PyObject*) self, name);
 
2663
}
 
2664
 
 
2665
#endif
 
2666
 
 
2667
 
 
2668
static PyObject*
 
2669
pixel_access_new(ImagingObject* imagep, PyObject* args)
 
2670
{
 
2671
    PixelAccessObject *self;
 
2672
 
 
2673
    int readonly = 0;
 
2674
    if (!PyArg_ParseTuple(args, "|i", &readonly))
 
2675
        return NULL;
 
2676
 
 
2677
    self = PyObject_New(PixelAccessObject, &PixelAccess_Type);
 
2678
    if (self == NULL)
 
2679
        return NULL;
 
2680
 
 
2681
    /* keep a reference to the image object */
 
2682
    Py_INCREF(imagep);
 
2683
    self->image = imagep;
 
2684
 
 
2685
    self->readonly = readonly;
 
2686
 
 
2687
    return (PyObject*) self;
 
2688
}
 
2689
 
 
2690
static void
 
2691
pixel_access_dealloc(PixelAccessObject* self)
 
2692
{
 
2693
    Py_XDECREF(self->image);
 
2694
    PyObject_Del(self);
 
2695
}
 
2696
 
 
2697
static PyObject *
 
2698
pixel_access_getitem(PixelAccessObject *self, PyObject *xy)
 
2699
{
 
2700
    int x, y;
 
2701
    if (_getxy(xy, &x, &y))
 
2702
        return NULL;
 
2703
 
 
2704
    return getpixel(self->image->image, self->image->access, x, y);
 
2705
}
 
2706
 
 
2707
static int
 
2708
pixel_access_setitem(PixelAccessObject *self, PyObject *xy, PyObject *color)
 
2709
{
 
2710
    Imaging im = self->image->image;
 
2711
    char ink[4];
 
2712
    int x, y;
 
2713
 
 
2714
    if (self->readonly) {
 
2715
        (void) ImagingError_ValueError(readonly);
 
2716
        return -1;
 
2717
    }
 
2718
 
 
2719
    if (_getxy(xy, &x, &y))
 
2720
        return -1;
 
2721
 
 
2722
    if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) {
 
2723
        PyErr_SetString(PyExc_IndexError, outside_image);
 
2724
        return -1;
 
2725
    }
 
2726
 
 
2727
    if (!color) /* FIXME: raise exception? */
 
2728
        return 0;
 
2729
 
 
2730
    if (!getink(color, im, ink))
 
2731
        return -1;
 
2732
 
 
2733
    self->image->access->put_pixel(im, x, y, ink);
 
2734
 
 
2735
    return 0;
 
2736
}
 
2737
 
 
2738
/* -------------------------------------------------------------------- */
 
2739
/* EFFECTS (experimental)                                               */
 
2740
/* -------------------------------------------------------------------- */
 
2741
 
 
2742
#ifdef WITH_EFFECTS
 
2743
 
 
2744
static PyObject* 
 
2745
_effect_mandelbrot(ImagingObject* self, PyObject* args)
 
2746
{
 
2747
    int xsize = 512;
 
2748
    int ysize = 512;
 
2749
    double extent[4];
 
2750
    int quality = 100;
 
2751
 
 
2752
    extent[0] = -3; extent[1] = -2.5;
 
2753
    extent[2] = 2;  extent[3] = 2.5;
 
2754
 
 
2755
    if (!PyArg_ParseTuple(args, "|(ii)(dddd)i", &xsize, &ysize,
 
2756
                          &extent[0], &extent[1], &extent[2], &extent[3],
 
2757
                          &quality))
 
2758
        return NULL;
 
2759
 
 
2760
    return PyImagingNew(ImagingEffectMandelbrot(xsize, ysize, extent, quality));
 
2761
}
 
2762
 
 
2763
static PyObject* 
 
2764
_effect_noise(ImagingObject* self, PyObject* args)
 
2765
{
 
2766
    int xsize, ysize;
 
2767
    float sigma = 128;
 
2768
    if (!PyArg_ParseTuple(args, "(ii)|f", &xsize, &ysize, &sigma))
 
2769
        return NULL;
 
2770
 
 
2771
    return PyImagingNew(ImagingEffectNoise(xsize, ysize, sigma));
 
2772
}
 
2773
 
 
2774
static PyObject* 
 
2775
_effect_spread(ImagingObject* self, PyObject* args)
 
2776
{
 
2777
    int dist;
 
2778
 
 
2779
    if (!PyArg_ParseTuple(args, "i", &dist))
 
2780
        return NULL;
 
2781
 
 
2782
    return PyImagingNew(ImagingEffectSpread(self->image, dist));
 
2783
}
 
2784
 
 
2785
#endif
 
2786
 
 
2787
/* -------------------------------------------------------------------- */
 
2788
/* UTILITIES                                                            */
 
2789
/* -------------------------------------------------------------------- */
 
2790
 
 
2791
static PyObject* 
 
2792
_crc32(PyObject* self, PyObject* args)
 
2793
{
 
2794
    unsigned char* buffer;
 
2795
    int bytes;
 
2796
    int hi, lo;
 
2797
    UINT32 crc;
 
2798
 
 
2799
    hi = lo = 0;
 
2800
 
 
2801
    if (!PyArg_ParseTuple(args, "s#|(ii)", &buffer, &bytes, &hi, &lo))
 
2802
        return NULL;
 
2803
 
 
2804
    crc = ((UINT32) (hi & 0xFFFF) << 16) + (lo & 0xFFFF);
 
2805
 
 
2806
    crc = ImagingCRC32(crc, (unsigned char *)buffer, bytes);
 
2807
 
 
2808
    return Py_BuildValue("ii", (crc >> 16) & 0xFFFF, crc & 0xFFFF);
 
2809
}
 
2810
 
 
2811
static PyObject* 
 
2812
_getcodecstatus(PyObject* self, PyObject* args)
 
2813
{
 
2814
    int status;
 
2815
    char* msg;
 
2816
 
 
2817
    if (!PyArg_ParseTuple(args, "i", &status))
 
2818
        return NULL;
 
2819
 
 
2820
    switch (status) {
 
2821
    case IMAGING_CODEC_OVERRUN:
 
2822
        msg = "buffer overrun"; break;
 
2823
    case IMAGING_CODEC_BROKEN:
 
2824
        msg = "broken data stream"; break;
 
2825
    case IMAGING_CODEC_UNKNOWN:
 
2826
        msg = "unrecognized data stream contents"; break;
 
2827
    case IMAGING_CODEC_CONFIG:
 
2828
        msg = "codec configuration error"; break;
 
2829
    case IMAGING_CODEC_MEMORY:
 
2830
        msg = "out of memory"; break;
 
2831
    default:
 
2832
        Py_INCREF(Py_None);
 
2833
        return Py_None;
 
2834
    }
 
2835
 
 
2836
    return PyString_FromString(msg);
 
2837
}
 
2838
 
 
2839
/* -------------------------------------------------------------------- */
 
2840
/* DEBUGGING HELPERS                                                    */
 
2841
/* -------------------------------------------------------------------- */
 
2842
 
 
2843
 
 
2844
#ifdef WITH_DEBUG
 
2845
 
 
2846
static PyObject* 
 
2847
_save_ppm(ImagingObject* self, PyObject* args)
 
2848
{
 
2849
    char* filename;
 
2850
 
 
2851
    if (!PyArg_ParseTuple(args, "s", &filename))
 
2852
        return NULL;
 
2853
 
 
2854
    if (!ImagingSavePPM(self->image, filename))
 
2855
        return NULL;
 
2856
 
 
2857
    Py_INCREF(Py_None);
 
2858
    return Py_None;
 
2859
}
 
2860
 
 
2861
#endif
 
2862
 
 
2863
/* -------------------------------------------------------------------- */
 
2864
 
 
2865
/* methods */
 
2866
 
 
2867
static struct PyMethodDef methods[] = {
 
2868
 
 
2869
    /* Put commonly used methods first */
 
2870
    {"getpixel", (PyCFunction)_getpixel, 1},
 
2871
    {"putpixel", (PyCFunction)_putpixel, 1},
 
2872
 
 
2873
    {"pixel_access", (PyCFunction)pixel_access_new, 1},
 
2874
 
 
2875
    /* Standard processing methods (Image) */
 
2876
    {"convert", (PyCFunction)_convert, 1},
 
2877
    {"convert2", (PyCFunction)_convert2, 1},
 
2878
    {"convert_matrix", (PyCFunction)_convert_matrix, 1},
 
2879
    {"copy", (PyCFunction)_copy, 1},
 
2880
    {"copy2", (PyCFunction)_copy2, 1},
 
2881
#ifdef WITH_CRACKCODE
 
2882
    {"crackcode", (PyCFunction)_crackcode, 1},
 
2883
#endif
 
2884
    {"crop", (PyCFunction)_crop, 1},
 
2885
    {"expand", (PyCFunction)_expand, 1},
 
2886
    {"filter", (PyCFunction)_filter, 1},
 
2887
    {"histogram", (PyCFunction)_histogram, 1},
 
2888
#ifdef WITH_MODEFILTER
 
2889
    {"modefilter", (PyCFunction)_modefilter, 1},
 
2890
#endif
 
2891
    {"offset", (PyCFunction)_offset, 1},
 
2892
    {"paste", (PyCFunction)_paste, 1},
 
2893
    {"point", (PyCFunction)_point, 1},
 
2894
    {"point_transform", (PyCFunction)_point_transform, 1},
 
2895
    {"putdata", (PyCFunction)_putdata, 1},
 
2896
#ifdef WITH_QUANTIZE
 
2897
    {"quantize", (PyCFunction)_quantize, 1},
 
2898
#endif
 
2899
#ifdef WITH_RANKFILTER
 
2900
    {"rankfilter", (PyCFunction)_rankfilter, 1},
 
2901
#endif
 
2902
    {"resize", (PyCFunction)_resize, 1},
 
2903
    {"rotate", (PyCFunction)_rotate, 1},
 
2904
    {"stretch", (PyCFunction)_stretch, 1},
 
2905
    {"transpose", (PyCFunction)_transpose, 1},
 
2906
    {"transform2", (PyCFunction)_transform2, 1},
 
2907
 
 
2908
    {"isblock", (PyCFunction)_isblock, 1},
 
2909
 
 
2910
    {"getbbox", (PyCFunction)_getbbox, 1},
 
2911
    {"getcolors", (PyCFunction)_getcolors, 1},
 
2912
    {"getextrema", (PyCFunction)_getextrema, 1},
 
2913
    {"getprojection", (PyCFunction)_getprojection, 1},
 
2914
 
 
2915
    {"getband", (PyCFunction)_getband, 1},
 
2916
    {"putband", (PyCFunction)_putband, 1},
 
2917
    {"fillband", (PyCFunction)_fillband, 1},
 
2918
 
 
2919
    {"setmode", (PyCFunction)im_setmode, 1},
 
2920
    
 
2921
    {"getpalette", (PyCFunction)_getpalette, 1},
 
2922
    {"putpalette", (PyCFunction)_putpalette, 1},
 
2923
    {"putpalettealpha", (PyCFunction)_putpalettealpha, 1},
 
2924
 
 
2925
#ifdef WITH_IMAGECHOPS
 
2926
    /* Channel operations (ImageChops) */
 
2927
    {"chop_invert", (PyCFunction)_chop_invert, 1},
 
2928
    {"chop_lighter", (PyCFunction)_chop_lighter, 1},
 
2929
    {"chop_darker", (PyCFunction)_chop_darker, 1},
 
2930
    {"chop_difference", (PyCFunction)_chop_difference, 1},
 
2931
    {"chop_multiply", (PyCFunction)_chop_multiply, 1},
 
2932
    {"chop_screen", (PyCFunction)_chop_screen, 1},
 
2933
    {"chop_add", (PyCFunction)_chop_add, 1},
 
2934
    {"chop_subtract", (PyCFunction)_chop_subtract, 1},
 
2935
    {"chop_add_modulo", (PyCFunction)_chop_add_modulo, 1},
 
2936
    {"chop_subtract_modulo", (PyCFunction)_chop_subtract_modulo, 1},
 
2937
    {"chop_and", (PyCFunction)_chop_and, 1},
 
2938
    {"chop_or", (PyCFunction)_chop_or, 1},
 
2939
    {"chop_xor", (PyCFunction)_chop_xor, 1},
 
2940
#endif
 
2941
 
 
2942
#ifdef WITH_UNSHARPMASK
 
2943
    /* Kevin Cazabon's unsharpmask extension */
 
2944
    {"gaussian_blur", (PyCFunction)_gaussian_blur, 1},
 
2945
    {"unsharp_mask", (PyCFunction)_unsharp_mask, 1},
 
2946
#endif
 
2947
 
 
2948
#ifdef WITH_EFFECTS
 
2949
    /* Special effects */
 
2950
    {"effect_spread", (PyCFunction)_effect_spread, 1},
 
2951
#endif
 
2952
 
 
2953
    /* Misc. */
 
2954
    {"new_array", (PyCFunction)_new_array, 1},
 
2955
    {"new_block", (PyCFunction)_new_block, 1},
 
2956
 
 
2957
#ifdef WITH_DEBUG
 
2958
    {"save_ppm", (PyCFunction)_save_ppm, 1},
 
2959
#endif
 
2960
 
 
2961
    {NULL, NULL} /* sentinel */
 
2962
};
 
2963
 
 
2964
 
 
2965
/* attributes */
 
2966
 
 
2967
static PyObject*  
 
2968
_getattr(ImagingObject* self, char* name)
 
2969
{
 
2970
    PyObject* res;
 
2971
 
 
2972
    res = Py_FindMethod(methods, (PyObject*) self, name);
 
2973
    if (res)
 
2974
        return res;
 
2975
    PyErr_Clear();
 
2976
    if (strcmp(name, "mode") == 0)
 
2977
        return PyString_FromString(self->image->mode);
 
2978
    if (strcmp(name, "size") == 0)
 
2979
        return Py_BuildValue("ii", self->image->xsize, self->image->ysize);
 
2980
    if (strcmp(name, "bands") == 0)
 
2981
        return PyInt_FromLong(self->image->bands);
 
2982
    if (strcmp(name, "id") == 0)
 
2983
        return PyInt_FromLong((long) self->image);
 
2984
    if (strcmp(name, "ptr") == 0)
 
2985
        return PyCObject_FromVoidPtrAndDesc(self->image, IMAGING_MAGIC, NULL);
 
2986
    PyErr_SetString(PyExc_AttributeError, name);
 
2987
    return NULL;
 
2988
}
 
2989
 
 
2990
 
 
2991
/* basic sequence semantics */
 
2992
 
 
2993
static Py_ssize_t
 
2994
image_length(ImagingObject *self)
 
2995
{
 
2996
    Imaging im = self->image;
 
2997
 
 
2998
    return im->xsize * im->ysize;
 
2999
}
 
3000
 
 
3001
static PyObject *
 
3002
image_item(ImagingObject *self, Py_ssize_t i)
 
3003
{
 
3004
    int x, y;
 
3005
    Imaging im = self->image;
 
3006
 
 
3007
    if (im->xsize > 0) {
 
3008
        x = i % im->xsize;
 
3009
        y = i / im->xsize;
 
3010
    } else
 
3011
        x = y = 0; /* leave it to getpixel to raise an exception */
 
3012
 
 
3013
    return getpixel(im, self->access, x, y);
 
3014
}
 
3015
 
 
3016
static PySequenceMethods image_as_sequence = {
 
3017
    (inquiry) image_length, /*sq_length*/
 
3018
    (binaryfunc) NULL, /*sq_concat*/
 
3019
    (ssizeargfunc) NULL, /*sq_repeat*/
 
3020
    (ssizeargfunc) image_item, /*sq_item*/
 
3021
    (ssizessizeargfunc) NULL, /*sq_slice*/
 
3022
    (ssizeobjargproc) NULL, /*sq_ass_item*/
 
3023
    (ssizessizeobjargproc) NULL, /*sq_ass_slice*/
 
3024
};
 
3025
 
 
3026
 
 
3027
/* type description */
 
3028
 
 
3029
statichere PyTypeObject Imaging_Type = {
 
3030
    PyObject_HEAD_INIT(NULL)
 
3031
    0,                          /*ob_size*/
 
3032
    "ImagingCore",              /*tp_name*/
 
3033
    sizeof(ImagingObject),      /*tp_size*/
 
3034
    0,                          /*tp_itemsize*/
 
3035
    /* methods */
 
3036
    (destructor)_dealloc,       /*tp_dealloc*/
 
3037
    0,                          /*tp_print*/
 
3038
    (getattrfunc)_getattr,      /*tp_getattr*/
 
3039
    0,                          /*tp_setattr*/
 
3040
    0,                          /*tp_compare*/
 
3041
    0,                          /*tp_repr*/
 
3042
    0,                          /*tp_as_number */
 
3043
    &image_as_sequence,         /*tp_as_sequence */
 
3044
    0,                          /*tp_as_mapping */
 
3045
    0                           /*tp_hash*/
 
3046
};
 
3047
 
 
3048
#ifdef WITH_IMAGEDRAW
 
3049
 
 
3050
statichere PyTypeObject ImagingFont_Type = {
 
3051
    PyObject_HEAD_INIT(NULL)
 
3052
    0,                          /*ob_size*/
 
3053
    "ImagingFont",              /*tp_name*/
 
3054
    sizeof(ImagingFontObject),  /*tp_size*/
 
3055
    0,                          /*tp_itemsize*/
 
3056
    /* methods */
 
3057
    (destructor)_font_dealloc,  /*tp_dealloc*/
 
3058
    0,                          /*tp_print*/
 
3059
    (getattrfunc)_font_getattr, /*tp_getattr*/
 
3060
};
 
3061
 
 
3062
statichere PyTypeObject ImagingDraw_Type = {
 
3063
    PyObject_HEAD_INIT(NULL)
 
3064
    0,                          /*ob_size*/
 
3065
    "ImagingDraw",              /*tp_name*/
 
3066
    sizeof(ImagingDrawObject),  /*tp_size*/
 
3067
    0,                          /*tp_itemsize*/
 
3068
    /* methods */
 
3069
    (destructor)_draw_dealloc,  /*tp_dealloc*/
 
3070
    0,                          /*tp_print*/
 
3071
    (getattrfunc)_draw_getattr, /*tp_getattr*/
 
3072
};
 
3073
 
 
3074
#endif
 
3075
 
 
3076
static PyMappingMethods pixel_access_as_mapping = {
 
3077
    (inquiry) NULL, /*mp_length*/
 
3078
    (binaryfunc) pixel_access_getitem, /*mp_subscript*/
 
3079
    (objobjargproc) pixel_access_setitem, /*mp_ass_subscript*/
 
3080
};
 
3081
 
 
3082
/* type description */
 
3083
 
 
3084
statichere PyTypeObject PixelAccess_Type = {
 
3085
    PyObject_HEAD_INIT(NULL)
 
3086
    0, "PixelAccess", sizeof(PixelAccessObject), 0,
 
3087
    /* methods */
 
3088
    (destructor)pixel_access_dealloc, /*tp_dealloc*/
 
3089
    0, /*tp_print*/
 
3090
    0, /*tp_getattr*/
 
3091
    0, /*tp_setattr*/
 
3092
    0, /*tp_compare*/
 
3093
    0, /*tp_repr*/
 
3094
    0, /*tp_as_number */
 
3095
    0, /*tp_as_sequence */
 
3096
    &pixel_access_as_mapping, /*tp_as_mapping */
 
3097
    0 /*tp_hash*/
 
3098
};
 
3099
 
 
3100
/* -------------------------------------------------------------------- */
 
3101
 
 
3102
/* FIXME: this is something of a mess.  Should replace this with
 
3103
   pluggable codecs, but not before PIL 1.2 */
 
3104
 
 
3105
/* Decoders (in decode.c) */
 
3106
extern PyObject* PyImaging_BitDecoderNew(PyObject* self, PyObject* args);
 
3107
extern PyObject* PyImaging_FliDecoderNew(PyObject* self, PyObject* args);
 
3108
extern PyObject* PyImaging_GifDecoderNew(PyObject* self, PyObject* args);
 
3109
extern PyObject* PyImaging_HexDecoderNew(PyObject* self, PyObject* args);
 
3110
extern PyObject* PyImaging_JpegDecoderNew(PyObject* self, PyObject* args);
 
3111
extern PyObject* PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args);
 
3112
extern PyObject* PyImaging_MspDecoderNew(PyObject* self, PyObject* args);
 
3113
extern PyObject* PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args);
 
3114
extern PyObject* PyImaging_PcdDecoderNew(PyObject* self, PyObject* args);
 
3115
extern PyObject* PyImaging_PcxDecoderNew(PyObject* self, PyObject* args);
 
3116
extern PyObject* PyImaging_RawDecoderNew(PyObject* self, PyObject* args);
 
3117
extern PyObject* PyImaging_SunRleDecoderNew(PyObject* self, PyObject* args);
 
3118
extern PyObject* PyImaging_TgaRleDecoderNew(PyObject* self, PyObject* args);
 
3119
extern PyObject* PyImaging_XbmDecoderNew(PyObject* self, PyObject* args);
 
3120
extern PyObject* PyImaging_ZipDecoderNew(PyObject* self, PyObject* args);
 
3121
 
 
3122
/* Encoders (in encode.c) */
 
3123
extern PyObject* PyImaging_EpsEncoderNew(PyObject* self, PyObject* args);
 
3124
extern PyObject* PyImaging_GifEncoderNew(PyObject* self, PyObject* args);
 
3125
extern PyObject* PyImaging_JpegEncoderNew(PyObject* self, PyObject* args);
 
3126
extern PyObject* PyImaging_PcxEncoderNew(PyObject* self, PyObject* args);
 
3127
extern PyObject* PyImaging_RawEncoderNew(PyObject* self, PyObject* args);
 
3128
extern PyObject* PyImaging_XbmEncoderNew(PyObject* self, PyObject* args);
 
3129
extern PyObject* PyImaging_ZipEncoderNew(PyObject* self, PyObject* args);
 
3130
 
 
3131
/* Display support etc (in display.c) */
 
3132
#ifdef WIN32
 
3133
extern PyObject* PyImaging_CreateWindowWin32(PyObject* self, PyObject* args);
 
3134
extern PyObject* PyImaging_DisplayWin32(PyObject* self, PyObject* args);
 
3135
extern PyObject* PyImaging_DisplayModeWin32(PyObject* self, PyObject* args);
 
3136
extern PyObject* PyImaging_GrabScreenWin32(PyObject* self, PyObject* args);
 
3137
extern PyObject* PyImaging_GrabClipboardWin32(PyObject* self, PyObject* args);
 
3138
extern PyObject* PyImaging_ListWindowsWin32(PyObject* self, PyObject* args);
 
3139
extern PyObject* PyImaging_EventLoopWin32(PyObject* self, PyObject* args);
 
3140
extern PyObject* PyImaging_DrawWmf(PyObject* self, PyObject* args);
 
3141
#endif
 
3142
 
 
3143
/* Experimental path stuff (in path.c) */
 
3144
extern PyObject* PyPath_Create(ImagingObject* self, PyObject* args);
 
3145
 
 
3146
/* Experimental outline stuff (in outline.c) */
 
3147
extern PyObject* PyOutline_Create(ImagingObject* self, PyObject* args);
 
3148
 
 
3149
extern PyObject* PyImaging_Mapper(PyObject* self, PyObject* args);
 
3150
extern PyObject* PyImaging_MapBuffer(PyObject* self, PyObject* args);
 
3151
 
 
3152
static PyMethodDef functions[] = {
 
3153
 
 
3154
    /* Object factories */
 
3155
    {"blend", (PyCFunction)_blend, 1},
 
3156
    {"fill", (PyCFunction)_fill, 1},
 
3157
    {"new", (PyCFunction)_new, 1},
 
3158
 
 
3159
    {"getcount", (PyCFunction)_getcount, 1},
 
3160
 
 
3161
    /* Functions */
 
3162
    {"convert", (PyCFunction)_convert2, 1},
 
3163
    {"copy", (PyCFunction)_copy2, 1},
 
3164
 
 
3165
    /* Codecs */
 
3166
    {"bit_decoder", (PyCFunction)PyImaging_BitDecoderNew, 1},
 
3167
    {"eps_encoder", (PyCFunction)PyImaging_EpsEncoderNew, 1},
 
3168
    {"fli_decoder", (PyCFunction)PyImaging_FliDecoderNew, 1},
 
3169
    {"gif_decoder", (PyCFunction)PyImaging_GifDecoderNew, 1},
 
3170
    {"gif_encoder", (PyCFunction)PyImaging_GifEncoderNew, 1},
 
3171
    {"hex_decoder", (PyCFunction)PyImaging_HexDecoderNew, 1},
 
3172
    {"hex_encoder", (PyCFunction)PyImaging_EpsEncoderNew, 1}, /* EPS=HEX! */
 
3173
#ifdef HAVE_LIBJPEG
 
3174
    {"jpeg_decoder", (PyCFunction)PyImaging_JpegDecoderNew, 1},
 
3175
    {"jpeg_encoder", (PyCFunction)PyImaging_JpegEncoderNew, 1},
 
3176
#endif
 
3177
    {"tiff_lzw_decoder", (PyCFunction)PyImaging_TiffLzwDecoderNew, 1},
 
3178
    {"msp_decoder", (PyCFunction)PyImaging_MspDecoderNew, 1},
 
3179
    {"packbits_decoder", (PyCFunction)PyImaging_PackbitsDecoderNew, 1},
 
3180
    {"pcd_decoder", (PyCFunction)PyImaging_PcdDecoderNew, 1},
 
3181
    {"pcx_decoder", (PyCFunction)PyImaging_PcxDecoderNew, 1},
 
3182
    {"pcx_encoder", (PyCFunction)PyImaging_PcxEncoderNew, 1},
 
3183
    {"raw_decoder", (PyCFunction)PyImaging_RawDecoderNew, 1},
 
3184
    {"raw_encoder", (PyCFunction)PyImaging_RawEncoderNew, 1},
 
3185
    {"sun_rle_decoder", (PyCFunction)PyImaging_SunRleDecoderNew, 1},
 
3186
    {"tga_rle_decoder", (PyCFunction)PyImaging_TgaRleDecoderNew, 1},
 
3187
    {"xbm_decoder", (PyCFunction)PyImaging_XbmDecoderNew, 1},
 
3188
    {"xbm_encoder", (PyCFunction)PyImaging_XbmEncoderNew, 1},
 
3189
#ifdef HAVE_LIBZ
 
3190
    {"zip_decoder", (PyCFunction)PyImaging_ZipDecoderNew, 1},
 
3191
    {"zip_encoder", (PyCFunction)PyImaging_ZipEncoderNew, 1},
 
3192
#endif
 
3193
 
 
3194
    /* Memory mapping */
 
3195
#ifdef WITH_MAPPING
 
3196
#ifdef WIN32
 
3197
    {"map", (PyCFunction)PyImaging_Mapper, 1},
 
3198
#endif
 
3199
    {"map_buffer", (PyCFunction)PyImaging_MapBuffer, 1},
 
3200
#endif
 
3201
 
 
3202
    /* Display support */
 
3203
#ifdef WIN32
 
3204
    {"display", (PyCFunction)PyImaging_DisplayWin32, 1},
 
3205
    {"display_mode", (PyCFunction)PyImaging_DisplayModeWin32, 1},
 
3206
    {"grabscreen", (PyCFunction)PyImaging_GrabScreenWin32, 1},
 
3207
    {"grabclipboard", (PyCFunction)PyImaging_GrabClipboardWin32, 1},
 
3208
    {"createwindow", (PyCFunction)PyImaging_CreateWindowWin32, 1},
 
3209
    {"eventloop", (PyCFunction)PyImaging_EventLoopWin32, 1},
 
3210
    {"listwindows", (PyCFunction)PyImaging_ListWindowsWin32, 1},
 
3211
    {"drawwmf", (PyCFunction)PyImaging_DrawWmf, 1},
 
3212
#endif
 
3213
 
 
3214
    /* Utilities */
 
3215
    {"crc32", (PyCFunction)_crc32, 1},
 
3216
    {"getcodecstatus", (PyCFunction)_getcodecstatus, 1},
 
3217
 
 
3218
    /* Debugging stuff */
 
3219
    {"open_ppm", (PyCFunction)_open_ppm, 1},
 
3220
 
 
3221
    /* Special effects (experimental) */
 
3222
#ifdef WITH_EFFECTS
 
3223
    {"effect_mandelbrot", (PyCFunction)_effect_mandelbrot, 1},
 
3224
    {"effect_noise", (PyCFunction)_effect_noise, 1},
 
3225
    {"linear_gradient", (PyCFunction)_linear_gradient, 1},
 
3226
    {"radial_gradient", (PyCFunction)_radial_gradient, 1},
 
3227
    {"wedge", (PyCFunction)_linear_gradient, 1}, /* Compatibility */
 
3228
#endif
 
3229
 
 
3230
    /* Drawing support stuff */
 
3231
#ifdef WITH_IMAGEDRAW
 
3232
    {"font", (PyCFunction)_font_new, 1},
 
3233
    {"draw", (PyCFunction)_draw_new, 1},
 
3234
#endif
 
3235
 
 
3236
    /* Experimental path stuff */
 
3237
#ifdef WITH_IMAGEPATH
 
3238
    {"path", (PyCFunction)PyPath_Create, 1},
 
3239
#endif
 
3240
    
 
3241
    /* Experimental arrow graphics stuff */
 
3242
#ifdef WITH_ARROW
 
3243
    {"outline", (PyCFunction)PyOutline_Create, 1},
 
3244
#endif
 
3245
 
 
3246
    {NULL, NULL} /* sentinel */
 
3247
};
 
3248
 
 
3249
DL_EXPORT(void)
 
3250
init_imaging(void)
 
3251
{
 
3252
    PyObject* m;
 
3253
    PyObject* d;
 
3254
 
 
3255
    /* Patch object type */
 
3256
    Imaging_Type.ob_type = &PyType_Type;
 
3257
#ifdef WITH_IMAGEDRAW
 
3258
    ImagingFont_Type.ob_type = &PyType_Type;
 
3259
    ImagingDraw_Type.ob_type = &PyType_Type;
 
3260
#endif
 
3261
    PixelAccess_Type.ob_type = &PyType_Type;
 
3262
 
 
3263
    ImagingAccessInit();
 
3264
 
 
3265
    m = Py_InitModule("_imaging", functions);
 
3266
    d = PyModule_GetDict(m);
 
3267
 
 
3268
#ifdef HAVE_LIBJPEG
 
3269
  {
 
3270
    extern const char* ImagingJpegVersion(void);
 
3271
    PyDict_SetItemString(d, "jpeglib_version", PyString_FromString(ImagingJpegVersion()));
 
3272
  }
 
3273
#endif
 
3274
 
 
3275
#ifdef HAVE_LIBZ
 
3276
  {
 
3277
    extern const char* ImagingZipVersion(void);
 
3278
    PyDict_SetItemString(d, "zlib_version", PyString_FromString(ImagingZipVersion()));
 
3279
  }
 
3280
#endif
 
3281
}