blob: 825e4fa05903334ae5498ed5d3e74d5f6f13ef79 [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 Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossum0317a471992-10-26 13:40:15 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum0317a471992-10-26 13:40:15 +000014
15******************************************************************/
16
17/* imageopmodule - Various operations on pictures */
18
19#ifdef sun
20#define signed
21#endif
22
Roger E. Massea141f8a1996-12-20 20:50:39 +000023#include "Python.h"
Guido van Rossum0317a471992-10-26 13:40:15 +000024
Guido van Rossum69011961998-04-23 20:23:00 +000025#if SIZEOF_INT == 4
26typedef int Py_Int32;
27typedef unsigned int Py_UInt32;
28#else
29#if SIZEOF_LONG == 4
30typedef long Py_Int32;
31typedef unsigned long Py_UInt32;
32#else
33#error "No 4-byte integral type"
34#endif
35#endif
36
Guido van Rossum0317a471992-10-26 13:40:15 +000037#define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
Jack Jansen76c79e91996-01-22 14:55:15 +000038#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
Guido van Rossum69011961998-04-23 20:23:00 +000039#define LONGP(cp, xmax, x, y) ((Py_Int32 *)(cp+4*(y*xmax+x)))
Guido van Rossum0317a471992-10-26 13:40:15 +000040
Roger E. Massea141f8a1996-12-20 20:50:39 +000041static PyObject *ImageopError;
Guido van Rossum0317a471992-10-26 13:40:15 +000042
Roger E. Massea141f8a1996-12-20 20:50:39 +000043static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +000044imageop_crop(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +000045 PyObject *self;
46PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +000047{
Roger E. Massea141f8a1996-12-20 20:50:39 +000048 char *cp, *ncp;
49 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +000050 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000051 int len, size, x, y, newx1, newx2, newy1, newy2;
52 int ix, iy, xstep, ystep;
53 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000054
Roger E. Massea141f8a1996-12-20 20:50:39 +000055 if ( !PyArg_Parse(args, "(s#iiiiiii)", &cp, &len, &size, &x, &y,
56 &newx1, &newy1, &newx2, &newy2) )
57 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000058
Roger E. Massea141f8a1996-12-20 20:50:39 +000059 if ( size != 1 && size != 2 && size != 4 ) {
60 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
61 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000062 }
Roger E. Massea141f8a1996-12-20 20:50:39 +000063 if ( len != size*x*y ) {
64 PyErr_SetString(ImageopError, "String has incorrect length");
65 return 0;
66 }
67 xstep = (newx1 < newx2)? 1 : -1;
68 ystep = (newy1 < newy2)? 1 : -1;
69
70 rv = PyString_FromStringAndSize(NULL,
71 (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
72 if ( rv == 0 )
73 return 0;
74 ncp = (char *)PyString_AsString(rv);
75 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +000076 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +000077 newy2 += ystep;
78 newx2 += xstep;
79 for( iy = newy1; iy != newy2; iy+=ystep ) {
80 for ( ix = newx1; ix != newx2; ix+=xstep ) {
81 if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
82 if ( size == 1 )
83 *ncp++ = 0;
84 else
85 *nlp++ = 0;
86 } else {
87 if ( size == 1 )
88 *ncp++ = *CHARP(cp, x, ix, iy);
89 else if ( size == 2 )
90 *nsp++ = *SHORTP(cp, x, ix, iy);
91 else
92 *nlp++ = *LONGP(cp, x, ix, iy);
93 }
94 }
95 }
96 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000097}
98
Roger E. Massea141f8a1996-12-20 20:50:39 +000099static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +0000100imageop_scale(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000101 PyObject *self;
102PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000103{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000104 char *cp, *ncp;
105 short *nsp;
Guido van Rossum69011961998-04-23 20:23:00 +0000106 Py_Int32 *nlp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000107 int len, size, x, y, newx, newy;
108 int ix, iy;
109 int oix, oiy;
110 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000111
Roger E. Massea141f8a1996-12-20 20:50:39 +0000112 if ( !PyArg_Parse(args, "(s#iiiii)",
113 &cp, &len, &size, &x, &y, &newx, &newy) )
114 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000115
Roger E. Massea141f8a1996-12-20 20:50:39 +0000116 if ( size != 1 && size != 2 && size != 4 ) {
117 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
118 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000119 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000120 if ( len != size*x*y ) {
121 PyErr_SetString(ImageopError, "String has incorrect length");
122 return 0;
123 }
124
125 rv = PyString_FromStringAndSize(NULL, newx*newy*size);
126 if ( rv == 0 )
127 return 0;
128 ncp = (char *)PyString_AsString(rv);
129 nsp = (short *)ncp;
Guido van Rossum69011961998-04-23 20:23:00 +0000130 nlp = (Py_Int32 *)ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000131 for( iy = 0; iy < newy; iy++ ) {
132 for ( ix = 0; ix < newx; ix++ ) {
133 oix = ix * x / newx;
134 oiy = iy * y / newy;
135 if ( size == 1 )
136 *ncp++ = *CHARP(cp, x, oix, oiy);
137 else if ( size == 2 )
138 *nsp++ = *SHORTP(cp, x, oix, oiy);
139 else
140 *nlp++ = *LONGP(cp, x, oix, oiy);
141 }
142 }
143 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000144}
145
Jack Jansend26b4581993-01-22 15:34:43 +0000146/* Note: this routine can use a bit of optimizing */
147
Roger E. Massea141f8a1996-12-20 20:50:39 +0000148static PyObject *
Jack Jansend26b4581993-01-22 15:34:43 +0000149imageop_tovideo(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000150 PyObject *self;
151PyObject *args;
Jack Jansend26b4581993-01-22 15:34:43 +0000152{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000153 int maxx, maxy, x, y, len;
154 int i;
155 unsigned char *cp, *ncp;
156 int width;
157 PyObject *rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000158
159
Roger E. Massea141f8a1996-12-20 20:50:39 +0000160 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &width, &maxx, &maxy) )
161 return 0;
Jack Jansend26b4581993-01-22 15:34:43 +0000162
Roger E. Massea141f8a1996-12-20 20:50:39 +0000163 if ( width != 1 && width != 4 ) {
164 PyErr_SetString(ImageopError, "Size should be 1 or 4");
165 return 0;
166 }
167 if ( maxx*maxy*width != len ) {
168 PyErr_SetString(ImageopError, "String has incorrect length");
169 return 0;
170 }
Jack Jansend26b4581993-01-22 15:34:43 +0000171
Roger E. Massea141f8a1996-12-20 20:50:39 +0000172 rv = PyString_FromStringAndSize(NULL, len);
173 if ( rv == 0 )
174 return 0;
175 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansend26b4581993-01-22 15:34:43 +0000176
Roger E. Massea141f8a1996-12-20 20:50:39 +0000177 if ( width == 1 ) {
178 memcpy(ncp, cp, maxx); /* Copy first line */
179 ncp += maxx;
180 for (y=1; y<maxy; y++) { /* Interpolate other lines */
181 for(x=0; x<maxx; x++) {
182 i = y*maxx + x;
183 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
184 }
185 }
186 } else {
187 memcpy(ncp, cp, maxx*4); /* Copy first line */
188 ncp += maxx*4;
189 for (y=1; y<maxy; y++) { /* Interpolate other lines */
190 for(x=0; x<maxx; x++) {
191 i = (y*maxx + x)*4 + 1;
192 *ncp++ = 0; /* Skip alfa comp */
193 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
194 i++;
195 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
196 i++;
197 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
198 }
199 }
Jack Jansend26b4581993-01-22 15:34:43 +0000200 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000201 return rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000202}
203
Roger E. Massea141f8a1996-12-20 20:50:39 +0000204static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000205imageop_grey2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000206 PyObject *self;
207PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000208{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000209 int tres, x, y, len;
210 unsigned char *cp, *ncp;
211 unsigned char ovalue;
212 PyObject *rv;
213 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000214
215
Roger E. Massea141f8a1996-12-20 20:50:39 +0000216 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &x, &y, &tres) )
217 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000218
Roger E. Massea141f8a1996-12-20 20:50:39 +0000219 if ( x*y != len ) {
220 PyErr_SetString(ImageopError, "String has incorrect length");
221 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000222 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000223
224 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
225 if ( rv == 0 )
226 return 0;
227 ncp = (unsigned char *)PyString_AsString(rv);
228
229 bit = 0x80;
230 ovalue = 0;
231 for ( i=0; i < len; i++ ) {
232 if ( (int)cp[i] > tres )
233 ovalue |= bit;
234 bit >>= 1;
235 if ( bit == 0 ) {
236 *ncp++ = ovalue;
237 bit = 0x80;
238 ovalue = 0;
239 }
240 }
241 if ( bit != 0x80 )
242 *ncp++ = ovalue;
243 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000244}
245
Roger E. Massea141f8a1996-12-20 20:50:39 +0000246static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000247imageop_grey2grey4(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000248 PyObject *self;
249PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000250{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000251 int x, y, len;
252 unsigned char *cp, *ncp;
253 unsigned char ovalue;
254 PyObject *rv;
255 int i;
256 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000257
258
Roger E. Massea141f8a1996-12-20 20:50:39 +0000259 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
260 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000261
Roger E. Massea141f8a1996-12-20 20:50:39 +0000262 if ( x*y != len ) {
263 PyErr_SetString(ImageopError, "String has incorrect length");
264 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000265 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000266
267 rv = PyString_FromStringAndSize(NULL, (len+1)/2);
268 if ( rv == 0 )
269 return 0;
270 ncp = (unsigned char *)PyString_AsString(rv);
271 pos = 0;
272 ovalue = 0;
273 for ( i=0; i < len; i++ ) {
274 ovalue |= ((int)cp[i] & 0xf0) >> pos;
275 pos += 4;
276 if ( pos == 8 ) {
277 *ncp++ = ovalue;
278 ovalue = 0;
279 pos = 0;
280 }
281 }
282 if ( pos != 0 )
283 *ncp++ = ovalue;
284 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000285}
286
Roger E. Massea141f8a1996-12-20 20:50:39 +0000287static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000288imageop_grey2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000289 PyObject *self;
290PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000291{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000292 int x, y, len;
293 unsigned char *cp, *ncp;
294 unsigned char ovalue;
295 PyObject *rv;
296 int i;
297 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000298
299
Roger E. Massea141f8a1996-12-20 20:50:39 +0000300 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
301 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000302
Roger E. Massea141f8a1996-12-20 20:50:39 +0000303 if ( x*y != len ) {
304 PyErr_SetString(ImageopError, "String has incorrect length");
305 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000306 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000307
308 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
309 if ( rv == 0 )
310 return 0;
311 ncp = (unsigned char *)PyString_AsString(rv);
312 pos = 0;
313 ovalue = 0;
314 for ( i=0; i < len; i++ ) {
315 ovalue |= ((int)cp[i] & 0xc0) >> pos;
316 pos += 2;
317 if ( pos == 8 ) {
318 *ncp++ = ovalue;
319 ovalue = 0;
320 pos = 0;
321 }
322 }
323 if ( pos != 0 )
324 *ncp++ = ovalue;
325 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000326}
327
Roger E. Massea141f8a1996-12-20 20:50:39 +0000328static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000329imageop_dither2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000330 PyObject *self;
331PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000332{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000333 int sum, x, y, len;
334 unsigned char *cp, *ncp;
335 unsigned char ovalue;
336 PyObject *rv;
337 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000338
339
Roger E. Massea141f8a1996-12-20 20:50:39 +0000340 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
341 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000342
Roger E. Massea141f8a1996-12-20 20:50:39 +0000343 if ( x*y != len ) {
344 PyErr_SetString(ImageopError, "String has incorrect length");
345 return 0;
346 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000347
Roger E. Massea141f8a1996-12-20 20:50:39 +0000348 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
349 if ( rv == 0 )
350 return 0;
351 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000352
Roger E. Massea141f8a1996-12-20 20:50:39 +0000353 bit = 0x80;
354 ovalue = 0;
355 sum = 0;
356 for ( i=0; i < len; i++ ) {
357 sum += cp[i];
358 if ( sum >= 256 ) {
359 sum -= 256;
360 ovalue |= bit;
361 }
362 bit >>= 1;
363 if ( bit == 0 ) {
364 *ncp++ = ovalue;
365 bit = 0x80;
366 ovalue = 0;
367 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000368 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000369 if ( bit != 0x80 )
370 *ncp++ = ovalue;
371 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000372}
373
Roger E. Massea141f8a1996-12-20 20:50:39 +0000374static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000375imageop_dither2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000376 PyObject *self;
377PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000378{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000379 int x, y, len;
380 unsigned char *cp, *ncp;
381 unsigned char ovalue;
382 PyObject *rv;
383 int i;
384 int pos;
385 int sum = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000386
387
Roger E. Massea141f8a1996-12-20 20:50:39 +0000388 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
389 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000390
Roger E. Massea141f8a1996-12-20 20:50:39 +0000391 if ( x*y != len ) {
392 PyErr_SetString(ImageopError, "String has incorrect length");
393 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000394 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000395
396 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
397 if ( rv == 0 )
398 return 0;
399 ncp = (unsigned char *)PyString_AsString(rv);
400 pos = 1;
401 ovalue = 0;
402 for ( i=0; i < len; i++ ) {
403 sum += cp[i];
404 nvalue = sum & 0x180;
405 sum -= nvalue;
406 ovalue |= nvalue >> pos;
407 pos += 2;
408 if ( pos == 9 ) {
409 *ncp++ = ovalue;
410 ovalue = 0;
411 pos = 1;
412 }
413 }
414 if ( pos != 0 )
415 *ncp++ = ovalue;
416 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000417}
418
Roger E. Massea141f8a1996-12-20 20:50:39 +0000419static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000420imageop_mono2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000421 PyObject *self;
422PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000423{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000424 int v0, v1, x, y, len, nlen;
425 unsigned char *cp, *ncp;
426 PyObject *rv;
427 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000428
Roger E. Massea141f8a1996-12-20 20:50:39 +0000429 if ( !PyArg_Parse(args, "(s#iiii)", &cp, &len, &x, &y, &v0, &v1) )
430 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000431
Roger E. Massea141f8a1996-12-20 20:50:39 +0000432 nlen = x*y;
433 if ( (nlen+7)/8 != len ) {
434 PyErr_SetString(ImageopError, "String has incorrect length");
435 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000436 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000437
438 rv = PyString_FromStringAndSize(NULL, nlen);
439 if ( rv == 0 )
440 return 0;
441 ncp = (unsigned char *)PyString_AsString(rv);
442
443 bit = 0x80;
444 for ( i=0; i < nlen; i++ ) {
445 if ( *cp & bit )
446 *ncp++ = v1;
447 else
448 *ncp++ = v0;
449 bit >>= 1;
450 if ( bit == 0 ) {
451 bit = 0x80;
452 cp++;
453 }
454 }
455 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000456}
457
Roger E. Massea141f8a1996-12-20 20:50:39 +0000458static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000459imageop_grey22grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000460 PyObject *self;
461PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000462{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000463 int x, y, len, nlen;
464 unsigned char *cp, *ncp;
465 PyObject *rv;
466 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000467
Roger E. Massea141f8a1996-12-20 20:50:39 +0000468 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
469 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000470
Roger E. Massea141f8a1996-12-20 20:50:39 +0000471 nlen = x*y;
472 if ( (nlen+3)/4 != len ) {
473 PyErr_SetString(ImageopError, "String has incorrect length");
474 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000475 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000476
477 rv = PyString_FromStringAndSize(NULL, nlen);
478 if ( rv == 0 )
479 return 0;
480 ncp = (unsigned char *)PyString_AsString(rv);
481
482 pos = 0;
483 for ( i=0; i < nlen; i++ ) {
484 if ( pos == 0 ) {
485 value = *cp++;
486 pos = 8;
487 }
488 pos -= 2;
489 nvalue = (value >> pos) & 0x03;
490 *ncp++ = nvalue | (nvalue << 2) |
491 (nvalue << 4) | (nvalue << 6);
492 }
493 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000494}
495
Roger E. Massea141f8a1996-12-20 20:50:39 +0000496static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000497imageop_grey42grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000498 PyObject *self;
499PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000500{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000501 int x, y, len, nlen;
502 unsigned char *cp, *ncp;
503 PyObject *rv;
504 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000505
Roger E. Massea141f8a1996-12-20 20:50:39 +0000506 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
507 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000508
Roger E. Massea141f8a1996-12-20 20:50:39 +0000509 nlen = x*y;
510 if ( (nlen+1)/2 != len ) {
511 PyErr_SetString(ImageopError, "String has incorrect length");
512 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000513 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000514
515 rv = PyString_FromStringAndSize(NULL, nlen);
516 if ( rv == 0 )
517 return 0;
518 ncp = (unsigned char *)PyString_AsString(rv);
519
520 pos = 0;
521 for ( i=0; i < nlen; i++ ) {
522 if ( pos == 0 ) {
523 value = *cp++;
524 pos = 8;
525 }
526 pos -= 4;
527 nvalue = (value >> pos) & 0x0f;
528 *ncp++ = nvalue | (nvalue << 4);
529 }
530 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000531}
532
Roger E. Massea141f8a1996-12-20 20:50:39 +0000533static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000534imageop_rgb2rgb8(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000535 PyObject *self;
536PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000537{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000538 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000539 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000540 unsigned char *ncp;
541 PyObject *rv;
542 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000543 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000544
Roger E. Massea141f8a1996-12-20 20:50:39 +0000545 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
546 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000547
Roger E. Massea141f8a1996-12-20 20:50:39 +0000548 nlen = x*y;
549 if ( nlen*4 != len ) {
550 PyErr_SetString(ImageopError, "String has incorrect length");
551 return 0;
552 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000553
Roger E. Massea141f8a1996-12-20 20:50:39 +0000554 rv = PyString_FromStringAndSize(NULL, nlen);
555 if ( rv == 0 )
556 return 0;
557 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000558
Roger E. Massea141f8a1996-12-20 20:50:39 +0000559 for ( i=0; i < nlen; i++ ) {
560 /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
561 value = *cp++;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000562#if 0
Roger E. Massea141f8a1996-12-20 20:50:39 +0000563 r = (value >> 5) & 7;
564 g = (value >> 13) & 7;
565 b = (value >> 22) & 3;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000566#else
Roger E. Massea141f8a1996-12-20 20:50:39 +0000567 r = (int) ((value & 0xff) / 255. * 7. + .5);
568 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
569 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000570#endif
Roger E. Massea141f8a1996-12-20 20:50:39 +0000571 nvalue = (r<<5) | (b<<3) | g;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000572 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000573 }
574 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000575}
576
Roger E. Massea141f8a1996-12-20 20:50:39 +0000577static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000578imageop_rgb82rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000579 PyObject *self;
580PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000581{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000582 int x, y, len, nlen;
583 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000584 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000585 PyObject *rv;
586 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000587 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000588
Roger E. Massea141f8a1996-12-20 20:50:39 +0000589 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
590 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000591
Roger E. Massea141f8a1996-12-20 20:50:39 +0000592 nlen = x*y;
593 if ( nlen != len ) {
594 PyErr_SetString(ImageopError, "String has incorrect length");
595 return 0;
596 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000597
Roger E. Massea141f8a1996-12-20 20:50:39 +0000598 rv = PyString_FromStringAndSize(NULL, nlen*4);
599 if ( rv == 0 )
600 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000601 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000602
Roger E. Massea141f8a1996-12-20 20:50:39 +0000603 for ( i=0; i < nlen; i++ ) {
604 /* Bits in source: RRRBBGGG
605 ** Red and Green are multiplied by 36.5, Blue by 85
606 */
607 value = *cp++;
608 r = (value >> 5) & 7;
609 g = (value ) & 7;
610 b = (value >> 3) & 3;
611 r = (r<<5) | (r<<3) | (r>>1);
612 g = (g<<5) | (g<<3) | (g>>1);
613 b = (b<<6) | (b<<4) | (b<<2) | b;
614 nvalue = r | (g<<8) | (b<<16);
615 *ncp++ = nvalue;
616 }
617 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000618}
619
Roger E. Massea141f8a1996-12-20 20:50:39 +0000620static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000621imageop_rgb2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000622 PyObject *self;
623PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000624{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000625 int x, y, len, nlen;
Guido van Rossum69011961998-04-23 20:23:00 +0000626 Py_UInt32 *cp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000627 unsigned char *ncp;
628 PyObject *rv;
629 int i, r, g, b;
Guido van Rossum69011961998-04-23 20:23:00 +0000630 Py_UInt32 value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000631
Roger E. Massea141f8a1996-12-20 20:50:39 +0000632 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
633 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000634
Roger E. Massea141f8a1996-12-20 20:50:39 +0000635 nlen = x*y;
636 if ( nlen*4 != len ) {
637 PyErr_SetString(ImageopError, "String has incorrect length");
638 return 0;
639 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000640
Roger E. Massea141f8a1996-12-20 20:50:39 +0000641 rv = PyString_FromStringAndSize(NULL, nlen);
642 if ( rv == 0 )
643 return 0;
644 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000645
Roger E. Massea141f8a1996-12-20 20:50:39 +0000646 for ( i=0; i < nlen; i++ ) {
647 value = *cp++;
648 r = (value ) & 0xff;
649 g = (value >> 8) & 0xff;
650 b = (value >> 16) & 0xff;
651 nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
652 if ( nvalue > 255 ) nvalue = 255;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000653 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000654 }
655 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000656}
657
Roger E. Massea141f8a1996-12-20 20:50:39 +0000658static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000659imageop_grey2rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000660 PyObject *self;
661PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000662{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000663 int x, y, len, nlen;
664 unsigned char *cp;
Guido van Rossum69011961998-04-23 20:23:00 +0000665 Py_UInt32 *ncp;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000666 PyObject *rv;
667 int i;
Guido van Rossum69011961998-04-23 20:23:00 +0000668 Py_UInt32 value;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000669
Roger E. Massea141f8a1996-12-20 20:50:39 +0000670 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
671 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000672
Roger E. Massea141f8a1996-12-20 20:50:39 +0000673 nlen = x*y;
674 if ( nlen != len ) {
675 PyErr_SetString(ImageopError, "String has incorrect length");
676 return 0;
677 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000678
Roger E. Massea141f8a1996-12-20 20:50:39 +0000679 rv = PyString_FromStringAndSize(NULL, nlen*4);
680 if ( rv == 0 )
681 return 0;
Guido van Rossum69011961998-04-23 20:23:00 +0000682 ncp = (Py_UInt32 *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000683
Roger E. Massea141f8a1996-12-20 20:50:39 +0000684 for ( i=0; i < nlen; i++ ) {
685 value = *cp++;
686 *ncp++ = value | (value << 8 ) | (value << 16);
687 }
688 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000689}
690
Guido van Rossum0317a471992-10-26 13:40:15 +0000691/*
692static object *
693imageop_mul(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000694 object *self;
695object *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000696{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000697 char *cp, *ncp;
698 int len, size, x, y;
699 object *rv;
700 int i;
Guido van Rossum0317a471992-10-26 13:40:15 +0000701
Roger E. Massea141f8a1996-12-20 20:50:39 +0000702 if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
703 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000704
Roger E. Massea141f8a1996-12-20 20:50:39 +0000705 if ( size != 1 && size != 4 ) {
706 err_setstr(ImageopError, "Size should be 1 or 4");
707 return 0;
708 }
709 if ( len != size*x*y ) {
710 err_setstr(ImageopError, "String has incorrect length");
711 return 0;
712 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000713
Roger E. Massea141f8a1996-12-20 20:50:39 +0000714 rv = newsizedstringobject(NULL, XXXX);
715 if ( rv == 0 )
716 return 0;
717 ncp = (char *)getstringvalue(rv);
Guido van Rossum0317a471992-10-26 13:40:15 +0000718
719
Roger E. Massea141f8a1996-12-20 20:50:39 +0000720 for ( i=0; i < len; i += size ) {
721 }
722 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000723}
724*/
725
Roger E. Massea141f8a1996-12-20 20:50:39 +0000726static PyMethodDef imageop_methods[] = {
727 { "crop", imageop_crop },
728 { "scale", imageop_scale },
729 { "grey2mono", imageop_grey2mono },
730 { "grey2grey2", imageop_grey2grey2 },
731 { "grey2grey4", imageop_grey2grey4 },
732 { "dither2mono", imageop_dither2mono },
733 { "dither2grey2", imageop_dither2grey2 },
734 { "mono2grey", imageop_mono2grey },
735 { "grey22grey", imageop_grey22grey },
736 { "grey42grey", imageop_grey42grey },
737 { "tovideo", imageop_tovideo },
738 { "rgb2rgb8", imageop_rgb2rgb8 },
739 { "rgb82rgb", imageop_rgb82rgb },
740 { "rgb2grey", imageop_rgb2grey },
741 { "grey2rgb", imageop_grey2rgb },
742 { 0, 0 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000743};
744
745
Guido van Rossum3886bb61998-12-04 18:50:17 +0000746DL_EXPORT(void)
Guido van Rossum0317a471992-10-26 13:40:15 +0000747initimageop()
748{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000749 PyObject *m, *d;
750 m = Py_InitModule("imageop", imageop_methods);
751 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000752 ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
753 if (ImageopError != NULL)
754 PyDict_SetItemString(d, "error", ImageopError);
Guido van Rossum0317a471992-10-26 13:40:15 +0000755}