blob: 049908da354d752597c01670a0a890a725e97304 [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
40#define CHARP(cp, xmax, x, y) ((char *)(cp+y*xmax+x))
Jack Jansen76c79e91996-01-22 14:55:15 +000041#define SHORTP(cp, xmax, x, y) ((short *)(cp+2*(y*xmax+x)))
Guido van Rossum0317a471992-10-26 13:40:15 +000042#define LONGP(cp, xmax, x, y) ((long *)(cp+4*(y*xmax+x)))
43
Roger E. Massea141f8a1996-12-20 20:50:39 +000044static PyObject *ImageopError;
Guido van Rossum0317a471992-10-26 13:40:15 +000045
Roger E. Massea141f8a1996-12-20 20:50:39 +000046static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +000047imageop_crop(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +000048 PyObject *self;
49PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +000050{
Roger E. Massea141f8a1996-12-20 20:50:39 +000051 char *cp, *ncp;
52 short *nsp;
53 long *nlp;
54 int len, size, x, y, newx1, newx2, newy1, newy2;
55 int ix, iy, xstep, ystep;
56 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +000057
Roger E. Massea141f8a1996-12-20 20:50:39 +000058 if ( !PyArg_Parse(args, "(s#iiiiiii)", &cp, &len, &size, &x, &y,
59 &newx1, &newy1, &newx2, &newy2) )
60 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000061
Roger E. Massea141f8a1996-12-20 20:50:39 +000062 if ( size != 1 && size != 2 && size != 4 ) {
63 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
64 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +000065 }
Roger E. Massea141f8a1996-12-20 20:50:39 +000066 if ( len != size*x*y ) {
67 PyErr_SetString(ImageopError, "String has incorrect length");
68 return 0;
69 }
70 xstep = (newx1 < newx2)? 1 : -1;
71 ystep = (newy1 < newy2)? 1 : -1;
72
73 rv = PyString_FromStringAndSize(NULL,
74 (abs(newx2-newx1)+1)*(abs(newy2-newy1)+1)*size);
75 if ( rv == 0 )
76 return 0;
77 ncp = (char *)PyString_AsString(rv);
78 nsp = (short *)ncp;
79 nlp = (long *)ncp;
80 newy2 += ystep;
81 newx2 += xstep;
82 for( iy = newy1; iy != newy2; iy+=ystep ) {
83 for ( ix = newx1; ix != newx2; ix+=xstep ) {
84 if ( iy < 0 || iy >= y || ix < 0 || ix >= x ) {
85 if ( size == 1 )
86 *ncp++ = 0;
87 else
88 *nlp++ = 0;
89 } else {
90 if ( size == 1 )
91 *ncp++ = *CHARP(cp, x, ix, iy);
92 else if ( size == 2 )
93 *nsp++ = *SHORTP(cp, x, ix, iy);
94 else
95 *nlp++ = *LONGP(cp, x, ix, iy);
96 }
97 }
98 }
99 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000100}
101
Roger E. Massea141f8a1996-12-20 20:50:39 +0000102static PyObject *
Guido van Rossum0317a471992-10-26 13:40:15 +0000103imageop_scale(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000104 PyObject *self;
105PyObject *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000106{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000107 char *cp, *ncp;
108 short *nsp;
109 long *nlp;
110 int len, size, x, y, newx, newy;
111 int ix, iy;
112 int oix, oiy;
113 PyObject *rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000114
Roger E. Massea141f8a1996-12-20 20:50:39 +0000115 if ( !PyArg_Parse(args, "(s#iiiii)",
116 &cp, &len, &size, &x, &y, &newx, &newy) )
117 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000118
Roger E. Massea141f8a1996-12-20 20:50:39 +0000119 if ( size != 1 && size != 2 && size != 4 ) {
120 PyErr_SetString(ImageopError, "Size should be 1, 2 or 4");
121 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000122 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000123 if ( len != size*x*y ) {
124 PyErr_SetString(ImageopError, "String has incorrect length");
125 return 0;
126 }
127
128 rv = PyString_FromStringAndSize(NULL, newx*newy*size);
129 if ( rv == 0 )
130 return 0;
131 ncp = (char *)PyString_AsString(rv);
132 nsp = (short *)ncp;
133 nlp = (long *)ncp;
134 for( iy = 0; iy < newy; iy++ ) {
135 for ( ix = 0; ix < newx; ix++ ) {
136 oix = ix * x / newx;
137 oiy = iy * y / newy;
138 if ( size == 1 )
139 *ncp++ = *CHARP(cp, x, oix, oiy);
140 else if ( size == 2 )
141 *nsp++ = *SHORTP(cp, x, oix, oiy);
142 else
143 *nlp++ = *LONGP(cp, x, oix, oiy);
144 }
145 }
146 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000147}
148
Jack Jansend26b4581993-01-22 15:34:43 +0000149/* Note: this routine can use a bit of optimizing */
150
Roger E. Massea141f8a1996-12-20 20:50:39 +0000151static PyObject *
Jack Jansend26b4581993-01-22 15:34:43 +0000152imageop_tovideo(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000153 PyObject *self;
154PyObject *args;
Jack Jansend26b4581993-01-22 15:34:43 +0000155{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000156 int maxx, maxy, x, y, len;
157 int i;
158 unsigned char *cp, *ncp;
159 int width;
160 PyObject *rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000161
162
Roger E. Massea141f8a1996-12-20 20:50:39 +0000163 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &width, &maxx, &maxy) )
164 return 0;
Jack Jansend26b4581993-01-22 15:34:43 +0000165
Roger E. Massea141f8a1996-12-20 20:50:39 +0000166 if ( width != 1 && width != 4 ) {
167 PyErr_SetString(ImageopError, "Size should be 1 or 4");
168 return 0;
169 }
170 if ( maxx*maxy*width != len ) {
171 PyErr_SetString(ImageopError, "String has incorrect length");
172 return 0;
173 }
Jack Jansend26b4581993-01-22 15:34:43 +0000174
Roger E. Massea141f8a1996-12-20 20:50:39 +0000175 rv = PyString_FromStringAndSize(NULL, len);
176 if ( rv == 0 )
177 return 0;
178 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansend26b4581993-01-22 15:34:43 +0000179
Roger E. Massea141f8a1996-12-20 20:50:39 +0000180 if ( width == 1 ) {
181 memcpy(ncp, cp, maxx); /* Copy first line */
182 ncp += maxx;
183 for (y=1; y<maxy; y++) { /* Interpolate other lines */
184 for(x=0; x<maxx; x++) {
185 i = y*maxx + x;
186 *ncp++ = ((int)cp[i] + (int)cp[i-maxx]) >> 1;
187 }
188 }
189 } else {
190 memcpy(ncp, cp, maxx*4); /* Copy first line */
191 ncp += maxx*4;
192 for (y=1; y<maxy; y++) { /* Interpolate other lines */
193 for(x=0; x<maxx; x++) {
194 i = (y*maxx + x)*4 + 1;
195 *ncp++ = 0; /* Skip alfa comp */
196 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
197 i++;
198 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
199 i++;
200 *ncp++ = ((int)cp[i] + (int)cp[i-4*maxx]) >> 1;
201 }
202 }
Jack Jansend26b4581993-01-22 15:34:43 +0000203 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000204 return rv;
Jack Jansend26b4581993-01-22 15:34:43 +0000205}
206
Roger E. Massea141f8a1996-12-20 20:50:39 +0000207static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000208imageop_grey2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000209 PyObject *self;
210PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000211{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000212 int tres, x, y, len;
213 unsigned char *cp, *ncp;
214 unsigned char ovalue;
215 PyObject *rv;
216 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000217
218
Roger E. Massea141f8a1996-12-20 20:50:39 +0000219 if ( !PyArg_Parse(args, "(s#iii)", &cp, &len, &x, &y, &tres) )
220 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000221
Roger E. Massea141f8a1996-12-20 20:50:39 +0000222 if ( x*y != len ) {
223 PyErr_SetString(ImageopError, "String has incorrect length");
224 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000225 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000226
227 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
228 if ( rv == 0 )
229 return 0;
230 ncp = (unsigned char *)PyString_AsString(rv);
231
232 bit = 0x80;
233 ovalue = 0;
234 for ( i=0; i < len; i++ ) {
235 if ( (int)cp[i] > tres )
236 ovalue |= bit;
237 bit >>= 1;
238 if ( bit == 0 ) {
239 *ncp++ = ovalue;
240 bit = 0x80;
241 ovalue = 0;
242 }
243 }
244 if ( bit != 0x80 )
245 *ncp++ = ovalue;
246 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000247}
248
Roger E. Massea141f8a1996-12-20 20:50:39 +0000249static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000250imageop_grey2grey4(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000251 PyObject *self;
252PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000253{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000254 int x, y, len;
255 unsigned char *cp, *ncp;
256 unsigned char ovalue;
257 PyObject *rv;
258 int i;
259 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000260
261
Roger E. Massea141f8a1996-12-20 20:50:39 +0000262 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
263 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000264
Roger E. Massea141f8a1996-12-20 20:50:39 +0000265 if ( x*y != len ) {
266 PyErr_SetString(ImageopError, "String has incorrect length");
267 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000268 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000269
270 rv = PyString_FromStringAndSize(NULL, (len+1)/2);
271 if ( rv == 0 )
272 return 0;
273 ncp = (unsigned char *)PyString_AsString(rv);
274 pos = 0;
275 ovalue = 0;
276 for ( i=0; i < len; i++ ) {
277 ovalue |= ((int)cp[i] & 0xf0) >> pos;
278 pos += 4;
279 if ( pos == 8 ) {
280 *ncp++ = ovalue;
281 ovalue = 0;
282 pos = 0;
283 }
284 }
285 if ( pos != 0 )
286 *ncp++ = ovalue;
287 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000288}
289
Roger E. Massea141f8a1996-12-20 20:50:39 +0000290static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000291imageop_grey2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000292 PyObject *self;
293PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000294{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000295 int x, y, len;
296 unsigned char *cp, *ncp;
297 unsigned char ovalue;
298 PyObject *rv;
299 int i;
300 int pos;
Jack Jansende3adf91992-12-22 14:05:55 +0000301
302
Roger E. Massea141f8a1996-12-20 20:50:39 +0000303 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
304 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000305
Roger E. Massea141f8a1996-12-20 20:50:39 +0000306 if ( x*y != len ) {
307 PyErr_SetString(ImageopError, "String has incorrect length");
308 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000309 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000310
311 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
312 if ( rv == 0 )
313 return 0;
314 ncp = (unsigned char *)PyString_AsString(rv);
315 pos = 0;
316 ovalue = 0;
317 for ( i=0; i < len; i++ ) {
318 ovalue |= ((int)cp[i] & 0xc0) >> pos;
319 pos += 2;
320 if ( pos == 8 ) {
321 *ncp++ = ovalue;
322 ovalue = 0;
323 pos = 0;
324 }
325 }
326 if ( pos != 0 )
327 *ncp++ = ovalue;
328 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000329}
330
Roger E. Massea141f8a1996-12-20 20:50:39 +0000331static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000332imageop_dither2mono(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000333 PyObject *self;
334PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000335{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000336 int sum, x, y, len;
337 unsigned char *cp, *ncp;
338 unsigned char ovalue;
339 PyObject *rv;
340 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000341
342
Roger E. Massea141f8a1996-12-20 20:50:39 +0000343 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
344 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000345
Roger E. Massea141f8a1996-12-20 20:50:39 +0000346 if ( x*y != len ) {
347 PyErr_SetString(ImageopError, "String has incorrect length");
348 return 0;
349 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000350
Roger E. Massea141f8a1996-12-20 20:50:39 +0000351 rv = PyString_FromStringAndSize(NULL, (len+7)/8);
352 if ( rv == 0 )
353 return 0;
354 ncp = (unsigned char *)PyString_AsString(rv);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000355
Roger E. Massea141f8a1996-12-20 20:50:39 +0000356 bit = 0x80;
357 ovalue = 0;
358 sum = 0;
359 for ( i=0; i < len; i++ ) {
360 sum += cp[i];
361 if ( sum >= 256 ) {
362 sum -= 256;
363 ovalue |= bit;
364 }
365 bit >>= 1;
366 if ( bit == 0 ) {
367 *ncp++ = ovalue;
368 bit = 0x80;
369 ovalue = 0;
370 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000371 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000372 if ( bit != 0x80 )
373 *ncp++ = ovalue;
374 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000375}
376
Roger E. Massea141f8a1996-12-20 20:50:39 +0000377static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000378imageop_dither2grey2(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000379 PyObject *self;
380PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000381{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000382 int x, y, len;
383 unsigned char *cp, *ncp;
384 unsigned char ovalue;
385 PyObject *rv;
386 int i;
387 int pos;
388 int sum = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000389
390
Roger E. Massea141f8a1996-12-20 20:50:39 +0000391 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
392 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000393
Roger E. Massea141f8a1996-12-20 20:50:39 +0000394 if ( x*y != len ) {
395 PyErr_SetString(ImageopError, "String has incorrect length");
396 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000397 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000398
399 rv = PyString_FromStringAndSize(NULL, (len+3)/4);
400 if ( rv == 0 )
401 return 0;
402 ncp = (unsigned char *)PyString_AsString(rv);
403 pos = 1;
404 ovalue = 0;
405 for ( i=0; i < len; i++ ) {
406 sum += cp[i];
407 nvalue = sum & 0x180;
408 sum -= nvalue;
409 ovalue |= nvalue >> pos;
410 pos += 2;
411 if ( pos == 9 ) {
412 *ncp++ = ovalue;
413 ovalue = 0;
414 pos = 1;
415 }
416 }
417 if ( pos != 0 )
418 *ncp++ = ovalue;
419 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000420}
421
Roger E. Massea141f8a1996-12-20 20:50:39 +0000422static PyObject *
Guido van Rossum5f59d601992-12-14 16:59:51 +0000423imageop_mono2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000424 PyObject *self;
425PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000426{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000427 int v0, v1, x, y, len, nlen;
428 unsigned char *cp, *ncp;
429 PyObject *rv;
430 int i, bit;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000431
Roger E. Massea141f8a1996-12-20 20:50:39 +0000432 if ( !PyArg_Parse(args, "(s#iiii)", &cp, &len, &x, &y, &v0, &v1) )
433 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000434
Roger E. Massea141f8a1996-12-20 20:50:39 +0000435 nlen = x*y;
436 if ( (nlen+7)/8 != len ) {
437 PyErr_SetString(ImageopError, "String has incorrect length");
438 return 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000439 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000440
441 rv = PyString_FromStringAndSize(NULL, nlen);
442 if ( rv == 0 )
443 return 0;
444 ncp = (unsigned char *)PyString_AsString(rv);
445
446 bit = 0x80;
447 for ( i=0; i < nlen; i++ ) {
448 if ( *cp & bit )
449 *ncp++ = v1;
450 else
451 *ncp++ = v0;
452 bit >>= 1;
453 if ( bit == 0 ) {
454 bit = 0x80;
455 cp++;
456 }
457 }
458 return rv;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000459}
460
Roger E. Massea141f8a1996-12-20 20:50:39 +0000461static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000462imageop_grey22grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000463 PyObject *self;
464PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000465{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000466 int x, y, len, nlen;
467 unsigned char *cp, *ncp;
468 PyObject *rv;
469 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000470
Roger E. Massea141f8a1996-12-20 20:50:39 +0000471 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
472 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000473
Roger E. Massea141f8a1996-12-20 20:50:39 +0000474 nlen = x*y;
475 if ( (nlen+3)/4 != len ) {
476 PyErr_SetString(ImageopError, "String has incorrect length");
477 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000478 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000479
480 rv = PyString_FromStringAndSize(NULL, nlen);
481 if ( rv == 0 )
482 return 0;
483 ncp = (unsigned char *)PyString_AsString(rv);
484
485 pos = 0;
486 for ( i=0; i < nlen; i++ ) {
487 if ( pos == 0 ) {
488 value = *cp++;
489 pos = 8;
490 }
491 pos -= 2;
492 nvalue = (value >> pos) & 0x03;
493 *ncp++ = nvalue | (nvalue << 2) |
494 (nvalue << 4) | (nvalue << 6);
495 }
496 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000497}
498
Roger E. Massea141f8a1996-12-20 20:50:39 +0000499static PyObject *
Jack Jansende3adf91992-12-22 14:05:55 +0000500imageop_grey42grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000501 PyObject *self;
502PyObject *args;
Jack Jansende3adf91992-12-22 14:05:55 +0000503{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000504 int x, y, len, nlen;
505 unsigned char *cp, *ncp;
506 PyObject *rv;
507 int i, pos, value = 0, nvalue;
Jack Jansende3adf91992-12-22 14:05:55 +0000508
Roger E. Massea141f8a1996-12-20 20:50:39 +0000509 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
510 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000511
Roger E. Massea141f8a1996-12-20 20:50:39 +0000512 nlen = x*y;
513 if ( (nlen+1)/2 != len ) {
514 PyErr_SetString(ImageopError, "String has incorrect length");
515 return 0;
Jack Jansende3adf91992-12-22 14:05:55 +0000516 }
Roger E. Massea141f8a1996-12-20 20:50:39 +0000517
518 rv = PyString_FromStringAndSize(NULL, nlen);
519 if ( rv == 0 )
520 return 0;
521 ncp = (unsigned char *)PyString_AsString(rv);
522
523 pos = 0;
524 for ( i=0; i < nlen; i++ ) {
525 if ( pos == 0 ) {
526 value = *cp++;
527 pos = 8;
528 }
529 pos -= 4;
530 nvalue = (value >> pos) & 0x0f;
531 *ncp++ = nvalue | (nvalue << 4);
532 }
533 return rv;
Jack Jansende3adf91992-12-22 14:05:55 +0000534}
535
Roger E. Massea141f8a1996-12-20 20:50:39 +0000536static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000537imageop_rgb2rgb8(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000538 PyObject *self;
539PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000540{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000541 int x, y, len, nlen;
542 unsigned long *cp;
543 unsigned char *ncp;
544 PyObject *rv;
545 int i, r, g, b;
546 unsigned long value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000547
Roger E. Massea141f8a1996-12-20 20:50:39 +0000548 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
549 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000550
Roger E. Massea141f8a1996-12-20 20:50:39 +0000551 nlen = x*y;
552 if ( nlen*4 != len ) {
553 PyErr_SetString(ImageopError, "String has incorrect length");
554 return 0;
555 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000556
Roger E. Massea141f8a1996-12-20 20:50:39 +0000557 rv = PyString_FromStringAndSize(NULL, nlen);
558 if ( rv == 0 )
559 return 0;
560 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000561
Roger E. Massea141f8a1996-12-20 20:50:39 +0000562 for ( i=0; i < nlen; i++ ) {
563 /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
564 value = *cp++;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000565#if 0
Roger E. Massea141f8a1996-12-20 20:50:39 +0000566 r = (value >> 5) & 7;
567 g = (value >> 13) & 7;
568 b = (value >> 22) & 3;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000569#else
Roger E. Massea141f8a1996-12-20 20:50:39 +0000570 r = (int) ((value & 0xff) / 255. * 7. + .5);
571 g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
572 b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000573#endif
Roger E. Massea141f8a1996-12-20 20:50:39 +0000574 nvalue = (r<<5) | (b<<3) | g;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000575 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000576 }
577 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000578}
579
Roger E. Massea141f8a1996-12-20 20:50:39 +0000580static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000581imageop_rgb82rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000582 PyObject *self;
583PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000584{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000585 int x, y, len, nlen;
586 unsigned char *cp;
587 unsigned long *ncp;
588 PyObject *rv;
589 int i, r, g, b;
590 unsigned long value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000591
Roger E. Massea141f8a1996-12-20 20:50:39 +0000592 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
593 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000594
Roger E. Massea141f8a1996-12-20 20:50:39 +0000595 nlen = x*y;
596 if ( nlen != len ) {
597 PyErr_SetString(ImageopError, "String has incorrect length");
598 return 0;
599 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000600
Roger E. Massea141f8a1996-12-20 20:50:39 +0000601 rv = PyString_FromStringAndSize(NULL, nlen*4);
602 if ( rv == 0 )
603 return 0;
604 ncp = (unsigned long *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000605
Roger E. Massea141f8a1996-12-20 20:50:39 +0000606 for ( i=0; i < nlen; i++ ) {
607 /* Bits in source: RRRBBGGG
608 ** Red and Green are multiplied by 36.5, Blue by 85
609 */
610 value = *cp++;
611 r = (value >> 5) & 7;
612 g = (value ) & 7;
613 b = (value >> 3) & 3;
614 r = (r<<5) | (r<<3) | (r>>1);
615 g = (g<<5) | (g<<3) | (g>>1);
616 b = (b<<6) | (b<<4) | (b<<2) | b;
617 nvalue = r | (g<<8) | (b<<16);
618 *ncp++ = nvalue;
619 }
620 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000621}
622
Roger E. Massea141f8a1996-12-20 20:50:39 +0000623static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000624imageop_rgb2grey(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000625 PyObject *self;
626PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000627{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000628 int x, y, len, nlen;
629 unsigned long *cp;
630 unsigned char *ncp;
631 PyObject *rv;
632 int i, r, g, b;
633 unsigned long value, nvalue;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000634
Roger E. Massea141f8a1996-12-20 20:50:39 +0000635 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
636 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000637
Roger E. Massea141f8a1996-12-20 20:50:39 +0000638 nlen = x*y;
639 if ( nlen*4 != len ) {
640 PyErr_SetString(ImageopError, "String has incorrect length");
641 return 0;
642 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000643
Roger E. Massea141f8a1996-12-20 20:50:39 +0000644 rv = PyString_FromStringAndSize(NULL, nlen);
645 if ( rv == 0 )
646 return 0;
647 ncp = (unsigned char *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000648
Roger E. Massea141f8a1996-12-20 20:50:39 +0000649 for ( i=0; i < nlen; i++ ) {
650 value = *cp++;
651 r = (value ) & 0xff;
652 g = (value >> 8) & 0xff;
653 b = (value >> 16) & 0xff;
654 nvalue = (int)(0.30*r + 0.59*g + 0.11*b);
655 if ( nvalue > 255 ) nvalue = 255;
Guido van Rossum644a12b1997-04-09 19:24:53 +0000656 *ncp++ = (unsigned char)nvalue;
Roger E. Massea141f8a1996-12-20 20:50:39 +0000657 }
658 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000659}
660
Roger E. Massea141f8a1996-12-20 20:50:39 +0000661static PyObject *
Jack Jansen4fada9c1993-02-19 15:51:41 +0000662imageop_grey2rgb(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000663 PyObject *self;
664PyObject *args;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000665{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000666 int x, y, len, nlen;
667 unsigned char *cp;
668 unsigned long *ncp;
669 PyObject *rv;
670 int i;
671 unsigned long value;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000672
Roger E. Massea141f8a1996-12-20 20:50:39 +0000673 if ( !PyArg_Parse(args, "(s#ii)", &cp, &len, &x, &y) )
674 return 0;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000675
Roger E. Massea141f8a1996-12-20 20:50:39 +0000676 nlen = x*y;
677 if ( nlen != len ) {
678 PyErr_SetString(ImageopError, "String has incorrect length");
679 return 0;
680 }
Jack Jansen4fada9c1993-02-19 15:51:41 +0000681
Roger E. Massea141f8a1996-12-20 20:50:39 +0000682 rv = PyString_FromStringAndSize(NULL, nlen*4);
683 if ( rv == 0 )
684 return 0;
685 ncp = (unsigned long *)PyString_AsString(rv);
Jack Jansen4fada9c1993-02-19 15:51:41 +0000686
Roger E. Massea141f8a1996-12-20 20:50:39 +0000687 for ( i=0; i < nlen; i++ ) {
688 value = *cp++;
689 *ncp++ = value | (value << 8 ) | (value << 16);
690 }
691 return rv;
Jack Jansen4fada9c1993-02-19 15:51:41 +0000692}
693
Guido van Rossum0317a471992-10-26 13:40:15 +0000694/*
695static object *
696imageop_mul(self, args)
Roger E. Massea141f8a1996-12-20 20:50:39 +0000697 object *self;
698object *args;
Guido van Rossum0317a471992-10-26 13:40:15 +0000699{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000700 char *cp, *ncp;
701 int len, size, x, y;
702 object *rv;
703 int i;
Guido van Rossum0317a471992-10-26 13:40:15 +0000704
Roger E. Massea141f8a1996-12-20 20:50:39 +0000705 if ( !getargs(args, "(s#iii)", &cp, &len, &size, &x, &y) )
706 return 0;
Guido van Rossum0317a471992-10-26 13:40:15 +0000707
Roger E. Massea141f8a1996-12-20 20:50:39 +0000708 if ( size != 1 && size != 4 ) {
709 err_setstr(ImageopError, "Size should be 1 or 4");
710 return 0;
711 }
712 if ( len != size*x*y ) {
713 err_setstr(ImageopError, "String has incorrect length");
714 return 0;
715 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000716
Roger E. Massea141f8a1996-12-20 20:50:39 +0000717 rv = newsizedstringobject(NULL, XXXX);
718 if ( rv == 0 )
719 return 0;
720 ncp = (char *)getstringvalue(rv);
Guido van Rossum0317a471992-10-26 13:40:15 +0000721
722
Roger E. Massea141f8a1996-12-20 20:50:39 +0000723 for ( i=0; i < len; i += size ) {
724 }
725 return rv;
Guido van Rossum0317a471992-10-26 13:40:15 +0000726}
727*/
728
Roger E. Massea141f8a1996-12-20 20:50:39 +0000729static PyMethodDef imageop_methods[] = {
730 { "crop", imageop_crop },
731 { "scale", imageop_scale },
732 { "grey2mono", imageop_grey2mono },
733 { "grey2grey2", imageop_grey2grey2 },
734 { "grey2grey4", imageop_grey2grey4 },
735 { "dither2mono", imageop_dither2mono },
736 { "dither2grey2", imageop_dither2grey2 },
737 { "mono2grey", imageop_mono2grey },
738 { "grey22grey", imageop_grey22grey },
739 { "grey42grey", imageop_grey42grey },
740 { "tovideo", imageop_tovideo },
741 { "rgb2rgb8", imageop_rgb2rgb8 },
742 { "rgb82rgb", imageop_rgb82rgb },
743 { "rgb2grey", imageop_rgb2grey },
744 { "grey2rgb", imageop_grey2rgb },
745 { 0, 0 }
Guido van Rossum0317a471992-10-26 13:40:15 +0000746};
747
748
749void
750initimageop()
751{
Roger E. Massea141f8a1996-12-20 20:50:39 +0000752 PyObject *m, *d;
753 m = Py_InitModule("imageop", imageop_methods);
754 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000755 ImageopError = PyErr_NewException("imageop.error", NULL, NULL);
756 if (ImageopError != NULL)
757 PyDict_SetItemString(d, "error", ImageopError);
Guido van Rossum0317a471992-10-26 13:40:15 +0000758}