blob: 7c7116d6cbd678701b0d43586f0a71b324d1da1f [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 *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +000038imageop_crop(PyObject *self, PyObject *args)
Guido van Rossum0317a471992-10-26 13:40:15 +000039{
Roger E. Massea141f8a1996-12-20 20:50:39 +000040 char *cp, *ncp;
41 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +000042 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000043 int len, size, x, y, newx1, newx2, newy1, newy2;
44 int ix, iy, xstep, ystep;
45 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000046
Roger E. Massea141f8a1996-12-20 20:50:39 +000047 if ( !PyArg_Parse(args, "(s#iiiiiii)", &cp, &len, &size, &x, &y,
48 &newx1, &newy1, &newx2, &newy2) )
49 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000050
Roger E. Massea141f8a1996-12-20 20:50:39 +000051 if ( size != 1 && size != 2 && size != 4 ) {
52 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
53 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000054 }
Roger E. Massea141f8a1996-12-20 20:50:39 +000055 if ( len != size*x*y ) {
56 PyErr_SetString(ImageopError, "String has incorrect length");
57 return 0;
58 }
59 xstep = (newx1 < newx2)? 1 : -1;
60 ystep = (newy1 < newy2)? 1 : -1;
61
62 rv = PyString_FromStringAndSize(NULL,
63 (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
64 if ( rv == 0 )
65 return 0;
66 ncp = (char *)PyString_AsString(rv);
67 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +000068 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000069 newy2 += ystep;
70 newx2 += xstep;
71 for( iy = newy1; iy != newy2; iy+=ystep ) {
72 for ( ix = newx1; ix != newx2; ix+=xstep ) {
73 if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
74 if ( size == 1 )
75 *ncp++ = 0;
76 else
77 *nlp++ = 0;
78 } else {
79 if ( size == 1 )
80 *ncp++ = *CHARP(cp, x, ix, iy);
81 else if ( size == 2 )
82 *nsp++ = *SHORTP(cp, x, ix, iy);
83 else
84 *nlp++ = *LONGP(cp, x, ix, iy);
85 }
86 }
87 }
88 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000089}
90
Roger E. Massea141f8a1996-12-20 20:50:39 +000091static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +000092imageop_scale(PyObject *self, PyObject *args)
Guido van Rossum0317a471992-10-26 13:40:15 +000093{
Roger E. Massea141f8a1996-12-20 20:50:39 +000094 char *cp, *ncp;
95 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +000096 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000097 int len, size, x, y, newx, newy;
98 int ix, iy;
99 int oix, oiy;
100 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000101
Roger E. Massea141f8a1996-12-20 20:50:39 +0000102 if ( !PyArg_Parse(args, "(s#iiiii)",
103 &cp, &len, &size, &x, &y, &newx, &newy) )
104 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000105
Roger E. Massea141f8a1996-12-20 20:50:39 +0000106 if ( size != 1 && size != 2 && size != 4 ) {
107 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
108 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000109 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000110 if ( len != size*x*y ) {
111 PyErr_SetString(ImageopError, "String has incorrect length");
112 return 0;
113 }
114
115 rv = PyString_FromStringAndSize(NULL, newx*newy*size);
116 if ( rv == 0 )
117 return 0;
118 ncp = (char *)PyString_AsString(rv);
119 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +0000120 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000121 for( iy = 0; iy < newy; iy++ ) {
122 for ( ix = 0; ix < newx; ix++ ) {
123 oix = ix * x / newx;
124 oiy = iy * y / newy;
125 if ( size == 1 )
126 *ncp++ = *CHARP(cp, x, oix, oiy);
127 else if ( size == 2 )
128 *nsp++ = *SHORTP(cp, x, oix, oiy);
129 else
130 *nlp++ = *LONGP(cp, x, oix, oiy);
131 }
132 }
133 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000134}
135
Jack Jansend26b4581993-01-22 15:34:43 +0000136/* Note: this routine can use a bit of optimizing */
137
Roger E. Massea141f8a1996-12-20 20:50:39 +0000138static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000139imageop_tovideo(PyObject *self, PyObject *args)
Jack Jansend26b4581993-01-22 15:34:43 +0000140{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000141 int maxx, maxy, x, y, len;
142 int i;
143 unsigned char *cp, *ncp;
144 int width;
145 PyObject *rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000146
147
Roger E. Massea141f8a1996-12-20 20:50:39 +0000148 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &width, &maxx, &maxy) )
149 return 0;
Jack Jansend26b4581993-01-22 15:34:43 +0000150
Roger E. Massea141f8a1996-12-20 20:50:39 +0000151 if ( width != 1 && width != 4 ) {
152 PyErr_SetString(ImageopError, "Size should be 1 or 4");
153 return 0;
154 }
155 if ( maxx*maxy*width != len ) {
156 PyErr_SetString(ImageopError, "String has incorrect length");
157 return 0;
158 }
Jack Jansend26b4581993-01-22 15:34:43 +0000159
Roger E. Massea141f8a1996-12-20 20:50:39 +0000160 rv = PyString_FromStringAndSize(NULL, len);
161 if ( rv == 0 )
162 return 0;
163 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansend26b4581993-01-22 15:34:43 +0000164
Roger E. Massea141f8a1996-12-20 20:50:39 +0000165 if ( width == 1 ) {
166 memcpy(ncp, cp, maxx); /* Copy first line */
167 ncp += maxx;
168 for (y=1; y<maxy; y++) { /* Interpolate other lines */
169 for(x=0; x<maxx; x++) {
170 i = y*maxx + x;
171 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
172 }
173 }
174 } else {
175 memcpy(ncp, cp, maxx*4); /* Copy first line */
176 ncp += maxx*4;
177 for (y=1; y<maxy; y++) { /* Interpolate other lines */
178 for(x=0; x<maxx; x++) {
179 i = (y*maxx + x)*4 + 1;
180 *ncp++ = 0; /* Skip alfa comp */
181 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
182 i++;
183 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
184 i++;
185 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
186 }
187 }
Jack Jansend26b4581993-01-22 15:34:43 +0000188 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000189 return rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000190}
191
Roger E. Massea141f8a1996-12-20 20:50:39 +0000192static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000193imageop_grey2mono(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000194{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000195 int tres, x, y, len;
196 unsigned char *cp, *ncp;
197 unsigned char ovalue;
198 PyObject *rv;
199 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000200
201
Roger E. Massea141f8a1996-12-20 20:50:39 +0000202 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &x, &y, &tres) )
203 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000204
Roger E. Massea141f8a1996-12-20 20:50:39 +0000205 if ( x*y != len ) {
206 PyErr_SetString(ImageopError, "String has incorrect length");
207 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000208 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000209
210 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
211 if ( rv == 0 )
212 return 0;
213 ncp = (unsigned char *)PyString_AsString(rv);
214
215 bit = 0x80;
216 ovalue = 0;
217 for ( i=0; i < len; i++ ) {
218 if ( (int)cp[i] > tres )
219 ovalue |= bit;
220 bit >>= 1;
221 if ( bit == 0 ) {
222 *ncp++ = ovalue;
223 bit = 0x80;
224 ovalue = 0;
225 }
226 }
227 if ( bit != 0x80 )
228 *ncp++ = ovalue;
229 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000230}
231
Roger E. Massea141f8a1996-12-20 20:50:39 +0000232static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000233imageop_grey2grey4(PyObject *self, PyObject *args)
Jack Jansende3adf91992-12-22 14:05:55 +0000234{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000235 int x, y, len;
236 unsigned char *cp, *ncp;
237 unsigned char ovalue;
238 PyObject *rv;
239 int i;
240 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000241
242
Roger E. Massea141f8a1996-12-20 20:50:39 +0000243 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
244 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000245
Roger E. Massea141f8a1996-12-20 20:50:39 +0000246 if ( x*y != len ) {
247 PyErr_SetString(ImageopError, "String has incorrect length");
248 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000249 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000250
251 rv = PyString_FromStringAndSize(NULL, (len+1)/2);
252 if ( rv == 0 )
253 return 0;
254 ncp = (unsigned char *)PyString_AsString(rv);
255 pos = 0;
256 ovalue = 0;
257 for ( i=0; i < len; i++ ) {
258 ovalue |= ((int)cp[i] & 0xf0) >> pos;
259 pos += 4;
260 if ( pos == 8 ) {
261 *ncp++ = ovalue;
262 ovalue = 0;
263 pos = 0;
264 }
265 }
266 if ( pos != 0 )
267 *ncp++ = ovalue;
268 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000269}
270
Roger E. Massea141f8a1996-12-20 20:50:39 +0000271static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000272imageop_grey2grey2(PyObject *self, PyObject *args)
Jack Jansende3adf91992-12-22 14:05:55 +0000273{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000274 int x, y, len;
275 unsigned char *cp, *ncp;
276 unsigned char ovalue;
277 PyObject *rv;
278 int i;
279 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000280
281
Roger E. Massea141f8a1996-12-20 20:50:39 +0000282 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
283 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000284
Roger E. Massea141f8a1996-12-20 20:50:39 +0000285 if ( x*y != len ) {
286 PyErr_SetString(ImageopError, "String has incorrect length");
287 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000288 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000289
290 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
291 if ( rv == 0 )
292 return 0;
293 ncp = (unsigned char *)PyString_AsString(rv);
294 pos = 0;
295 ovalue = 0;
296 for ( i=0; i < len; i++ ) {
297 ovalue |= ((int)cp[i] & 0xc0) >> pos;
298 pos += 2;
299 if ( pos == 8 ) {
300 *ncp++ = ovalue;
301 ovalue = 0;
302 pos = 0;
303 }
304 }
305 if ( pos != 0 )
306 *ncp++ = ovalue;
307 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000308}
309
Roger E. Massea141f8a1996-12-20 20:50:39 +0000310static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000311imageop_dither2mono(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000312{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000313 int sum, x, y, len;
314 unsigned char *cp, *ncp;
315 unsigned char ovalue;
316 PyObject *rv;
317 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000318
319
Roger E. Massea141f8a1996-12-20 20:50:39 +0000320 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
321 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000322
Roger E. Massea141f8a1996-12-20 20:50:39 +0000323 if ( x*y != len ) {
324 PyErr_SetString(ImageopError, "String has incorrect length");
325 return 0;
326 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000327
Roger E. Massea141f8a1996-12-20 20:50:39 +0000328 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
329 if ( rv == 0 )
330 return 0;
331 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000332
Roger E. Massea141f8a1996-12-20 20:50:39 +0000333 bit = 0x80;
334 ovalue = 0;
335 sum = 0;
336 for ( i=0; i < len; i++ ) {
337 sum += cp[i];
338 if ( sum >= 256 ) {
339 sum -= 256;
340 ovalue |= bit;
341 }
342 bit >>= 1;
343 if ( bit == 0 ) {
344 *ncp++ = ovalue;
345 bit = 0x80;
346 ovalue = 0;
347 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000348 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000349 if ( bit != 0x80 )
350 *ncp++ = ovalue;
351 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000352}
353
Roger E. Massea141f8a1996-12-20 20:50:39 +0000354static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000355imageop_dither2grey2(PyObject *self, PyObject *args)
Jack Jansende3adf91992-12-22 14:05:55 +0000356{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000357 int x, y, len;
358 unsigned char *cp, *ncp;
359 unsigned char ovalue;
360 PyObject *rv;
361 int i;
362 int pos;
363 int sum = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000364
365
Roger E. Massea141f8a1996-12-20 20:50:39 +0000366 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
367 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000368
Roger E. Massea141f8a1996-12-20 20:50:39 +0000369 if ( x*y != len ) {
370 PyErr_SetString(ImageopError, "String has incorrect length");
371 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000372 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000373
374 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
375 if ( rv == 0 )
376 return 0;
377 ncp = (unsigned char *)PyString_AsString(rv);
378 pos = 1;
379 ovalue = 0;
380 for ( i=0; i < len; i++ ) {
381 sum += cp[i];
382 nvalue = sum & 0x180;
383 sum -= nvalue;
384 ovalue |= nvalue >> pos;
385 pos += 2;
386 if ( pos == 9 ) {
387 *ncp++ = ovalue;
388 ovalue = 0;
389 pos = 1;
390 }
391 }
392 if ( pos != 0 )
393 *ncp++ = ovalue;
394 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000395}
396
Roger E. Massea141f8a1996-12-20 20:50:39 +0000397static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000398imageop_mono2grey(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000399{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000400 int v0, v1, x, y, len, nlen;
401 unsigned char *cp, *ncp;
402 PyObject *rv;
403 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000404
Roger E. Massea141f8a1996-12-20 20:50:39 +0000405 if ( !PyArg_Parse(args, "(s#iiii)", &cp, &len, &x, &y, &v0, &v1) )
406 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000407
Roger E. Massea141f8a1996-12-20 20:50:39 +0000408 nlen = x*y;
409 if ( (nlen+7)/8 != len ) {
410 PyErr_SetString(ImageopError, "String has incorrect length");
411 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000412 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000413
414 rv = PyString_FromStringAndSize(NULL, nlen);
415 if ( rv == 0 )
416 return 0;
417 ncp = (unsigned char *)PyString_AsString(rv);
418
419 bit = 0x80;
420 for ( i=0; i < nlen; i++ ) {
421 if ( *cp & bit )
422 *ncp++ = v1;
423 else
424 *ncp++ = v0;
425 bit >>= 1;
426 if ( bit == 0 ) {
427 bit = 0x80;
428 cp++;
429 }
430 }
431 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000432}
433
Roger E. Massea141f8a1996-12-20 20:50:39 +0000434static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000435imageop_grey22grey(PyObject *self, PyObject *args)
Jack Jansende3adf91992-12-22 14:05:55 +0000436{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000437 int x, y, len, nlen;
438 unsigned char *cp, *ncp;
439 PyObject *rv;
440 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000441
Roger E. Massea141f8a1996-12-20 20:50:39 +0000442 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
443 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000444
Roger E. Massea141f8a1996-12-20 20:50:39 +0000445 nlen = x*y;
446 if ( (nlen+3)/4 != len ) {
447 PyErr_SetString(ImageopError, "String has incorrect length");
448 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000449 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000450
451 rv = PyString_FromStringAndSize(NULL, nlen);
452 if ( rv == 0 )
453 return 0;
454 ncp = (unsigned char *)PyString_AsString(rv);
455
456 pos = 0;
457 for ( i=0; i < nlen; i++ ) {
458 if ( pos == 0 ) {
459 value = *cp++;
460 pos = 8;
461 }
462 pos -= 2;
463 nvalue = (value >> pos) & 0x03;
464 *ncp++ = nvalue | (nvalue << 2) |
465 (nvalue << 4) | (nvalue << 6);
466 }
467 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000468}
469
Roger E. Massea141f8a1996-12-20 20:50:39 +0000470static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000471imageop_grey42grey(PyObject *self, PyObject *args)
Jack Jansende3adf91992-12-22 14:05:55 +0000472{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000473 int x, y, len, nlen;
474 unsigned char *cp, *ncp;
475 PyObject *rv;
476 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000477
Roger E. Massea141f8a1996-12-20 20:50:39 +0000478 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
479 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000480
Roger E. Massea141f8a1996-12-20 20:50:39 +0000481 nlen = x*y;
482 if ( (nlen+1)/2 != len ) {
483 PyErr_SetString(ImageopError, "String has incorrect length");
484 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000485 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000486
487 rv = PyString_FromStringAndSize(NULL, nlen);
488 if ( rv == 0 )
489 return 0;
490 ncp = (unsigned char *)PyString_AsString(rv);
491
492 pos = 0;
493 for ( i=0; i < nlen; i++ ) {
494 if ( pos == 0 ) {
495 value = *cp++;
496 pos = 8;
497 }
498 pos -= 4;
499 nvalue = (value >> pos) & 0x0f;
500 *ncp++ = nvalue | (nvalue << 4);
501 }
502 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000503}
504
Roger E. Massea141f8a1996-12-20 20:50:39 +0000505static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000506imageop_rgb2rgb8(PyObject *self, PyObject *args)
Jack Jansen4fada9c1993-02-19 15:51:41 +0000507{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000508 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000509 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000510 unsigned char *ncp;
511 PyObject *rv;
512 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000513 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000514
Roger E. Massea141f8a1996-12-20 20:50:39 +0000515 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
516 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000517
Roger E. Massea141f8a1996-12-20 20:50:39 +0000518 nlen = x*y;
519 if ( nlen*4 != len ) {
520 PyErr_SetString(ImageopError, "String has incorrect length");
521 return 0;
522 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000523
Roger E. Massea141f8a1996-12-20 20:50:39 +0000524 rv = PyString_FromStringAndSize(NULL, nlen);
525 if ( rv == 0 )
526 return 0;
527 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000528
Roger E. Massea141f8a1996-12-20 20:50:39 +0000529 for ( i=0; i < nlen; i++ ) {
530 /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
531 value = *cp++;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000532#if 0
Roger E. Massea141f8a1996-12-20 20:50:39 +0000533 r = (value >> 5) & 7;
534 g = (value >> 13) & 7;
535 b = (value >> 22) & 3;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000536#else
Roger E. Massea141f8a1996-12-20 20:50:39 +0000537 r = (int) ((value & 0xff) / 255. * 7. + .5);
538 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
539 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000540#endif
Roger E. Massea141f8a1996-12-20 20:50:39 +0000541 nvalue = (r<<5) | (b<<3) | g;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000542 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000543 }
544 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000545}
546
Roger E. Massea141f8a1996-12-20 20:50:39 +0000547static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000548imageop_rgb82rgb(PyObject *self, PyObject *args)
Jack Jansen4fada9c1993-02-19 15:51:41 +0000549{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000550 int x, y, len, nlen;
551 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000552 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000553 PyObject *rv;
554 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000555 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000556
Roger E. Massea141f8a1996-12-20 20:50:39 +0000557 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
558 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000559
Roger E. Massea141f8a1996-12-20 20:50:39 +0000560 nlen = x*y;
561 if ( nlen != len ) {
562 PyErr_SetString(ImageopError, "String has incorrect length");
563 return 0;
564 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000565
Roger E. Massea141f8a1996-12-20 20:50:39 +0000566 rv = PyString_FromStringAndSize(NULL, nlen*4);
567 if ( rv == 0 )
568 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000569 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000570
Roger E. Massea141f8a1996-12-20 20:50:39 +0000571 for ( i=0; i < nlen; i++ ) {
572 /* Bits in source: RRRBBGGG
573 ** Red and Green are multiplied by 36.5, Blue by 85
574 */
575 value = *cp++;
576 r = (value >> 5) & 7;
577 g = (value ) & 7;
578 b = (value >> 3) & 3;
579 r = (r<<5) | (r<<3) | (r>>1);
580 g = (g<<5) | (g<<3) | (g>>1);
581 b = (b<<6) | (b<<4) | (b<<2) | b;
582 nvalue = r | (g<<8) | (b<<16);
583 *ncp++ = nvalue;
584 }
585 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000586}
587
Roger E. Massea141f8a1996-12-20 20:50:39 +0000588static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000589imageop_rgb2grey(PyObject *self, PyObject *args)
Jack Jansen4fada9c1993-02-19 15:51:41 +0000590{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000591 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000592 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000593 unsigned char *ncp;
594 PyObject *rv;
595 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000596 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000597
Roger E. Massea141f8a1996-12-20 20:50:39 +0000598 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
599 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000600
Roger E. Massea141f8a1996-12-20 20:50:39 +0000601 nlen = x*y;
602 if ( nlen*4 != len ) {
603 PyErr_SetString(ImageopError, "String has incorrect length");
604 return 0;
605 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000606
Roger E. Massea141f8a1996-12-20 20:50:39 +0000607 rv = PyString_FromStringAndSize(NULL, nlen);
608 if ( rv == 0 )
609 return 0;
610 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000611
Roger E. Massea141f8a1996-12-20 20:50:39 +0000612 for ( i=0; i < nlen; i++ ) {
613 value = *cp++;
614 r = (value ) & 0xff;
615 g = (value >> 8) & 0xff;
616 b = (value >> 16) & 0xff;
617 nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
618 if ( nvalue > 255 ) nvalue = 255;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000619 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000620 }
621 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000622}
623
Roger E. Massea141f8a1996-12-20 20:50:39 +0000624static PyObject *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000625imageop_grey2rgb(PyObject *self, PyObject *args)
Jack Jansen4fada9c1993-02-19 15:51:41 +0000626{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000627 int x, y, len, nlen;
628 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000629 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000630 PyObject *rv;
631 int i;
Guido van Rossum69011961998-04-23 20:23:00 +0000632 Py_UInt32 value;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000633
Roger E. Massea141f8a1996-12-20 20:50:39 +0000634 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
635 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000636
Roger E. Massea141f8a1996-12-20 20:50:39 +0000637 nlen = x*y;
638 if ( nlen != len ) {
639 PyErr_SetString(ImageopError, "String has incorrect length");
640 return 0;
641 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000642
Roger E. Massea141f8a1996-12-20 20:50:39 +0000643 rv = PyString_FromStringAndSize(NULL, nlen*4);
644 if ( rv == 0 )
645 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000646 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000647
Roger E. Massea141f8a1996-12-20 20:50:39 +0000648 for ( i=0; i < nlen; i++ ) {
649 value = *cp++;
650 *ncp++ = value | (value << 8 ) | (value << 16);
651 }
652 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000653}
654
Guido van Rossum0317a471992-10-26 13:40:15 +0000655/*
656static object *
Peter Schneider-Kampfe742632000-07-10 09:55:32 +0000657imageop_mul(object *self, object *args)
Guido van Rossum0317a471992-10-26 13:40:15 +0000658{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000659 char *cp, *ncp;
660 int len, size, x, y;
661 object *rv;
662 int i;
Guido van Rossum0317a471992-10-26 13:40:15 +0000663
Roger E. Massea141f8a1996-12-20 20:50:39 +0000664 if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
665 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000666
Roger E. Massea141f8a1996-12-20 20:50:39 +0000667 if ( size != 1 && size != 4 ) {
668 err_setstr(ImageopError, "Size should be 1 or 4");
669 return 0;
670 }
671 if ( len != size*x*y ) {
672 err_setstr(ImageopError, "String has incorrect length");
673 return 0;
674 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000675
Roger E. Massea141f8a1996-12-20 20:50:39 +0000676 rv = newsizedstringobject(NULL, XXXX);
677 if ( rv == 0 )
678 return 0;
679 ncp = (char *)getstringvalue(rv);
Guido van Rossum0317a471992-10-26 13:40:15 +0000680
681
Roger E. Massea141f8a1996-12-20 20:50:39 +0000682 for ( i=0; i < len; i += size ) {
683 }
684 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000685}
686*/
687
Roger E. Massea141f8a1996-12-20 20:50:39 +0000688static PyMethodDef imageop_methods[] = {
689 { "crop", imageop_crop },
690 { "scale", imageop_scale },
691 { "grey2mono", imageop_grey2mono },
692 { "grey2grey2", imageop_grey2grey2 },
693 { "grey2grey4", imageop_grey2grey4 },
694 { "dither2mono", imageop_dither2mono },
695 { "dither2grey2", imageop_dither2grey2 },
696 { "mono2grey", imageop_mono2grey },
697 { "grey22grey", imageop_grey22grey },
698 { "grey42grey", imageop_grey42grey },
699 { "tovideo", imageop_tovideo },
700 { "rgb2rgb8", imageop_rgb2rgb8 },
701 { "rgb82rgb", imageop_rgb82rgb },
702 { "rgb2grey", imageop_rgb2grey },
703 { "grey2rgb", imageop_grey2rgb },
704 { 0, 0 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000705};
706
707
Guido van Rossum3886bb61998-12-04 18:50:17 +0000708DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000709initimageop(void)
Guido van Rossum0317a471992-10-26 13:40:15 +0000710{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000711 PyObject *m, *d;
712 m = Py_InitModule("imageop", imageop_methods);
713 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000714 ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
715 if (ImageopError != NULL)
716 PyDict_SetItemString(d, "error", ImageopError);
Guido van Rossum0317a471992-10-26 13:40:15 +0000717}