No issues found
1 /* imageopmodule - Various operations on pictures */
2
3 #ifdef sun
4 #define signed
5 #endif
6
7 #include "Python.h"
8
9 #if SIZEOF_INT == 4
10 typedef int Py_Int32;
11 typedef unsigned int Py_UInt32;
12 #else
13 #if SIZEOF_LONG == 4
14 typedef long Py_Int32;
15 typedef unsigned long Py_UInt32;
16 #else
17 #error "No 4-byte integral type"
18 #endif
19 #endif
20
21 #define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
22 #define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
23 #define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x)))
24
25 static PyObject *ImageopError;
26 static PyObject *ImageopDict;
27
28 /**
29 * Check a coordonnate, make sure that (0 < value).
30 * Return 0 on error.
31 */
32 static int
33 check_coordonnate(int value, const char* name)
34 {
35 if ( 0 < value)
36 return 1;
37 PyErr_Format(PyExc_ValueError, "%s value is negative or nul", name);
38 return 0;
39 }
40
41 /**
42 * Check integer overflow to make sure that product == x*y*size.
43 * Return 0 on error.
44 */
45 static int
46 check_multiply_size(int product, int x, const char* xname, int y, const char* yname, int size)
47 {
48 if ( !check_coordonnate(x, xname) )
49 return 0;
50 if ( !check_coordonnate(y, yname) )
51 return 0;
52 if ( size == (product / y) / x )
53 return 1;
54 PyErr_SetString(ImageopError, "String has incorrect length");
55 return 0;
56 }
57
58 /**
59 * Check integer overflow to make sure that product == x*y.
60 * Return 0 on error.
61 */
62 static int
63 check_multiply(int product, int x, int y)
64 {
65 return check_multiply_size(product, x, "x", y, "y", 1);
66 }
67
68 /* If this function returns true (the default if anything goes wrong), we're
69 behaving in a backward-compatible way with respect to how multi-byte pixels
70 are stored in the strings. The code in this module was originally written
71 for an SGI which is a big-endian system, and so the old code assumed that
72 4-byte integers hold the R, G, and B values in a particular order.
73 However, on little-endian systems the order is reversed, and so not
74 actually compatible with what gl.lrectwrite and imgfile expect.
75 (gl.lrectwrite and imgfile are also SGI-specific, however, it is
76 conceivable that the data handled here comes from or goes to an SGI or that
77 it is otherwise used in the expectation that the byte order in the strings
78 is as specified.)
79
80 The function returns the value of the module variable
81 "backward_compatible", or 1 if the variable does not exist or is not an
82 int.
83 */
84
85 static int
86 imageop_backward_compatible(void)
87 {
88 static PyObject *bcos;
89 PyObject *bco;
90 long rc;
91
92 if (ImageopDict == NULL) /* "cannot happen" */
93 return 1;
94 if (bcos == NULL) {
95 /* cache string object for future use */
96 bcos = PyString_FromString("backward_compatible");
97 if (bcos == NULL)
98 return 1;
99 }
100 bco = PyDict_GetItem(ImageopDict, bcos);
101 if (bco == NULL)
102 return 1;
103 if (!PyInt_Check(bco))
104 return 1;
105 rc = PyInt_AsLong(bco);
106 if (PyErr_Occurred()) {
107 /* not an integer, or too large, or something */
108 PyErr_Clear();
109 rc = 1;
110 }
111 return rc != 0; /* convert to values 0, 1 */
112 }
113
114 static PyObject *
115 imageop_crop(PyObject *self, PyObject *args)
116 {
117 char *cp, *ncp;
118 short *nsp;
119 Py_Int32 *nlp;
120 int len, size, x, y, newx1, newx2, newy1, newy2, nlen;
121 int ix, iy, xstep, ystep;
122 PyObject *rv;
123
124 if ( !PyArg_ParseTuple(args, "s#iiiiiii", &cp, &len, &size, &x, &y,
125 &newx1, &newy1, &newx2, &newy2) )
126 return 0;
127
128 if ( size != 1 && size != 2 && size != 4 ) {
129 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
130 return 0;
131 }
132 if ( !check_multiply_size(len, x, "x", y, "y", size) )
133 return 0;
134
135 xstep = (newx1 < newx2)? 1 : -1;
136 ystep = (newy1 < newy2)? 1 : -1;
137
138 nlen = (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size;
139 if ( !check_multiply_size(nlen, abs(newx2-newx1)+1, "abs(newx2-newx1)+1", abs(newy2-newy1)+1, "abs(newy2-newy1)+1", size) )
140 return 0;
141 rv = PyString_FromStringAndSize(NULL, nlen);
142 if ( rv == 0 )
143 return 0;
144 ncp = (char *)PyString_AsString(rv);
145 nsp = (short *)ncp;
146 nlp = (Py_Int32 *)ncp;
147 newy2 += ystep;
148 newx2 += xstep;
149 for( iy = newy1; iy != newy2; iy+=ystep ) {
150 for ( ix = newx1; ix != newx2; ix+=xstep ) {
151 if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
152 if ( size == 1 )
153 *ncp++ = 0;
154 else
155 *nlp++ = 0;
156 } else {
157 if ( size == 1 )
158 *ncp++ = *CHARP(cp, x, ix, iy);
159 else if ( size == 2 )
160 *nsp++ = *SHORTP(cp, x, ix, iy);
161 else
162 *nlp++ = *LONGP(cp, x, ix, iy);
163 }
164 }
165 }
166 return rv;
167 }
168
169 static PyObject *
170 imageop_scale(PyObject *self, PyObject *args)
171 {
172 char *cp, *ncp;
173 short *nsp;
174 Py_Int32 *nlp;
175 int len, size, x, y, newx, newy, nlen;
176 int ix, iy;
177 int oix, oiy;
178 PyObject *rv;
179
180 if ( !PyArg_ParseTuple(args, "s#iiiii",
181 &cp, &len, &size, &x, &y, &newx, &newy) )
182 return 0;
183
184 if ( size != 1 && size != 2 && size != 4 ) {
185 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
186 return 0;
187 }
188 if ( !check_multiply_size(len, x, "x", y, "y", size) )
189 return 0;
190 nlen = newx*newy*size;
191 if ( !check_multiply_size(nlen, newx, "newx", newy, "newy", size) )
192 return 0;
193
194 rv = PyString_FromStringAndSize(NULL, nlen);
195 if ( rv == 0 )
196 return 0;
197 ncp = (char *)PyString_AsString(rv);
198 nsp = (short *)ncp;
199 nlp = (Py_Int32 *)ncp;
200 for( iy = 0; iy < newy; iy++ ) {
201 for ( ix = 0; ix < newx; ix++ ) {
202 oix = ix * x / newx;
203 oiy = iy * y / newy;
204 if ( size == 1 )
205 *ncp++ = *CHARP(cp, x, oix, oiy);
206 else if ( size == 2 )
207 *nsp++ = *SHORTP(cp, x, oix, oiy);
208 else
209 *nlp++ = *LONGP(cp, x, oix, oiy);
210 }
211 }
212 return rv;
213 }
214
215 /* Note: this routine can use a bit of optimizing */
216
217 static PyObject *
218 imageop_tovideo(PyObject *self, PyObject *args)
219 {
220 int maxx, maxy, x, y, len;
221 int i;
222 unsigned char *cp, *ncp;
223 int width;
224 PyObject *rv;
225
226
227 if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &width, &maxx, &maxy) )
228 return 0;
229
230 if ( width != 1 && width != 4 ) {
231 PyErr_SetString(ImageopError, "Size should be 1 or 4");
232 return 0;
233 }
234 if ( !check_multiply_size(len, maxx, "max", maxy, "maxy", width) )
235 return 0;
236
237 rv = PyString_FromStringAndSize(NULL, len);
238 if ( rv == 0 )
239 return 0;
240 ncp = (unsigned char *)PyString_AsString(rv);
241
242 if ( width == 1 ) {
243 memcpy(ncp, cp, maxx); /* Copy first line */
244 ncp += maxx;
245 for (y=1; y<maxy; y++) { /* Interpolate other lines */
246 for(x=0; x<maxx; x++) {
247 i = y*maxx + x;
248 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
249 }
250 }
251 } else {
252 memcpy(ncp, cp, maxx*4); /* Copy first line */
253 ncp += maxx*4;
254 for (y=1; y<maxy; y++) { /* Interpolate other lines */
255 for(x=0; x<maxx; x++) {
256 i = (y*maxx + x)*4 + 1;
257 *ncp++ = 0; /* Skip alfa comp */
258 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
259 i++;
260 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
261 i++;
262 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
263 }
264 }
265 }
266 return rv;
267 }
268
269 static PyObject *
270 imageop_grey2mono(PyObject *self, PyObject *args)
271 {
272 int tres, x, y, len;
273 unsigned char *cp, *ncp;
274 unsigned char ovalue;
275 PyObject *rv;
276 int i, bit;
277
278
279 if ( !PyArg_ParseTuple(args, "s#iii", &cp, &len, &x, &y, &tres) )
280 return 0;
281
282 if ( !check_multiply(len, x, y) )
283 return 0;
284
285 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
286 if ( rv == 0 )
287 return 0;
288 ncp = (unsigned char *)PyString_AsString(rv);
289
290 bit = 0x80;
291 ovalue = 0;
292 for ( i=0; i < len; i++ ) {
293 if ( (int)cp[i] > tres )
294 ovalue |= bit;
295 bit >>= 1;
296 if ( bit == 0 ) {
297 *ncp++ = ovalue;
298 bit = 0x80;
299 ovalue = 0;
300 }
301 }
302 if ( bit != 0x80 )
303 *ncp++ = ovalue;
304 return rv;
305 }
306
307 static PyObject *
308 imageop_grey2grey4(PyObject *self, PyObject *args)
309 {
310 int x, y, len;
311 unsigned char *cp, *ncp;
312 unsigned char ovalue;
313 PyObject *rv;
314 int i;
315 int pos;
316
317
318 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
319 return 0;
320
321 if ( !check_multiply(len, x, y) )
322 return 0;
323
324 rv = PyString_FromStringAndSize(NULL, (len+1)/2);
325 if ( rv == 0 )
326 return 0;
327 ncp = (unsigned char *)PyString_AsString(rv);
328 pos = 0;
329 ovalue = 0;
330 for ( i=0; i < len; i++ ) {
331 ovalue |= ((int)cp[i] & 0xf0) >> pos;
332 pos += 4;
333 if ( pos == 8 ) {
334 *ncp++ = ovalue;
335 ovalue = 0;
336 pos = 0;
337 }
338 }
339 if ( pos != 0 )
340 *ncp++ = ovalue;
341 return rv;
342 }
343
344 static PyObject *
345 imageop_grey2grey2(PyObject *self, PyObject *args)
346 {
347 int x, y, len;
348 unsigned char *cp, *ncp;
349 unsigned char ovalue;
350 PyObject *rv;
351 int i;
352 int pos;
353
354
355 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
356 return 0;
357
358 if ( !check_multiply(len, x, y) )
359 return 0;
360
361 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
362 if ( rv == 0 )
363 return 0;
364 ncp = (unsigned char *)PyString_AsString(rv);
365 pos = 0;
366 ovalue = 0;
367 for ( i=0; i < len; i++ ) {
368 ovalue |= ((int)cp[i] & 0xc0) >> pos;
369 pos += 2;
370 if ( pos == 8 ) {
371 *ncp++ = ovalue;
372 ovalue = 0;
373 pos = 0;
374 }
375 }
376 if ( pos != 0 )
377 *ncp++ = ovalue;
378 return rv;
379 }
380
381 static PyObject *
382 imageop_dither2mono(PyObject *self, PyObject *args)
383 {
384 int sum, x, y, len;
385 unsigned char *cp, *ncp;
386 unsigned char ovalue;
387 PyObject *rv;
388 int i, bit;
389
390
391 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
392 return 0;
393
394 if ( !check_multiply(len, x, y) )
395 return 0;
396
397 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
398 if ( rv == 0 )
399 return 0;
400 ncp = (unsigned char *)PyString_AsString(rv);
401
402 bit = 0x80;
403 ovalue = 0;
404 sum = 0;
405 for ( i=0; i < len; i++ ) {
406 sum += cp[i];
407 if ( sum >= 256 ) {
408 sum -= 256;
409 ovalue |= bit;
410 }
411 bit >>= 1;
412 if ( bit == 0 ) {
413 *ncp++ = ovalue;
414 bit = 0x80;
415 ovalue = 0;
416 }
417 }
418 if ( bit != 0x80 )
419 *ncp++ = ovalue;
420 return rv;
421 }
422
423 static PyObject *
424 imageop_dither2grey2(PyObject *self, PyObject *args)
425 {
426 int x, y, len;
427 unsigned char *cp, *ncp;
428 unsigned char ovalue;
429 PyObject *rv;
430 int i;
431 int pos;
432 int sum = 0, nvalue;
433
434
435 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
436 return 0;
437
438 if ( !check_multiply(len, x, y) )
439 return 0;
440
441 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
442 if ( rv == 0 )
443 return 0;
444 ncp = (unsigned char *)PyString_AsString(rv);
445 pos = 1;
446 ovalue = 0;
447 for ( i=0; i < len; i++ ) {
448 sum += cp[i];
449 nvalue = sum & 0x180;
450 sum -= nvalue;
451 ovalue |= nvalue >> pos;
452 pos += 2;
453 if ( pos == 9 ) {
454 *ncp++ = ovalue;
455 ovalue = 0;
456 pos = 1;
457 }
458 }
459 if ( pos != 0 )
460 *ncp++ = ovalue;
461 return rv;
462 }
463
464 static PyObject *
465 imageop_mono2grey(PyObject *self, PyObject *args)
466 {
467 int v0, v1, x, y, len, nlen;
468 unsigned char *cp, *ncp;
469 PyObject *rv;
470 int i, bit;
471
472 if ( !PyArg_ParseTuple(args, "s#iiii", &cp, &len, &x, &y, &v0, &v1) )
473 return 0;
474
475 nlen = x*y;
476 if ( !check_multiply(nlen, x, y) )
477 return 0;
478 if ( (nlen+7)/8 != len ) {
479 PyErr_SetString(ImageopError, "String has incorrect length");
480 return 0;
481 }
482
483 rv = PyString_FromStringAndSize(NULL, nlen);
484 if ( rv == 0 )
485 return 0;
486 ncp = (unsigned char *)PyString_AsString(rv);
487
488 bit = 0x80;
489 for ( i=0; i < nlen; i++ ) {
490 if ( *cp & bit )
491 *ncp++ = v1;
492 else
493 *ncp++ = v0;
494 bit >>= 1;
495 if ( bit == 0 ) {
496 bit = 0x80;
497 cp++;
498 }
499 }
500 return rv;
501 }
502
503 static PyObject *
504 imageop_grey22grey(PyObject *self, PyObject *args)
505 {
506 int x, y, len, nlen;
507 unsigned char *cp, *ncp;
508 PyObject *rv;
509 int i, pos, value = 0, nvalue;
510
511 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
512 return 0;
513
514 nlen = x*y;
515 if ( !check_multiply(nlen, x, y) ) {
516 return 0;
517 }
518 if ( (nlen+3)/4 != len ) {
519 PyErr_SetString(ImageopError, "String has incorrect length");
520 return 0;
521 }
522
523 rv = PyString_FromStringAndSize(NULL, nlen);
524 if ( rv == 0 )
525 return 0;
526 ncp = (unsigned char *)PyString_AsString(rv);
527
528 pos = 0;
529 for ( i=0; i < nlen; i++ ) {
530 if ( pos == 0 ) {
531 value = *cp++;
532 pos = 8;
533 }
534 pos -= 2;
535 nvalue = (value >> pos) & 0x03;
536 *ncp++ = nvalue | (nvalue << 2) |
537 (nvalue << 4) | (nvalue << 6);
538 }
539 return rv;
540 }
541
542 static PyObject *
543 imageop_grey42grey(PyObject *self, PyObject *args)
544 {
545 int x, y, len, nlen;
546 unsigned char *cp, *ncp;
547 PyObject *rv;
548 int i, pos, value = 0, nvalue;
549
550 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
551 return 0;
552
553 nlen = x*y;
554 if ( !check_multiply(nlen, x, y) )
555 return 0;
556 if ( (nlen+1)/2 != len ) {
557 PyErr_SetString(ImageopError, "String has incorrect length");
558 return 0;
559 }
560
561 rv = PyString_FromStringAndSize(NULL, nlen);
562 if ( rv == 0 )
563 return 0;
564 ncp = (unsigned char *)PyString_AsString(rv);
565
566 pos = 0;
567 for ( i=0; i < nlen; i++ ) {
568 if ( pos == 0 ) {
569 value = *cp++;
570 pos = 8;
571 }
572 pos -= 4;
573 nvalue = (value >> pos) & 0x0f;
574 *ncp++ = nvalue | (nvalue << 4);
575 }
576 return rv;
577 }
578
579 static PyObject *
580 imageop_rgb2rgb8(PyObject *self, PyObject *args)
581 {
582 int x, y, len, nlen;
583 unsigned char *cp;
584 unsigned char *ncp;
585 PyObject *rv;
586 int i, r, g, b;
587 int backward_compatible = imageop_backward_compatible();
588
589 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
590 return 0;
591
592 if ( !check_multiply_size(len, x, "x", y, "y", 4) )
593 return 0;
594 nlen = x*y;
595 if ( !check_multiply(nlen, x, y) )
596 return 0;
597
598 rv = PyString_FromStringAndSize(NULL, nlen);
599 if ( rv == 0 )
600 return 0;
601 ncp = (unsigned char *)PyString_AsString(rv);
602
603 for ( i=0; i < nlen; i++ ) {
604 /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
605 if (backward_compatible) {
606 Py_UInt32 value = * (Py_UInt32 *) cp;
607 cp += 4;
608 r = (int) ((value & 0xff) / 255. * 7. + .5);
609 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
610 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
611 } else {
612 cp++; /* skip alpha channel */
613 b = (int) (*cp++ / 255. * 3. + .5);
614 g = (int) (*cp++ / 255. * 7. + .5);
615 r = (int) (*cp++ / 255. * 7. + .5);
616 }
617 *ncp++ = (unsigned char)((r<<5) | (b<<3) | g);
618 }
619 return rv;
620 }
621
622 static PyObject *
623 imageop_rgb82rgb(PyObject *self, PyObject *args)
624 {
625 int x, y, len, nlen;
626 unsigned char *cp;
627 unsigned char *ncp;
628 PyObject *rv;
629 int i, r, g, b;
630 unsigned char value;
631 int backward_compatible = imageop_backward_compatible();
632
633 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
634 return 0;
635
636 if ( !check_multiply(len, x, y) )
637 return 0;
638 nlen = x*y*4;
639 if ( !check_multiply_size(nlen, x, "x", y, "y", 4) )
640 return 0;
641
642 rv = PyString_FromStringAndSize(NULL, nlen);
643 if ( rv == 0 )
644 return 0;
645 ncp = (unsigned char *)PyString_AsString(rv);
646
647 for ( i=0; i < len; i++ ) {
648 /* Bits in source: RRRBBGGG
649 ** Red and Green are multiplied by 36.5, Blue by 85
650 */
651 value = *cp++;
652 r = (value >> 5) & 7;
653 g = (value ) & 7;
654 b = (value >> 3) & 3;
655 r = (r<<5) | (r<<3) | (r>>1);
656 g = (g<<5) | (g<<3) | (g>>1);
657 b = (b<<6) | (b<<4) | (b<<2) | b;
658 if (backward_compatible) {
659 Py_UInt32 nvalue = r | (g<<8) | (b<<16);
660 * (Py_UInt32 *) ncp = nvalue;
661 ncp += 4;
662 } else {
663 *ncp++ = 0;
664 *ncp++ = b;
665 *ncp++ = g;
666 *ncp++ = r;
667 }
668 }
669 return rv;
670 }
671
672 static PyObject *
673 imageop_rgb2grey(PyObject *self, PyObject *args)
674 {
675 int x, y, len, nlen;
676 unsigned char *cp;
677 unsigned char *ncp;
678 PyObject *rv;
679 int i, r, g, b;
680 int nvalue;
681 int backward_compatible = imageop_backward_compatible();
682
683 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
684 return 0;
685
686 if ( !check_multiply_size(len, x, "x", y, "y", 4) )
687 return 0;
688 nlen = x*y;
689 if ( !check_multiply(nlen, x, y) )
690 return 0;
691
692 rv = PyString_FromStringAndSize(NULL, nlen);
693 if ( rv == 0 )
694 return 0;
695 ncp = (unsigned char *)PyString_AsString(rv);
696
697 for ( i=0; i < nlen; i++ ) {
698 if (backward_compatible) {
699 Py_UInt32 value = * (Py_UInt32 *) cp;
700 cp += 4;
701 r = (int) ((value & 0xff) / 255. * 7. + .5);
702 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
703 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
704 } else {
705 cp++; /* skip alpha channel */
706 b = *cp++;
707 g = *cp++;
708 r = *cp++;
709 }
710 nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
711 if ( nvalue > 255 ) nvalue = 255;
712 *ncp++ = (unsigned char)nvalue;
713 }
714 return rv;
715 }
716
717 static PyObject *
718 imageop_grey2rgb(PyObject *self, PyObject *args)
719 {
720 int x, y, len, nlen;
721 unsigned char *cp;
722 unsigned char *ncp;
723 PyObject *rv;
724 int i;
725 unsigned char value;
726 int backward_compatible = imageop_backward_compatible();
727
728 if ( !PyArg_ParseTuple(args, "s#ii", &cp, &len, &x, &y) )
729 return 0;
730
731 if ( !check_multiply(len, x, y) )
732 return 0;
733 nlen = x*y*4;
734 if ( !check_multiply_size(nlen, x, "x", y, "y", 4) )
735 return 0;
736
737 rv = PyString_FromStringAndSize(NULL, nlen);
738 if ( rv == 0 )
739 return 0;
740 ncp = (unsigned char *)PyString_AsString(rv);
741
742 for ( i=0; i < len; i++ ) {
743 value = *cp++;
744 if (backward_compatible) {
745 * (Py_UInt32 *) ncp = (Py_UInt32) value | ((Py_UInt32) value << 8 ) | ((Py_UInt32) value << 16);
746 ncp += 4;
747 } else {
748 *ncp++ = 0;
749 *ncp++ = value;
750 *ncp++ = value;
751 *ncp++ = value;
752 }
753 }
754 return rv;
755 }
756
757 static PyMethodDef imageop_methods[] = {
758 { "crop", imageop_crop, METH_VARARGS },
759 { "scale", imageop_scale, METH_VARARGS },
760 { "grey2mono", imageop_grey2mono, METH_VARARGS },
761 { "grey2grey2", imageop_grey2grey2, METH_VARARGS },
762 { "grey2grey4", imageop_grey2grey4, METH_VARARGS },
763 { "dither2mono", imageop_dither2mono, METH_VARARGS },
764 { "dither2grey2", imageop_dither2grey2, METH_VARARGS },
765 { "mono2grey", imageop_mono2grey, METH_VARARGS },
766 { "grey22grey", imageop_grey22grey, METH_VARARGS },
767 { "grey42grey", imageop_grey42grey, METH_VARARGS },
768 { "tovideo", imageop_tovideo, METH_VARARGS },
769 { "rgb2rgb8", imageop_rgb2rgb8, METH_VARARGS },
770 { "rgb82rgb", imageop_rgb82rgb, METH_VARARGS },
771 { "rgb2grey", imageop_rgb2grey, METH_VARARGS },
772 { "grey2rgb", imageop_grey2rgb, METH_VARARGS },
773 { 0, 0 }
774 };
775
776
777 PyMODINIT_FUNC
778 initimageop(void)
779 {
780 PyObject *m;
781
782 if (PyErr_WarnPy3k("the imageop module has been removed in "
783 "Python 3.0", 2) < 0)
784 return;
785
786 m = Py_InitModule("imageop", imageop_methods);
787 if (m == NULL)
788 return;
789 ImageopDict = PyModule_GetDict(m);
790 ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
791 if (ImageopError != NULL)
792 PyDict_SetItemString(ImageopDict, "error", ImageopError);
793 }