blob: 108d4504be1e8e3bb0a3dba85b747c477f4bbf4f [file] [log] [blame]
Guido van Rossum0317a471992-10-26 13:40:15 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum0317a471992-10-26 13:40:15 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum0317a471992-10-26 13:40:15 +00009******************************************************************/
10
11/* imageopmodule - Various operations on pictures */
12
13#ifdef sun
14#define signed
15#endif
16
Roger E. Massea141f8a1996-12-20 20:50:39 +000017#include "Python.h"
Guido van Rossum0317a471992-10-26 13:40:15 +000018
Guido van Rossum69011961998-04-23 20:23:00 +000019#if SIZEOF_INT == 4
20typedef int Py_Int32;
21typedef unsigned int Py_UInt32;
22#else
23#if SIZEOF_LONG == 4
24typedef long Py_Int32;
25typedef unsigned long Py_UInt32;
26#else
27#error "No 4-byte integral type"
28#endif
29#endif
30
Guido van Rossum0317a471992-10-26 13:40:15 +000031#define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
Jack Jansen76c79e91996-01-22 14:55:15 +000032#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
Guido van Rossum69011961998-04-23 20:23:00 +000033#define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x)))
Guido van Rossum0317a471992-10-26 13:40:15 +000034
Roger E. Massea141f8a1996-12-20 20:50:39 +000035static PyObject *ImageopError;
Guido van Rossum0317a471992-10-26 13:40:15 +000036
Roger E. Massea141f8a1996-12-20 20:50:39 +000037static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +000038imageop_crop(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +000039 PyObject *self;
40PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +000041{
Roger E. Massea141f8a1996-12-20 20:50:39 +000042 char *cp, *ncp;
43 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +000044 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000045 int len, size, x, y, newx1, newx2, newy1, newy2;
46 int ix, iy, xstep, ystep;
47 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000048
Roger E. Massea141f8a1996-12-20 20:50:39 +000049 if ( !PyArg_Parse(args, "(s#iiiiiii)", &cp, &len, &size, &x, &y,
50 &newx1, &newy1, &newx2, &newy2) )
51 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000052
Roger E. Massea141f8a1996-12-20 20:50:39 +000053 if ( size != 1 && size != 2 && size != 4 ) {
54 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
55 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000056 }
Roger E. Massea141f8a1996-12-20 20:50:39 +000057 if ( len != size*x*y ) {
58 PyErr_SetString(ImageopError, "String has incorrect length");
59 return 0;
60 }
61 xstep = (newx1 < newx2)? 1 : -1;
62 ystep = (newy1 < newy2)? 1 : -1;
63
64 rv = PyString_FromStringAndSize(NULL,
65 (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
66 if ( rv == 0 )
67 return 0;
68 ncp = (char *)PyString_AsString(rv);
69 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +000070 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000071 newy2 += ystep;
72 newx2 += xstep;
73 for( iy = newy1; iy != newy2; iy+=ystep ) {
74 for ( ix = newx1; ix != newx2; ix+=xstep ) {
75 if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
76 if ( size == 1 )
77 *ncp++ = 0;
78 else
79 *nlp++ = 0;
80 } else {
81 if ( size == 1 )
82 *ncp++ = *CHARP(cp, x, ix, iy);
83 else if ( size == 2 )
84 *nsp++ = *SHORTP(cp, x, ix, iy);
85 else
86 *nlp++ = *LONGP(cp, x, ix, iy);
87 }
88 }
89 }
90 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000091}
92
Roger E. Massea141f8a1996-12-20 20:50:39 +000093static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +000094imageop_scale(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +000095 PyObject *self;
96PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +000097{
Roger E. Massea141f8a1996-12-20 20:50:39 +000098 char *cp, *ncp;
99 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +0000100 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000101 int len, size, x, y, newx, newy;
102 int ix, iy;
103 int oix, oiy;
104 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000105
Roger E. Massea141f8a1996-12-20 20:50:39 +0000106 if ( !PyArg_Parse(args, "(s#iiiii)",
107 &cp, &len, &size, &x, &y, &newx, &newy) )
108 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000109
Roger E. Massea141f8a1996-12-20 20:50:39 +0000110 if ( size != 1 && size != 2 && size != 4 ) {
111 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
112 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000113 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000114 if ( len != size*x*y ) {
115 PyErr_SetString(ImageopError, "String has incorrect length");
116 return 0;
117 }
118
119 rv = PyString_FromStringAndSize(NULL, newx*newy*size);
120 if ( rv == 0 )
121 return 0;
122 ncp = (char *)PyString_AsString(rv);
123 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +0000124 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000125 for( iy = 0; iy < newy; iy++ ) {
126 for ( ix = 0; ix < newx; ix++ ) {
127 oix = ix * x / newx;
128 oiy = iy * y / newy;
129 if ( size == 1 )
130 *ncp++ = *CHARP(cp, x, oix, oiy);
131 else if ( size == 2 )
132 *nsp++ = *SHORTP(cp, x, oix, oiy);
133 else
134 *nlp++ = *LONGP(cp, x, oix, oiy);
135 }
136 }
137 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000138}
139
Jack Jansend26b4581993-01-22 15:34:43 +0000140/* Note: this routine can use a bit of optimizing */
141
Roger E. Massea141f8a1996-12-20 20:50:39 +0000142static PyObject *
Jack Jansend26b4581993-01-22 15:34:43 +0000143imageop_tovideo(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000144 PyObject *self;
145PyObject *args;
Jack Jansend26b4581993-01-22 15:34:43 +0000146{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000147 int maxx, maxy, x, y, len;
148 int i;
149 unsigned char *cp, *ncp;
150 int width;
151 PyObject *rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000152
153
Roger E. Massea141f8a1996-12-20 20:50:39 +0000154 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &width, &maxx, &maxy) )
155 return 0;
Jack Jansend26b4581993-01-22 15:34:43 +0000156
Roger E. Massea141f8a1996-12-20 20:50:39 +0000157 if ( width != 1 && width != 4 ) {
158 PyErr_SetString(ImageopError, "Size should be 1 or 4");
159 return 0;
160 }
161 if ( maxx*maxy*width != len ) {
162 PyErr_SetString(ImageopError, "String has incorrect length");
163 return 0;
164 }
Jack Jansend26b4581993-01-22 15:34:43 +0000165
Roger E. Massea141f8a1996-12-20 20:50:39 +0000166 rv = PyString_FromStringAndSize(NULL, len);
167 if ( rv == 0 )
168 return 0;
169 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansend26b4581993-01-22 15:34:43 +0000170
Roger E. Massea141f8a1996-12-20 20:50:39 +0000171 if ( width == 1 ) {
172 memcpy(ncp, cp, maxx); /* Copy first line */
173 ncp += maxx;
174 for (y=1; y<maxy; y++) { /* Interpolate other lines */
175 for(x=0; x<maxx; x++) {
176 i = y*maxx + x;
177 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
178 }
179 }
180 } else {
181 memcpy(ncp, cp, maxx*4); /* Copy first line */
182 ncp += maxx*4;
183 for (y=1; y<maxy; y++) { /* Interpolate other lines */
184 for(x=0; x<maxx; x++) {
185 i = (y*maxx + x)*4 + 1;
186 *ncp++ = 0; /* Skip alfa comp */
187 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
188 i++;
189 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
190 i++;
191 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
192 }
193 }
Jack Jansend26b4581993-01-22 15:34:43 +0000194 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000195 return rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000196}
197
Roger E. Massea141f8a1996-12-20 20:50:39 +0000198static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000199imageop_grey2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000200 PyObject *self;
201PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000202{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000203 int tres, x, y, len;
204 unsigned char *cp, *ncp;
205 unsigned char ovalue;
206 PyObject *rv;
207 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000208
209
Roger E. Massea141f8a1996-12-20 20:50:39 +0000210 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &x, &y, &tres) )
211 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000212
Roger E. Massea141f8a1996-12-20 20:50:39 +0000213 if ( x*y != len ) {
214 PyErr_SetString(ImageopError, "String has incorrect length");
215 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000216 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000217
218 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
219 if ( rv == 0 )
220 return 0;
221 ncp = (unsigned char *)PyString_AsString(rv);
222
223 bit = 0x80;
224 ovalue = 0;
225 for ( i=0; i < len; i++ ) {
226 if ( (int)cp[i] > tres )
227 ovalue |= bit;
228 bit >>= 1;
229 if ( bit == 0 ) {
230 *ncp++ = ovalue;
231 bit = 0x80;
232 ovalue = 0;
233 }
234 }
235 if ( bit != 0x80 )
236 *ncp++ = ovalue;
237 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000238}
239
Roger E. Massea141f8a1996-12-20 20:50:39 +0000240static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000241imageop_grey2grey4(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000242 PyObject *self;
243PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000244{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000245 int x, y, len;
246 unsigned char *cp, *ncp;
247 unsigned char ovalue;
248 PyObject *rv;
249 int i;
250 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000251
252
Roger E. Massea141f8a1996-12-20 20:50:39 +0000253 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
254 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000255
Roger E. Massea141f8a1996-12-20 20:50:39 +0000256 if ( x*y != len ) {
257 PyErr_SetString(ImageopError, "String has incorrect length");
258 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000259 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000260
261 rv = PyString_FromStringAndSize(NULL, (len+1)/2);
262 if ( rv == 0 )
263 return 0;
264 ncp = (unsigned char *)PyString_AsString(rv);
265 pos = 0;
266 ovalue = 0;
267 for ( i=0; i < len; i++ ) {
268 ovalue |= ((int)cp[i] & 0xf0) >> pos;
269 pos += 4;
270 if ( pos == 8 ) {
271 *ncp++ = ovalue;
272 ovalue = 0;
273 pos = 0;
274 }
275 }
276 if ( pos != 0 )
277 *ncp++ = ovalue;
278 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000279}
280
Roger E. Massea141f8a1996-12-20 20:50:39 +0000281static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000282imageop_grey2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000283 PyObject *self;
284PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000285{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000286 int x, y, len;
287 unsigned char *cp, *ncp;
288 unsigned char ovalue;
289 PyObject *rv;
290 int i;
291 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000292
293
Roger E. Massea141f8a1996-12-20 20:50:39 +0000294 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
295 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000296
Roger E. Massea141f8a1996-12-20 20:50:39 +0000297 if ( x*y != len ) {
298 PyErr_SetString(ImageopError, "String has incorrect length");
299 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000300 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000301
302 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
303 if ( rv == 0 )
304 return 0;
305 ncp = (unsigned char *)PyString_AsString(rv);
306 pos = 0;
307 ovalue = 0;
308 for ( i=0; i < len; i++ ) {
309 ovalue |= ((int)cp[i] & 0xc0) >> pos;
310 pos += 2;
311 if ( pos == 8 ) {
312 *ncp++ = ovalue;
313 ovalue = 0;
314 pos = 0;
315 }
316 }
317 if ( pos != 0 )
318 *ncp++ = ovalue;
319 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000320}
321
Roger E. Massea141f8a1996-12-20 20:50:39 +0000322static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000323imageop_dither2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000324 PyObject *self;
325PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000326{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000327 int sum, x, y, len;
328 unsigned char *cp, *ncp;
329 unsigned char ovalue;
330 PyObject *rv;
331 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000332
333
Roger E. Massea141f8a1996-12-20 20:50:39 +0000334 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
335 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000336
Roger E. Massea141f8a1996-12-20 20:50:39 +0000337 if ( x*y != len ) {
338 PyErr_SetString(ImageopError, "String has incorrect length");
339 return 0;
340 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000341
Roger E. Massea141f8a1996-12-20 20:50:39 +0000342 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
343 if ( rv == 0 )
344 return 0;
345 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000346
Roger E. Massea141f8a1996-12-20 20:50:39 +0000347 bit = 0x80;
348 ovalue = 0;
349 sum = 0;
350 for ( i=0; i < len; i++ ) {
351 sum += cp[i];
352 if ( sum >= 256 ) {
353 sum -= 256;
354 ovalue |= bit;
355 }
356 bit >>= 1;
357 if ( bit == 0 ) {
358 *ncp++ = ovalue;
359 bit = 0x80;
360 ovalue = 0;
361 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000362 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000363 if ( bit != 0x80 )
364 *ncp++ = ovalue;
365 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000366}
367
Roger E. Massea141f8a1996-12-20 20:50:39 +0000368static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000369imageop_dither2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000370 PyObject *self;
371PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000372{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000373 int x, y, len;
374 unsigned char *cp, *ncp;
375 unsigned char ovalue;
376 PyObject *rv;
377 int i;
378 int pos;
379 int sum = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000380
381
Roger E. Massea141f8a1996-12-20 20:50:39 +0000382 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
383 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000384
Roger E. Massea141f8a1996-12-20 20:50:39 +0000385 if ( x*y != len ) {
386 PyErr_SetString(ImageopError, "String has incorrect length");
387 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000388 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000389
390 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
391 if ( rv == 0 )
392 return 0;
393 ncp = (unsigned char *)PyString_AsString(rv);
394 pos = 1;
395 ovalue = 0;
396 for ( i=0; i < len; i++ ) {
397 sum += cp[i];
398 nvalue = sum & 0x180;
399 sum -= nvalue;
400 ovalue |= nvalue >> pos;
401 pos += 2;
402 if ( pos == 9 ) {
403 *ncp++ = ovalue;
404 ovalue = 0;
405 pos = 1;
406 }
407 }
408 if ( pos != 0 )
409 *ncp++ = ovalue;
410 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000411}
412
Roger E. Massea141f8a1996-12-20 20:50:39 +0000413static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000414imageop_mono2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000415 PyObject *self;
416PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000417{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000418 int v0, v1, x, y, len, nlen;
419 unsigned char *cp, *ncp;
420 PyObject *rv;
421 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000422
Roger E. Massea141f8a1996-12-20 20:50:39 +0000423 if ( !PyArg_Parse(args, "(s#iiii)", &cp, &len, &x, &y, &v0, &v1) )
424 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000425
Roger E. Massea141f8a1996-12-20 20:50:39 +0000426 nlen = x*y;
427 if ( (nlen+7)/8 != len ) {
428 PyErr_SetString(ImageopError, "String has incorrect length");
429 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000430 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000431
432 rv = PyString_FromStringAndSize(NULL, nlen);
433 if ( rv == 0 )
434 return 0;
435 ncp = (unsigned char *)PyString_AsString(rv);
436
437 bit = 0x80;
438 for ( i=0; i < nlen; i++ ) {
439 if ( *cp & bit )
440 *ncp++ = v1;
441 else
442 *ncp++ = v0;
443 bit >>= 1;
444 if ( bit == 0 ) {
445 bit = 0x80;
446 cp++;
447 }
448 }
449 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000450}
451
Roger E. Massea141f8a1996-12-20 20:50:39 +0000452static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000453imageop_grey22grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000454 PyObject *self;
455PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000456{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000457 int x, y, len, nlen;
458 unsigned char *cp, *ncp;
459 PyObject *rv;
460 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000461
Roger E. Massea141f8a1996-12-20 20:50:39 +0000462 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
463 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000464
Roger E. Massea141f8a1996-12-20 20:50:39 +0000465 nlen = x*y;
466 if ( (nlen+3)/4 != len ) {
467 PyErr_SetString(ImageopError, "String has incorrect length");
468 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000469 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000470
471 rv = PyString_FromStringAndSize(NULL, nlen);
472 if ( rv == 0 )
473 return 0;
474 ncp = (unsigned char *)PyString_AsString(rv);
475
476 pos = 0;
477 for ( i=0; i < nlen; i++ ) {
478 if ( pos == 0 ) {
479 value = *cp++;
480 pos = 8;
481 }
482 pos -= 2;
483 nvalue = (value >> pos) & 0x03;
484 *ncp++ = nvalue | (nvalue << 2) |
485 (nvalue << 4) | (nvalue << 6);
486 }
487 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000488}
489
Roger E. Massea141f8a1996-12-20 20:50:39 +0000490static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000491imageop_grey42grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000492 PyObject *self;
493PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000494{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000495 int x, y, len, nlen;
496 unsigned char *cp, *ncp;
497 PyObject *rv;
498 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000499
Roger E. Massea141f8a1996-12-20 20:50:39 +0000500 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
501 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000502
Roger E. Massea141f8a1996-12-20 20:50:39 +0000503 nlen = x*y;
504 if ( (nlen+1)/2 != len ) {
505 PyErr_SetString(ImageopError, "String has incorrect length");
506 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000507 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000508
509 rv = PyString_FromStringAndSize(NULL, nlen);
510 if ( rv == 0 )
511 return 0;
512 ncp = (unsigned char *)PyString_AsString(rv);
513
514 pos = 0;
515 for ( i=0; i < nlen; i++ ) {
516 if ( pos == 0 ) {
517 value = *cp++;
518 pos = 8;
519 }
520 pos -= 4;
521 nvalue = (value >> pos) & 0x0f;
522 *ncp++ = nvalue | (nvalue << 4);
523 }
524 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000525}
526
Roger E. Massea141f8a1996-12-20 20:50:39 +0000527static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000528imageop_rgb2rgb8(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000529 PyObject *self;
530PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000531{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000532 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000533 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000534 unsigned char *ncp;
535 PyObject *rv;
536 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000537 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000538
Roger E. Massea141f8a1996-12-20 20:50:39 +0000539 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
540 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000541
Roger E. Massea141f8a1996-12-20 20:50:39 +0000542 nlen = x*y;
543 if ( nlen*4 != len ) {
544 PyErr_SetString(ImageopError, "String has incorrect length");
545 return 0;
546 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000547
Roger E. Massea141f8a1996-12-20 20:50:39 +0000548 rv = PyString_FromStringAndSize(NULL, nlen);
549 if ( rv == 0 )
550 return 0;
551 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000552
Roger E. Massea141f8a1996-12-20 20:50:39 +0000553 for ( i=0; i < nlen; i++ ) {
554 /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
555 value = *cp++;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000556#if 0
Roger E. Massea141f8a1996-12-20 20:50:39 +0000557 r = (value >> 5) & 7;
558 g = (value >> 13) & 7;
559 b = (value >> 22) & 3;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000560#else
Roger E. Massea141f8a1996-12-20 20:50:39 +0000561 r = (int) ((value & 0xff) / 255. * 7. + .5);
562 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
563 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000564#endif
Roger E. Massea141f8a1996-12-20 20:50:39 +0000565 nvalue = (r<<5) | (b<<3) | g;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000566 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000567 }
568 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000569}
570
Roger E. Massea141f8a1996-12-20 20:50:39 +0000571static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000572imageop_rgb82rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000573 PyObject *self;
574PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000575{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000576 int x, y, len, nlen;
577 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000578 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000579 PyObject *rv;
580 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000581 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000582
Roger E. Massea141f8a1996-12-20 20:50:39 +0000583 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
584 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000585
Roger E. Massea141f8a1996-12-20 20:50:39 +0000586 nlen = x*y;
587 if ( nlen != len ) {
588 PyErr_SetString(ImageopError, "String has incorrect length");
589 return 0;
590 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000591
Roger E. Massea141f8a1996-12-20 20:50:39 +0000592 rv = PyString_FromStringAndSize(NULL, nlen*4);
593 if ( rv == 0 )
594 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000595 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000596
Roger E. Massea141f8a1996-12-20 20:50:39 +0000597 for ( i=0; i < nlen; i++ ) {
598 /* Bits in source: RRRBBGGG
599 ** Red and Green are multiplied by 36.5, Blue by 85
600 */
601 value = *cp++;
602 r = (value >> 5) & 7;
603 g = (value ) & 7;
604 b = (value >> 3) & 3;
605 r = (r<<5) | (r<<3) | (r>>1);
606 g = (g<<5) | (g<<3) | (g>>1);
607 b = (b<<6) | (b<<4) | (b<<2) | b;
608 nvalue = r | (g<<8) | (b<<16);
609 *ncp++ = nvalue;
610 }
611 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000612}
613
Roger E. Massea141f8a1996-12-20 20:50:39 +0000614static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000615imageop_rgb2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000616 PyObject *self;
617PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000618{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000619 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000620 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000621 unsigned char *ncp;
622 PyObject *rv;
623 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000624 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000625
Roger E. Massea141f8a1996-12-20 20:50:39 +0000626 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
627 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000628
Roger E. Massea141f8a1996-12-20 20:50:39 +0000629 nlen = x*y;
630 if ( nlen*4 != len ) {
631 PyErr_SetString(ImageopError, "String has incorrect length");
632 return 0;
633 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000634
Roger E. Massea141f8a1996-12-20 20:50:39 +0000635 rv = PyString_FromStringAndSize(NULL, nlen);
636 if ( rv == 0 )
637 return 0;
638 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000639
Roger E. Massea141f8a1996-12-20 20:50:39 +0000640 for ( i=0; i < nlen; i++ ) {
641 value = *cp++;
642 r = (value ) & 0xff;
643 g = (value >> 8) & 0xff;
644 b = (value >> 16) & 0xff;
645 nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
646 if ( nvalue > 255 ) nvalue = 255;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000647 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000648 }
649 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000650}
651
Roger E. Massea141f8a1996-12-20 20:50:39 +0000652static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000653imageop_grey2rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000654 PyObject *self;
655PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000656{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000657 int x, y, len, nlen;
658 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000659 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000660 PyObject *rv;
661 int i;
Guido van Rossum69011961998-04-23 20:23:00 +0000662 Py_UInt32 value;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000663
Roger E. Massea141f8a1996-12-20 20:50:39 +0000664 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
665 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000666
Roger E. Massea141f8a1996-12-20 20:50:39 +0000667 nlen = x*y;
668 if ( nlen != len ) {
669 PyErr_SetString(ImageopError, "String has incorrect length");
670 return 0;
671 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000672
Roger E. Massea141f8a1996-12-20 20:50:39 +0000673 rv = PyString_FromStringAndSize(NULL, nlen*4);
674 if ( rv == 0 )
675 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000676 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000677
Roger E. Massea141f8a1996-12-20 20:50:39 +0000678 for ( i=0; i < nlen; i++ ) {
679 value = *cp++;
680 *ncp++ = value | (value << 8 ) | (value << 16);
681 }
682 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000683}
684
Guido van Rossum0317a471992-10-26 13:40:15 +0000685/*
686static object *
687imageop_mul(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000688 object *self;
689object *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000690{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000691 char *cp, *ncp;
692 int len, size, x, y;
693 object *rv;
694 int i;
Guido van Rossum0317a471992-10-26 13:40:15 +0000695
Roger E. Massea141f8a1996-12-20 20:50:39 +0000696 if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
697 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000698
Roger E. Massea141f8a1996-12-20 20:50:39 +0000699 if ( size != 1 && size != 4 ) {
700 err_setstr(ImageopError, "Size should be 1 or 4");
701 return 0;
702 }
703 if ( len != size*x*y ) {
704 err_setstr(ImageopError, "String has incorrect length");
705 return 0;
706 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000707
Roger E. Massea141f8a1996-12-20 20:50:39 +0000708 rv = newsizedstringobject(NULL, XXXX);
709 if ( rv == 0 )
710 return 0;
711 ncp = (char *)getstringvalue(rv);
Guido van Rossum0317a471992-10-26 13:40:15 +0000712
713
Roger E. Massea141f8a1996-12-20 20:50:39 +0000714 for ( i=0; i < len; i += size ) {
715 }
716 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000717}
718*/
719
Roger E. Massea141f8a1996-12-20 20:50:39 +0000720static PyMethodDef imageop_methods[] = {
721 { "crop", imageop_crop },
722 { "scale", imageop_scale },
723 { "grey2mono", imageop_grey2mono },
724 { "grey2grey2", imageop_grey2grey2 },
725 { "grey2grey4", imageop_grey2grey4 },
726 { "dither2mono", imageop_dither2mono },
727 { "dither2grey2", imageop_dither2grey2 },
728 { "mono2grey", imageop_mono2grey },
729 { "grey22grey", imageop_grey22grey },
730 { "grey42grey", imageop_grey42grey },
731 { "tovideo", imageop_tovideo },
732 { "rgb2rgb8", imageop_rgb2rgb8 },
733 { "rgb82rgb", imageop_rgb82rgb },
734 { "rgb2grey", imageop_rgb2grey },
735 { "grey2rgb", imageop_grey2rgb },
736 { 0, 0 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000737};
738
739
Guido van Rossum3886bb61998-12-04 18:50:17 +0000740DL_EXPORT(void)
Guido van Rossum0317a471992-10-26 13:40:15 +0000741initimageop()
742{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000743 PyObject *m, *d;
744 m = Py_InitModule("imageop", imageop_methods);
745 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000746 ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
747 if (ImageopError != NULL)
748 PyDict_SetItemString(d, "error", ImageopError);
Guido van Rossum0317a471992-10-26 13:40:15 +0000749}