blob: 86ee71c8fb6370f4ab1ce12e4f3a439d0c2a37dc [file] [log] [blame]
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +00001/*
2 * fastimg -
3 * Faster reading and writing of image files.
4 *
5 * This code should work on machines with any byte order.
6 *
7 * Could someone make this run real fast using multiple processors
8 * or how about using memory mapped files to speed it up?
9 *
10 * Paul Haeberli - 1991
11 *
12 * Changed to return sizes.
13 * Sjoerd Mullender - 1993
14 * Changed to incorporate into Python.
15 * Sjoerd Mullender - 1993
16 */
17#include "allobjects.h"
18#include "modsupport.h"
19#include <unistd.h>
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +000020#include <string.h>
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +000021
22/*
23 * from image.h
24 *
25 */
26typedef struct {
27 unsigned short imagic; /* stuff saved on disk . . */
28 unsigned short type;
29 unsigned short dim;
30 unsigned short xsize;
31 unsigned short ysize;
32 unsigned short zsize;
33 unsigned long min;
34 unsigned long max;
35 unsigned long wastebytes;
36 char name[80];
37 unsigned long colormap;
38
39 long file; /* stuff used in core only */
40 unsigned short flags;
41 short dorev;
42 short x;
43 short y;
44 short z;
45 short cnt;
46 unsigned short *ptr;
47 unsigned short *base;
48 unsigned short *tmpbuf;
49 unsigned long offset;
50 unsigned long rleend; /* for rle images */
51 unsigned long *rowstart; /* for rle images */
52 long *rowsize; /* for rle images */
53} IMAGE;
54
55#define IMAGIC 0732
56
57#define TYPEMASK 0xff00
58#define BPPMASK 0x00ff
59#define ITYPE_VERBATIM 0x0000
60#define ITYPE_RLE 0x0100
61#define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE)
62#define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM)
63#define BPP(type) ((type) & BPPMASK)
64#define RLE(bpp) (ITYPE_RLE | (bpp))
65#define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp))
66/*
67 * end of image.h stuff
68 *
69 */
70
71#define RINTLUM (79)
72#define GINTLUM (156)
73#define BINTLUM (21)
74
75#define ILUM(r,g,b) ((int)(RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b))>>8)
76
77#define OFFSET_R 3 /* this is byte order dependent */
78#define OFFSET_G 2
79#define OFFSET_B 1
80#define OFFSET_A 0
81
82#define CHANOFFSET(z) (3-(z)) /* this is byte order dependent */
83
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +000084static expandrow PROTO((unsigned char *, unsigned char *, int));
85static setalpha PROTO((unsigned char *, int));
86static copybw PROTO((long *, int));
87static interleaverow PROTO((unsigned char *, unsigned char *, int, int));
88static int compressrow PROTO((unsigned char *, unsigned char *, int, int));
89static lumrow PROTO((unsigned char *, unsigned char *, int));
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +000090
91#ifdef ADD_TAGS
92#define TAGLEN (5)
93#else
94#define TAGLEN (0)
95#endif
96
97static object *ImgfileError;
98
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +000099static int reverse_order;
100
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000101#ifdef ADD_TAGS
102/*
103 * addlongimgtag -
104 * this is used to extract image data from core dumps.
105 *
106 */
107addlongimgtag(dptr,xsize,ysize)
108unsigned long *dptr;
109int xsize, ysize;
110{
111 dptr = dptr+(xsize*ysize);
112 dptr[0] = 0x12345678;
113 dptr[1] = 0x59493333;
114 dptr[2] = 0x69434222;
115 dptr[3] = xsize;
116 dptr[4] = ysize;
117}
118#endif
119
120/*
121 * byte order independent read/write of shorts and longs.
122 *
123 */
124static unsigned short getshort(inf)
125FILE *inf;
126{
127 unsigned char buf[2];
128
129 fread(buf,2,1,inf);
130 return (buf[0]<<8)+(buf[1]<<0);
131}
132
133static unsigned long getlong(inf)
134FILE *inf;
135{
136 unsigned char buf[4];
137
138 fread(buf,4,1,inf);
139 return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);
140}
141
142static putshort(outf,val)
143FILE *outf;
144unsigned short val;
145{
146 unsigned char buf[2];
147
148 buf[0] = (val>>8);
149 buf[1] = (val>>0);
150 fwrite(buf,2,1,outf);
151}
152
153static int putlong(outf,val)
154FILE *outf;
155unsigned long val;
156{
157 unsigned char buf[4];
158
159 buf[0] = (val>>24);
160 buf[1] = (val>>16);
161 buf[2] = (val>>8);
162 buf[3] = (val>>0);
163 return fwrite(buf,4,1,outf);
164}
165
166static readheader(inf,image)
167FILE *inf;
168IMAGE *image;
169{
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000170 memset(image,0,sizeof(IMAGE));
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000171 image->imagic = getshort(inf);
172 image->type = getshort(inf);
173 image->dim = getshort(inf);
174 image->xsize = getshort(inf);
175 image->ysize = getshort(inf);
176 image->zsize = getshort(inf);
177}
178
179static int writeheader(outf,image)
180FILE *outf;
181IMAGE *image;
182{
183 IMAGE t;
184
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000185 memset(&t,0,sizeof(IMAGE));
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000186 fwrite(&t,sizeof(IMAGE),1,outf);
187 fseek(outf,0,SEEK_SET);
188 putshort(outf,image->imagic);
189 putshort(outf,image->type);
190 putshort(outf,image->dim);
191 putshort(outf,image->xsize);
192 putshort(outf,image->ysize);
193 putshort(outf,image->zsize);
194 putlong(outf,image->min);
195 putlong(outf,image->max);
196 putlong(outf,0);
197 return fwrite("no name",8,1,outf);
198}
199
200static int writetab(outf,tab,len)
201FILE *outf;
202unsigned long *tab;
203int len;
204{
205 int r;
206
207 while(len) {
208 r = putlong(outf,*tab++);
209 len -= 4;
210 }
211 return r;
212}
213
214static readtab(inf,tab,len)
215FILE *inf;
216unsigned long *tab;
217int len;
218{
219 while(len) {
220 *tab++ = getlong(inf);
221 len -= 4;
222 }
223}
224
225/*
226 * sizeofimage -
227 * return the xsize and ysize of an iris image file.
228 *
229 */
230static object *
231sizeofimage(self, args)
232 object *self, *args;
233{
234 char *name;
235 IMAGE image;
236 FILE *inf;
237
238 if (!getargs(args, "s", &name))
239 return NULL;
240
241 inf = fopen(name,"r");
242 if(!inf) {
243 err_setstr(ImgfileError, "can't open image file");
244 return NULL;
245 }
246 readheader(inf,&image);
247 fclose(inf);
248 if(image.imagic != IMAGIC) {
249 err_setstr(ImgfileError, "bad magic number in image file");
250 return NULL;
251 }
252 return mkvalue("(ii)", image.xsize, image.ysize);
253}
254
255/*
256 * longimagedata -
257 * read in a B/W RGB or RGBA iris image file and return a
258 * pointer to an array of longs.
259 *
260 */
261static object *
262longimagedata(self, args)
263 object *self, *args;
264{
265 char *name;
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000266 unsigned char *base, *lptr;
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000267 unsigned char *rledat, *verdat;
268 long *starttab, *lengthtab;
269 FILE *inf;
270 IMAGE image;
271 int y, z, pos, len, tablen;
272 int xsize, ysize, zsize;
273 int bpp, rle, cur, badorder;
274 int rlebuflen;
275 object *rv;
276
277 if (!getargs(args, "s", &name))
278 return NULL;
279
280 inf = fopen(name,"r");
281 if(!inf) {
282 err_setstr(ImgfileError,"can't open image file");
283 return NULL;
284 }
285 readheader(inf,&image);
286 if(image.imagic != IMAGIC) {
287 err_setstr(ImgfileError,"bad magic number in image file");
288 fclose(inf);
289 return NULL;
290 }
291 rle = ISRLE(image.type);
292 bpp = BPP(image.type);
293 if(bpp != 1 ) {
294 err_setstr(ImgfileError,"image must have 1 byte per pix chan");
295 fclose(inf);
296 return NULL;
297 }
298 xsize = image.xsize;
299 ysize = image.ysize;
300 zsize = image.zsize;
301 if(rle) {
302 tablen = ysize*zsize*sizeof(long);
303 starttab = (long *)malloc(tablen);
304 lengthtab = (long *)malloc(tablen);
305 rlebuflen = 1.05*xsize+10;
306 rledat = (unsigned char *)malloc(rlebuflen);
307 fseek(inf,512,SEEK_SET);
308 readtab(inf,starttab,tablen);
309 readtab(inf,lengthtab,tablen);
310
311/* check data order */
312 cur = 0;
313 badorder = 0;
314 for(y=0; y<ysize; y++) {
315 for(z=0; z<zsize; z++) {
316 if(starttab[y+z*ysize]<cur) {
317 badorder = 1;
318 break;
319 }
320 cur = starttab[y+z*ysize];
321 }
322 if(badorder)
323 break;
324 }
325
326 fseek(inf,512+2*tablen,SEEK_SET);
327 cur = 512+2*tablen;
328 rv = newsizedstringobject((char *) 0,
329 (xsize*ysize+TAGLEN)*sizeof(long));
330 if (rv == NULL) {
331 fclose(inf);
332 free(lengthtab);
333 free(starttab);
334 free(rledat);
335 return NULL;
336 }
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000337 base = (unsigned char *) getstringvalue(rv);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000338#ifdef ADD_TAGS
339 addlongimgtag(base,xsize,ysize);
340#endif
341 if(badorder) {
342 for(z=0; z<zsize; z++) {
343 lptr = base;
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000344 if (reverse_order)
345 lptr += (ysize - 1) * xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000346 for(y=0; y<ysize; y++) {
347 if(cur != starttab[y+z*ysize]) {
348 fseek(inf,starttab[y+z*ysize],SEEK_SET);
349 cur = starttab[y+z*ysize];
350 }
351 if(lengthtab[y+z*ysize]>rlebuflen) {
352 err_setstr(ImgfileError,"rlebuf is too small - bad poop");
353 fclose(inf);
354 DECREF(rv);
355 free(rledat);
356 free(starttab);
357 free(lengthtab);
358 return NULL;
359 }
360 fread(rledat,lengthtab[y+z*ysize],1,inf);
361 cur += lengthtab[y+z*ysize];
362 expandrow(lptr,rledat,3-z);
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000363 if (reverse_order)
364 lptr -= xsize * sizeof(unsigned long);
365 else
366 lptr += xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000367 }
368 }
369 } else {
370 lptr = base;
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000371 if (reverse_order)
372 lptr += (ysize - 1) * xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000373 for(y=0; y<ysize; y++) {
374 for(z=0; z<zsize; z++) {
375 if(cur != starttab[y+z*ysize]) {
376 fseek(inf,starttab[y+z*ysize],SEEK_SET);
377 cur = starttab[y+z*ysize];
378 }
379 fread(rledat,lengthtab[y+z*ysize],1,inf);
380 cur += lengthtab[y+z*ysize];
381 expandrow(lptr,rledat,3-z);
382 }
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000383 if (reverse_order)
384 lptr -= xsize * sizeof(unsigned long);
385 else
386 lptr += xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000387 }
388 }
389 if(zsize == 3)
390 setalpha(base,xsize*ysize);
391 else if(zsize<3)
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000392 copybw((long *) base,xsize*ysize);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000393 fclose(inf);
394 free(starttab);
395 free(lengthtab);
396 free(rledat);
397 return rv;
398 } else {
399 rv = newsizedstringobject((char *) 0,
400 (xsize*ysize+TAGLEN)*sizeof(long));
401 if (rv == NULL) {
402 fclose(inf);
403 return NULL;
404 }
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000405 base = (unsigned char *) getstringvalue(rv);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000406#ifdef ADD_TAGS
407 addlongimgtag(base,xsize,ysize);
408#endif
409 verdat = (unsigned char *)malloc(xsize);
410 fseek(inf,512,SEEK_SET);
411 for(z=0; z<zsize; z++) {
412 lptr = base;
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000413 if (reverse_order)
414 lptr += (ysize - 1) * xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000415 for(y=0; y<ysize; y++) {
416 fread(verdat,xsize,1,inf);
417 interleaverow(lptr,verdat,3-z,xsize);
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000418 if (reverse_order)
419 lptr -= xsize * sizeof(unsigned long);
420 else
421 lptr += xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000422 }
423 }
424 if(zsize == 3)
425 setalpha(base,xsize*ysize);
426 else if(zsize<3)
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000427 copybw((long *) base,xsize*ysize);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000428 fclose(inf);
429 free(verdat);
430 return rv;
431 }
432}
433
434/* static utility functions for longimagedata */
435
436static interleaverow(lptr,cptr,z,n)
437unsigned char *lptr, *cptr;
438int z, n;
439{
440 lptr += z;
441 while(n--) {
442 *lptr = *cptr++;
443 lptr += 4;
444 }
445}
446
447static copybw(lptr,n)
448long *lptr;
449int n;
450{
451 while(n>=8) {
452 lptr[0] = 0xff000000+(0x010101*(lptr[0]&0xff));
453 lptr[1] = 0xff000000+(0x010101*(lptr[1]&0xff));
454 lptr[2] = 0xff000000+(0x010101*(lptr[2]&0xff));
455 lptr[3] = 0xff000000+(0x010101*(lptr[3]&0xff));
456 lptr[4] = 0xff000000+(0x010101*(lptr[4]&0xff));
457 lptr[5] = 0xff000000+(0x010101*(lptr[5]&0xff));
458 lptr[6] = 0xff000000+(0x010101*(lptr[6]&0xff));
459 lptr[7] = 0xff000000+(0x010101*(lptr[7]&0xff));
460 lptr += 8;
461 n-=8;
462 }
463 while(n--) {
464 *lptr = 0xff000000+(0x010101*(*lptr&0xff));
465 lptr++;
466 }
467}
468
469static setalpha(lptr,n)
470unsigned char *lptr;
471{
472 while(n>=8) {
473 lptr[0*4] = 0xff;
474 lptr[1*4] = 0xff;
475 lptr[2*4] = 0xff;
476 lptr[3*4] = 0xff;
477 lptr[4*4] = 0xff;
478 lptr[5*4] = 0xff;
479 lptr[6*4] = 0xff;
480 lptr[7*4] = 0xff;
481 lptr += 4*8;
482 n -= 8;
483 }
484 while(n--) {
485 *lptr = 0xff;
486 lptr += 4;
487 }
488}
489
490static expandrow(optr,iptr,z)
491unsigned char *optr, *iptr;
492int z;
493{
494 unsigned char pixel, count;
495
496 optr += z;
497 while(1) {
498 pixel = *iptr++;
499 if ( !(count = (pixel & 0x7f)) )
500 return;
501 if(pixel & 0x80) {
502 while(count>=8) {
503 optr[0*4] = iptr[0];
504 optr[1*4] = iptr[1];
505 optr[2*4] = iptr[2];
506 optr[3*4] = iptr[3];
507 optr[4*4] = iptr[4];
508 optr[5*4] = iptr[5];
509 optr[6*4] = iptr[6];
510 optr[7*4] = iptr[7];
511 optr += 8*4;
512 iptr += 8;
513 count -= 8;
514 }
515 while(count--) {
516 *optr = *iptr++;
517 optr+=4;
518 }
519 } else {
520 pixel = *iptr++;
521 while(count>=8) {
522 optr[0*4] = pixel;
523 optr[1*4] = pixel;
524 optr[2*4] = pixel;
525 optr[3*4] = pixel;
526 optr[4*4] = pixel;
527 optr[5*4] = pixel;
528 optr[6*4] = pixel;
529 optr[7*4] = pixel;
530 optr += 8*4;
531 count -= 8;
532 }
533 while(count--) {
534 *optr = pixel;
535 optr+=4;
536 }
537 }
538 }
539}
540
541/*
542 * longstoimage -
543 * copy an array of longs to an iris image file. Each long
544 * represents one pixel. xsize and ysize specify the dimensions of
545 * the pixel array. zsize specifies what kind of image file to
546 * write out. if zsize is 1, the luminance of the pixels are
547 * calculated, and a sinlge channel black and white image is saved.
548 * If zsize is 3, an RGB image file is saved. If zsize is 4, an
549 * RGBA image file is saved.
550 *
551 */
552static object *
553longstoimage(self, args)
554 object *self, *args;
555{
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000556 unsigned char *lptr;
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000557 char *name;
558 int xsize, ysize, zsize;
559 FILE *outf;
560 IMAGE image;
561 int tablen, y, z, pos, len;
562 long *starttab, *lengthtab;
563 unsigned char *rlebuf;
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000564 unsigned char *lumbuf;
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000565 int rlebuflen, goodwrite;
566
567 if (!getargs(args, "(s#iiis)", &lptr, &len, &xsize, &ysize, &zsize, &name))
568 return NULL;
569
570 goodwrite = 1;
571 outf = fopen(name,"w");
572 if(!outf) {
573 err_setstr(ImgfileError,"can't open output file");
574 return NULL;
575 }
576 tablen = ysize*zsize*sizeof(long);
577
578 starttab = (long *)malloc(tablen);
579 lengthtab = (long *)malloc(tablen);
580 rlebuflen = 1.05*xsize+10;
581 rlebuf = (unsigned char *)malloc(rlebuflen);
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000582 lumbuf = (unsigned char *)malloc(xsize*sizeof(long));
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000583
Sjoerd Mullender92fa23f1993-12-24 10:05:51 +0000584 memset(&image,0,sizeof(IMAGE));
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000585 image.imagic = IMAGIC;
586 image.type = RLE(1);
587 if(zsize>1)
588 image.dim = 3;
589 else
590 image.dim = 2;
591 image.xsize = xsize;
592 image.ysize = ysize;
593 image.zsize = zsize;
594 image.min = 0;
595 image.max = 255;
596 goodwrite *= writeheader(outf,&image);
597 fseek(outf,512+2*tablen,SEEK_SET);
598 pos = 512+2*tablen;
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000599 if (reverse_order)
600 lptr += (ysize - 1) * xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000601 for(y=0; y<ysize; y++) {
602 for(z=0; z<zsize; z++) {
603 if(zsize == 1) {
604 lumrow(lptr,lumbuf,xsize);
605 len = compressrow(lumbuf,rlebuf,CHANOFFSET(z),xsize);
606 } else {
607 len = compressrow(lptr,rlebuf,CHANOFFSET(z),xsize);
608 }
609 if(len>rlebuflen) {
610 err_setstr(ImgfileError,"rlebuf is too small - bad poop");
611 free(starttab);
612 free(lengthtab);
613 free(rlebuf);
614 free(lumbuf);
615 fclose(outf);
616 return NULL;
617 }
618 goodwrite *= fwrite(rlebuf,len,1,outf);
619 starttab[y+z*ysize] = pos;
620 lengthtab[y+z*ysize] = len;
621 pos += len;
622 }
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000623 if (reverse_order)
624 lptr -= xsize * sizeof(unsigned long);
625 else
626 lptr += xsize * sizeof(unsigned long);
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000627 }
628
629 fseek(outf,512,SEEK_SET);
630 goodwrite *= writetab(outf,starttab,tablen);
631 goodwrite *= writetab(outf,lengthtab,tablen);
632 free(starttab);
633 free(lengthtab);
634 free(rlebuf);
635 free(lumbuf);
636 fclose(outf);
637 if(goodwrite) {
638 INCREF(None);
639 return None;
640 } else {
641 err_setstr(ImgfileError,"not enough space for image!!");
642 return NULL;
643 }
644}
645
646/* static utility functions for longstoimage */
647
648static lumrow(rgbptr,lumptr,n)
649unsigned char *rgbptr, *lumptr;
650int n;
651{
652 lumptr += CHANOFFSET(0);
653 while(n--) {
654 *lumptr = ILUM(rgbptr[OFFSET_R],rgbptr[OFFSET_G],rgbptr[OFFSET_B]);
655 lumptr += 4;
656 rgbptr += 4;
657 }
658}
659
660static int compressrow(lbuf,rlebuf,z,cnt)
661unsigned char *lbuf, *rlebuf;
662int z, cnt;
663{
664 unsigned char *iptr, *ibufend, *sptr, *optr;
665 short todo, cc;
666 long count;
667
668 lbuf += z;
669 iptr = lbuf;
670 ibufend = iptr+cnt*4;
671 optr = rlebuf;
672
673 while(iptr<ibufend) {
674 sptr = iptr;
675 iptr += 8;
676 while((iptr<ibufend)&& ((iptr[-8]!=iptr[-4])||(iptr[-4]!=iptr[0])))
677 iptr+=4;
678 iptr -= 8;
679 count = (iptr-sptr)/4;
680 while(count) {
681 todo = count>126 ? 126:count;
682 count -= todo;
683 *optr++ = 0x80|todo;
684 while(todo>8) {
685 optr[0] = sptr[0*4];
686 optr[1] = sptr[1*4];
687 optr[2] = sptr[2*4];
688 optr[3] = sptr[3*4];
689 optr[4] = sptr[4*4];
690 optr[5] = sptr[5*4];
691 optr[6] = sptr[6*4];
692 optr[7] = sptr[7*4];
693 optr += 8;
694 sptr += 8*4;
695 todo -= 8;
696 }
697 while(todo--) {
698 *optr++ = *sptr;
699 sptr += 4;
700 }
701 }
702 sptr = iptr;
703 cc = *iptr;
704 iptr += 4;
705 while( (iptr<ibufend) && (*iptr == cc) )
706 iptr += 4;
707 count = (iptr-sptr)/4;
708 while(count) {
709 todo = count>126 ? 126:count;
710 count -= todo;
711 *optr++ = todo;
712 *optr++ = cc;
713 }
714 }
715 *optr++ = 0;
716 return optr - (unsigned char *)rlebuf;
717}
718
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000719static object *
720ttob(self, args)
721 object *self;
722 object *args;
723{
724 int order, oldorder;
725
726 if (!getargs(args, "d", &order))
727 return NULL;
728 oldorder = reverse_order;
729 reverse_order = order;
730 return newintobject(oldorder);
731}
732
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000733static struct methodlist rgbimg_methods[] = {
734 {"sizeofimage", sizeofimage},
735 {"longimagedata", longimagedata},
736 {"longstoimage", longstoimage},
Sjoerd Mullender0d2d3971993-12-24 14:51:14 +0000737 {"ttob", ttob},
Sjoerd Mullenderc4f169c1993-12-21 17:06:12 +0000738 {NULL, NULL} /* sentinel */
739};
740
741void
742initrgbimg()
743{
744 object *m, *d;
745 m = initmodule("rgbimg", rgbimg_methods);
746 d = getmoduledict(m);
747 ImgfileError = newstringobject("rgbimg,error");
748 if (ImgfileError == NULL || dictinsert(d, "error", ImgfileError))
749 fatal("can't define rgbimg.error");
750}