blob: 5572c9fd79c1f3fd40bbc0f57ebca922dd7d01f4 [file] [log] [blame]
Guido van Rossum0317a471992-10-26 13:40:15 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum0317a471992-10-26 13:40:15 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum0317a471992-10-26 13:40:15 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum0317a471992-10-26 13:40:15 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum0317a471992-10-26 13:40:15 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum0317a471992-10-26 13:40:15 +000029
30******************************************************************/
31
32/* imageopmodule - Various operations on pictures */
33
34#ifdef sun
35#define signed
36#endif
37
Roger E. Massea141f8a1996-12-20 20:50:39 +000038#include "Python.h"
Guido van Rossum0317a471992-10-26 13:40:15 +000039
Guido van Rossum69011961998-04-23 20:23:00 +000040#if SIZEOF_INT == 4
41typedef int Py_Int32;
42typedef unsigned int Py_UInt32;
43#else
44#if SIZEOF_LONG == 4
45typedef long Py_Int32;
46typedef unsigned long Py_UInt32;
47#else
48#error "No 4-byte integral type"
49#endif
50#endif
51
Guido van Rossum0317a471992-10-26 13:40:15 +000052#define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
Jack Jansen76c79e91996-01-22 14:55:15 +000053#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
Guido van Rossum69011961998-04-23 20:23:00 +000054#define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x)))
Guido van Rossum0317a471992-10-26 13:40:15 +000055
Roger E. Massea141f8a1996-12-20 20:50:39 +000056static PyObject *ImageopError;
Guido van Rossum0317a471992-10-26 13:40:15 +000057
Roger E. Massea141f8a1996-12-20 20:50:39 +000058static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +000059imageop_crop(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +000060 PyObject *self;
61PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +000062{
Roger E. Massea141f8a1996-12-20 20:50:39 +000063 char *cp, *ncp;
64 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +000065 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000066 int len, size, x, y, newx1, newx2, newy1, newy2;
67 int ix, iy, xstep, ystep;
68 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000069
Roger E. Massea141f8a1996-12-20 20:50:39 +000070 if ( !PyArg_Parse(args, "(s#iiiiiii)", &cp, &len, &size, &x, &y,
71 &newx1, &newy1, &newx2, &newy2) )
72 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000073
Roger E. Massea141f8a1996-12-20 20:50:39 +000074 if ( size != 1 && size != 2 && size != 4 ) {
75 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
76 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000077 }
Roger E. Massea141f8a1996-12-20 20:50:39 +000078 if ( len != size*x*y ) {
79 PyErr_SetString(ImageopError, "String has incorrect length");
80 return 0;
81 }
82 xstep = (newx1 < newx2)? 1 : -1;
83 ystep = (newy1 < newy2)? 1 : -1;
84
85 rv = PyString_FromStringAndSize(NULL,
86 (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
87 if ( rv == 0 )
88 return 0;
89 ncp = (char *)PyString_AsString(rv);
90 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +000091 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000092 newy2 += ystep;
93 newx2 += xstep;
94 for( iy = newy1; iy != newy2; iy+=ystep ) {
95 for ( ix = newx1; ix != newx2; ix+=xstep ) {
96 if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
97 if ( size == 1 )
98 *ncp++ = 0;
99 else
100 *nlp++ = 0;
101 } else {
102 if ( size == 1 )
103 *ncp++ = *CHARP(cp, x, ix, iy);
104 else if ( size == 2 )
105 *nsp++ = *SHORTP(cp, x, ix, iy);
106 else
107 *nlp++ = *LONGP(cp, x, ix, iy);
108 }
109 }
110 }
111 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000112}
113
Roger E. Massea141f8a1996-12-20 20:50:39 +0000114static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +0000115imageop_scale(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000116 PyObject *self;
117PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000118{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000119 char *cp, *ncp;
120 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +0000121 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000122 int len, size, x, y, newx, newy;
123 int ix, iy;
124 int oix, oiy;
125 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000126
Roger E. Massea141f8a1996-12-20 20:50:39 +0000127 if ( !PyArg_Parse(args, "(s#iiiii)",
128 &cp, &len, &size, &x, &y, &newx, &newy) )
129 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000130
Roger E. Massea141f8a1996-12-20 20:50:39 +0000131 if ( size != 1 && size != 2 && size != 4 ) {
132 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
133 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000134 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000135 if ( len != size*x*y ) {
136 PyErr_SetString(ImageopError, "String has incorrect length");
137 return 0;
138 }
139
140 rv = PyString_FromStringAndSize(NULL, newx*newy*size);
141 if ( rv == 0 )
142 return 0;
143 ncp = (char *)PyString_AsString(rv);
144 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +0000145 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000146 for( iy = 0; iy < newy; iy++ ) {
147 for ( ix = 0; ix < newx; ix++ ) {
148 oix = ix * x / newx;
149 oiy = iy * y / newy;
150 if ( size == 1 )
151 *ncp++ = *CHARP(cp, x, oix, oiy);
152 else if ( size == 2 )
153 *nsp++ = *SHORTP(cp, x, oix, oiy);
154 else
155 *nlp++ = *LONGP(cp, x, oix, oiy);
156 }
157 }
158 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000159}
160
Jack Jansend26b4581993-01-22 15:34:43 +0000161/* Note: this routine can use a bit of optimizing */
162
Roger E. Massea141f8a1996-12-20 20:50:39 +0000163static PyObject *
Jack Jansend26b4581993-01-22 15:34:43 +0000164imageop_tovideo(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000165 PyObject *self;
166PyObject *args;
Jack Jansend26b4581993-01-22 15:34:43 +0000167{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000168 int maxx, maxy, x, y, len;
169 int i;
170 unsigned char *cp, *ncp;
171 int width;
172 PyObject *rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000173
174
Roger E. Massea141f8a1996-12-20 20:50:39 +0000175 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &width, &maxx, &maxy) )
176 return 0;
Jack Jansend26b4581993-01-22 15:34:43 +0000177
Roger E. Massea141f8a1996-12-20 20:50:39 +0000178 if ( width != 1 && width != 4 ) {
179 PyErr_SetString(ImageopError, "Size should be 1 or 4");
180 return 0;
181 }
182 if ( maxx*maxy*width != len ) {
183 PyErr_SetString(ImageopError, "String has incorrect length");
184 return 0;
185 }
Jack Jansend26b4581993-01-22 15:34:43 +0000186
Roger E. Massea141f8a1996-12-20 20:50:39 +0000187 rv = PyString_FromStringAndSize(NULL, len);
188 if ( rv == 0 )
189 return 0;
190 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansend26b4581993-01-22 15:34:43 +0000191
Roger E. Massea141f8a1996-12-20 20:50:39 +0000192 if ( width == 1 ) {
193 memcpy(ncp, cp, maxx); /* Copy first line */
194 ncp += maxx;
195 for (y=1; y<maxy; y++) { /* Interpolate other lines */
196 for(x=0; x<maxx; x++) {
197 i = y*maxx + x;
198 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
199 }
200 }
201 } else {
202 memcpy(ncp, cp, maxx*4); /* Copy first line */
203 ncp += maxx*4;
204 for (y=1; y<maxy; y++) { /* Interpolate other lines */
205 for(x=0; x<maxx; x++) {
206 i = (y*maxx + x)*4 + 1;
207 *ncp++ = 0; /* Skip alfa comp */
208 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
209 i++;
210 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
211 i++;
212 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
213 }
214 }
Jack Jansend26b4581993-01-22 15:34:43 +0000215 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000216 return rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000217}
218
Roger E. Massea141f8a1996-12-20 20:50:39 +0000219static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000220imageop_grey2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000221 PyObject *self;
222PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000223{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000224 int tres, x, y, len;
225 unsigned char *cp, *ncp;
226 unsigned char ovalue;
227 PyObject *rv;
228 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000229
230
Roger E. Massea141f8a1996-12-20 20:50:39 +0000231 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &x, &y, &tres) )
232 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000233
Roger E. Massea141f8a1996-12-20 20:50:39 +0000234 if ( x*y != len ) {
235 PyErr_SetString(ImageopError, "String has incorrect length");
236 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000237 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000238
239 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
240 if ( rv == 0 )
241 return 0;
242 ncp = (unsigned char *)PyString_AsString(rv);
243
244 bit = 0x80;
245 ovalue = 0;
246 for ( i=0; i < len; i++ ) {
247 if ( (int)cp[i] > tres )
248 ovalue |= bit;
249 bit >>= 1;
250 if ( bit == 0 ) {
251 *ncp++ = ovalue;
252 bit = 0x80;
253 ovalue = 0;
254 }
255 }
256 if ( bit != 0x80 )
257 *ncp++ = ovalue;
258 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000259}
260
Roger E. Massea141f8a1996-12-20 20:50:39 +0000261static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000262imageop_grey2grey4(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000263 PyObject *self;
264PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000265{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000266 int x, y, len;
267 unsigned char *cp, *ncp;
268 unsigned char ovalue;
269 PyObject *rv;
270 int i;
271 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000272
273
Roger E. Massea141f8a1996-12-20 20:50:39 +0000274 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
275 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000276
Roger E. Massea141f8a1996-12-20 20:50:39 +0000277 if ( x*y != len ) {
278 PyErr_SetString(ImageopError, "String has incorrect length");
279 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000280 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000281
282 rv = PyString_FromStringAndSize(NULL, (len+1)/2);
283 if ( rv == 0 )
284 return 0;
285 ncp = (unsigned char *)PyString_AsString(rv);
286 pos = 0;
287 ovalue = 0;
288 for ( i=0; i < len; i++ ) {
289 ovalue |= ((int)cp[i] & 0xf0) >> pos;
290 pos += 4;
291 if ( pos == 8 ) {
292 *ncp++ = ovalue;
293 ovalue = 0;
294 pos = 0;
295 }
296 }
297 if ( pos != 0 )
298 *ncp++ = ovalue;
299 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000300}
301
Roger E. Massea141f8a1996-12-20 20:50:39 +0000302static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000303imageop_grey2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000304 PyObject *self;
305PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000306{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000307 int x, y, len;
308 unsigned char *cp, *ncp;
309 unsigned char ovalue;
310 PyObject *rv;
311 int i;
312 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000313
314
Roger E. Massea141f8a1996-12-20 20:50:39 +0000315 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
316 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000317
Roger E. Massea141f8a1996-12-20 20:50:39 +0000318 if ( x*y != len ) {
319 PyErr_SetString(ImageopError, "String has incorrect length");
320 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000321 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000322
323 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
324 if ( rv == 0 )
325 return 0;
326 ncp = (unsigned char *)PyString_AsString(rv);
327 pos = 0;
328 ovalue = 0;
329 for ( i=0; i < len; i++ ) {
330 ovalue |= ((int)cp[i] & 0xc0) >> pos;
331 pos += 2;
332 if ( pos == 8 ) {
333 *ncp++ = ovalue;
334 ovalue = 0;
335 pos = 0;
336 }
337 }
338 if ( pos != 0 )
339 *ncp++ = ovalue;
340 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000341}
342
Roger E. Massea141f8a1996-12-20 20:50:39 +0000343static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000344imageop_dither2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000345 PyObject *self;
346PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000347{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000348 int sum, x, y, len;
349 unsigned char *cp, *ncp;
350 unsigned char ovalue;
351 PyObject *rv;
352 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000353
354
Roger E. Massea141f8a1996-12-20 20:50:39 +0000355 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
356 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000357
Roger E. Massea141f8a1996-12-20 20:50:39 +0000358 if ( x*y != len ) {
359 PyErr_SetString(ImageopError, "String has incorrect length");
360 return 0;
361 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000362
Roger E. Massea141f8a1996-12-20 20:50:39 +0000363 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
364 if ( rv == 0 )
365 return 0;
366 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000367
Roger E. Massea141f8a1996-12-20 20:50:39 +0000368 bit = 0x80;
369 ovalue = 0;
370 sum = 0;
371 for ( i=0; i < len; i++ ) {
372 sum += cp[i];
373 if ( sum >= 256 ) {
374 sum -= 256;
375 ovalue |= bit;
376 }
377 bit >>= 1;
378 if ( bit == 0 ) {
379 *ncp++ = ovalue;
380 bit = 0x80;
381 ovalue = 0;
382 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000383 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000384 if ( bit != 0x80 )
385 *ncp++ = ovalue;
386 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000387}
388
Roger E. Massea141f8a1996-12-20 20:50:39 +0000389static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000390imageop_dither2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000391 PyObject *self;
392PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000393{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000394 int x, y, len;
395 unsigned char *cp, *ncp;
396 unsigned char ovalue;
397 PyObject *rv;
398 int i;
399 int pos;
400 int sum = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000401
402
Roger E. Massea141f8a1996-12-20 20:50:39 +0000403 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
404 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000405
Roger E. Massea141f8a1996-12-20 20:50:39 +0000406 if ( x*y != len ) {
407 PyErr_SetString(ImageopError, "String has incorrect length");
408 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000409 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000410
411 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
412 if ( rv == 0 )
413 return 0;
414 ncp = (unsigned char *)PyString_AsString(rv);
415 pos = 1;
416 ovalue = 0;
417 for ( i=0; i < len; i++ ) {
418 sum += cp[i];
419 nvalue = sum & 0x180;
420 sum -= nvalue;
421 ovalue |= nvalue >> pos;
422 pos += 2;
423 if ( pos == 9 ) {
424 *ncp++ = ovalue;
425 ovalue = 0;
426 pos = 1;
427 }
428 }
429 if ( pos != 0 )
430 *ncp++ = ovalue;
431 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000432}
433
Roger E. Massea141f8a1996-12-20 20:50:39 +0000434static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000435imageop_mono2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000436 PyObject *self;
437PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000438{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000439 int v0, v1, x, y, len, nlen;
440 unsigned char *cp, *ncp;
441 PyObject *rv;
442 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000443
Roger E. Massea141f8a1996-12-20 20:50:39 +0000444 if ( !PyArg_Parse(args, "(s#iiii)", &cp, &len, &x, &y, &v0, &v1) )
445 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000446
Roger E. Massea141f8a1996-12-20 20:50:39 +0000447 nlen = x*y;
448 if ( (nlen+7)/8 != len ) {
449 PyErr_SetString(ImageopError, "String has incorrect length");
450 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000451 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000452
453 rv = PyString_FromStringAndSize(NULL, nlen);
454 if ( rv == 0 )
455 return 0;
456 ncp = (unsigned char *)PyString_AsString(rv);
457
458 bit = 0x80;
459 for ( i=0; i < nlen; i++ ) {
460 if ( *cp & bit )
461 *ncp++ = v1;
462 else
463 *ncp++ = v0;
464 bit >>= 1;
465 if ( bit == 0 ) {
466 bit = 0x80;
467 cp++;
468 }
469 }
470 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000471}
472
Roger E. Massea141f8a1996-12-20 20:50:39 +0000473static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000474imageop_grey22grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000475 PyObject *self;
476PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000477{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000478 int x, y, len, nlen;
479 unsigned char *cp, *ncp;
480 PyObject *rv;
481 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000482
Roger E. Massea141f8a1996-12-20 20:50:39 +0000483 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
484 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000485
Roger E. Massea141f8a1996-12-20 20:50:39 +0000486 nlen = x*y;
487 if ( (nlen+3)/4 != len ) {
488 PyErr_SetString(ImageopError, "String has incorrect length");
489 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000490 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000491
492 rv = PyString_FromStringAndSize(NULL, nlen);
493 if ( rv == 0 )
494 return 0;
495 ncp = (unsigned char *)PyString_AsString(rv);
496
497 pos = 0;
498 for ( i=0; i < nlen; i++ ) {
499 if ( pos == 0 ) {
500 value = *cp++;
501 pos = 8;
502 }
503 pos -= 2;
504 nvalue = (value >> pos) & 0x03;
505 *ncp++ = nvalue | (nvalue << 2) |
506 (nvalue << 4) | (nvalue << 6);
507 }
508 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000509}
510
Roger E. Massea141f8a1996-12-20 20:50:39 +0000511static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000512imageop_grey42grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000513 PyObject *self;
514PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000515{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000516 int x, y, len, nlen;
517 unsigned char *cp, *ncp;
518 PyObject *rv;
519 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000520
Roger E. Massea141f8a1996-12-20 20:50:39 +0000521 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
522 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000523
Roger E. Massea141f8a1996-12-20 20:50:39 +0000524 nlen = x*y;
525 if ( (nlen+1)/2 != len ) {
526 PyErr_SetString(ImageopError, "String has incorrect length");
527 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000528 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000529
530 rv = PyString_FromStringAndSize(NULL, nlen);
531 if ( rv == 0 )
532 return 0;
533 ncp = (unsigned char *)PyString_AsString(rv);
534
535 pos = 0;
536 for ( i=0; i < nlen; i++ ) {
537 if ( pos == 0 ) {
538 value = *cp++;
539 pos = 8;
540 }
541 pos -= 4;
542 nvalue = (value >> pos) & 0x0f;
543 *ncp++ = nvalue | (nvalue << 4);
544 }
545 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000546}
547
Roger E. Massea141f8a1996-12-20 20:50:39 +0000548static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000549imageop_rgb2rgb8(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000550 PyObject *self;
551PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000552{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000553 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000554 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000555 unsigned char *ncp;
556 PyObject *rv;
557 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000558 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000559
Roger E. Massea141f8a1996-12-20 20:50:39 +0000560 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
561 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000562
Roger E. Massea141f8a1996-12-20 20:50:39 +0000563 nlen = x*y;
564 if ( nlen*4 != len ) {
565 PyErr_SetString(ImageopError, "String has incorrect length");
566 return 0;
567 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000568
Roger E. Massea141f8a1996-12-20 20:50:39 +0000569 rv = PyString_FromStringAndSize(NULL, nlen);
570 if ( rv == 0 )
571 return 0;
572 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000573
Roger E. Massea141f8a1996-12-20 20:50:39 +0000574 for ( i=0; i < nlen; i++ ) {
575 /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
576 value = *cp++;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000577#if 0
Roger E. Massea141f8a1996-12-20 20:50:39 +0000578 r = (value >> 5) & 7;
579 g = (value >> 13) & 7;
580 b = (value >> 22) & 3;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000581#else
Roger E. Massea141f8a1996-12-20 20:50:39 +0000582 r = (int) ((value & 0xff) / 255. * 7. + .5);
583 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
584 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000585#endif
Roger E. Massea141f8a1996-12-20 20:50:39 +0000586 nvalue = (r<<5) | (b<<3) | g;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000587 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000588 }
589 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000590}
591
Roger E. Massea141f8a1996-12-20 20:50:39 +0000592static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000593imageop_rgb82rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000594 PyObject *self;
595PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000596{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000597 int x, y, len, nlen;
598 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000599 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000600 PyObject *rv;
601 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000602 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000603
Roger E. Massea141f8a1996-12-20 20:50:39 +0000604 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
605 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000606
Roger E. Massea141f8a1996-12-20 20:50:39 +0000607 nlen = x*y;
608 if ( nlen != len ) {
609 PyErr_SetString(ImageopError, "String has incorrect length");
610 return 0;
611 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000612
Roger E. Massea141f8a1996-12-20 20:50:39 +0000613 rv = PyString_FromStringAndSize(NULL, nlen*4);
614 if ( rv == 0 )
615 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000616 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000617
Roger E. Massea141f8a1996-12-20 20:50:39 +0000618 for ( i=0; i < nlen; i++ ) {
619 /* Bits in source: RRRBBGGG
620 ** Red and Green are multiplied by 36.5, Blue by 85
621 */
622 value = *cp++;
623 r = (value >> 5) & 7;
624 g = (value ) & 7;
625 b = (value >> 3) & 3;
626 r = (r<<5) | (r<<3) | (r>>1);
627 g = (g<<5) | (g<<3) | (g>>1);
628 b = (b<<6) | (b<<4) | (b<<2) | b;
629 nvalue = r | (g<<8) | (b<<16);
630 *ncp++ = nvalue;
631 }
632 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000633}
634
Roger E. Massea141f8a1996-12-20 20:50:39 +0000635static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000636imageop_rgb2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000637 PyObject *self;
638PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000639{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000640 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000641 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000642 unsigned char *ncp;
643 PyObject *rv;
644 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000645 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000646
Roger E. Massea141f8a1996-12-20 20:50:39 +0000647 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
648 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000649
Roger E. Massea141f8a1996-12-20 20:50:39 +0000650 nlen = x*y;
651 if ( nlen*4 != len ) {
652 PyErr_SetString(ImageopError, "String has incorrect length");
653 return 0;
654 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000655
Roger E. Massea141f8a1996-12-20 20:50:39 +0000656 rv = PyString_FromStringAndSize(NULL, nlen);
657 if ( rv == 0 )
658 return 0;
659 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000660
Roger E. Massea141f8a1996-12-20 20:50:39 +0000661 for ( i=0; i < nlen; i++ ) {
662 value = *cp++;
663 r = (value ) & 0xff;
664 g = (value >> 8) & 0xff;
665 b = (value >> 16) & 0xff;
666 nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
667 if ( nvalue > 255 ) nvalue = 255;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000668 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000669 }
670 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000671}
672
Roger E. Massea141f8a1996-12-20 20:50:39 +0000673static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000674imageop_grey2rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000675 PyObject *self;
676PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000677{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000678 int x, y, len, nlen;
679 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000680 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000681 PyObject *rv;
682 int i;
Guido van Rossum69011961998-04-23 20:23:00 +0000683 Py_UInt32 value;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000684
Roger E. Massea141f8a1996-12-20 20:50:39 +0000685 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
686 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000687
Roger E. Massea141f8a1996-12-20 20:50:39 +0000688 nlen = x*y;
689 if ( nlen != len ) {
690 PyErr_SetString(ImageopError, "String has incorrect length");
691 return 0;
692 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000693
Roger E. Massea141f8a1996-12-20 20:50:39 +0000694 rv = PyString_FromStringAndSize(NULL, nlen*4);
695 if ( rv == 0 )
696 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000697 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000698
Roger E. Massea141f8a1996-12-20 20:50:39 +0000699 for ( i=0; i < nlen; i++ ) {
700 value = *cp++;
701 *ncp++ = value | (value << 8 ) | (value << 16);
702 }
703 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000704}
705
Guido van Rossum0317a471992-10-26 13:40:15 +0000706/*
707static object *
708imageop_mul(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000709 object *self;
710object *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000711{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000712 char *cp, *ncp;
713 int len, size, x, y;
714 object *rv;
715 int i;
Guido van Rossum0317a471992-10-26 13:40:15 +0000716
Roger E. Massea141f8a1996-12-20 20:50:39 +0000717 if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
718 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000719
Roger E. Massea141f8a1996-12-20 20:50:39 +0000720 if ( size != 1 && size != 4 ) {
721 err_setstr(ImageopError, "Size should be 1 or 4");
722 return 0;
723 }
724 if ( len != size*x*y ) {
725 err_setstr(ImageopError, "String has incorrect length");
726 return 0;
727 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000728
Roger E. Massea141f8a1996-12-20 20:50:39 +0000729 rv = newsizedstringobject(NULL, XXXX);
730 if ( rv == 0 )
731 return 0;
732 ncp = (char *)getstringvalue(rv);
Guido van Rossum0317a471992-10-26 13:40:15 +0000733
734
Roger E. Massea141f8a1996-12-20 20:50:39 +0000735 for ( i=0; i < len; i += size ) {
736 }
737 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000738}
739*/
740
Roger E. Massea141f8a1996-12-20 20:50:39 +0000741static PyMethodDef imageop_methods[] = {
742 { "crop", imageop_crop },
743 { "scale", imageop_scale },
744 { "grey2mono", imageop_grey2mono },
745 { "grey2grey2", imageop_grey2grey2 },
746 { "grey2grey4", imageop_grey2grey4 },
747 { "dither2mono", imageop_dither2mono },
748 { "dither2grey2", imageop_dither2grey2 },
749 { "mono2grey", imageop_mono2grey },
750 { "grey22grey", imageop_grey22grey },
751 { "grey42grey", imageop_grey42grey },
752 { "tovideo", imageop_tovideo },
753 { "rgb2rgb8", imageop_rgb2rgb8 },
754 { "rgb82rgb", imageop_rgb82rgb },
755 { "rgb2grey", imageop_rgb2grey },
756 { "grey2rgb", imageop_grey2rgb },
757 { 0, 0 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000758};
759
760
Guido van Rossum3886bb61998-12-04 18:50:17 +0000761DL_EXPORT(void)
Guido van Rossum0317a471992-10-26 13:40:15 +0000762initimageop()
763{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000764 PyObject *m, *d;
765 m = Py_InitModule("imageop", imageop_methods);
766 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000767 ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
768 if (ImageopError != NULL)
769 PyDict_SetItemString(d, "error", ImageopError);
Guido van Rossum0317a471992-10-26 13:40:15 +0000770}