2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
20 #define MIN(a,b) ((a<b)?a:b)
22 #define MAKE_SIG(a,b,c,d) (((long)(a)<<24)+((long)(b)<<16)+((c)<<8)+(d))
24 #define form_sig MAKE_SIG('F','O','R','M')
25 #define ilbm_sig MAKE_SIG('I','L','B','M')
26 #define body_sig MAKE_SIG('B','O','D','Y')
27 #define pbm_sig MAKE_SIG('P','B','M',' ')
28 #define bmhd_sig MAKE_SIG('B','M','H','D')
29 #define cmap_sig MAKE_SIG('C','M','A','P')
35 /* printf("%c%c%c%c",*(&s+3),*(&s+2),*(&s+1),s);*/
36 printf("%c%c%c%c",t[3],t[2],t[1],t[0]);
43 if ((s[3]=getc(f))==EOF) return(EOF);
44 if ((s[2]=getc(f))==EOF) return(EOF);
45 if ((s[1]=getc(f))==EOF) return(EOF);
46 if ((s[0]=getc(f))==EOF) return(EOF);
48 return(*((long *) s));
51 int put_sig(long sig,FILE *f)
53 char *s = (char *) &sig;
69 if (c0==0xff) return(EOF);
71 return(((int)c1<<8) + c0);
75 char get_byte(FILE *f)
80 char put_byte(unsigned char c,FILE *f)
85 int put_word(int n,FILE *f)
89 c0 = (n & 0xff00) >> 8;
93 return put_byte(c1,f);
96 int put_long(long n,FILE *f)
100 n0 = (int) ((n & 0xffff0000l) >> 16);
101 n1 = (int) (n & 0xffff);
104 return put_word(n1,f);
108 long get_long(FILE *f)
110 unsigned char c0,c1,c2,c3;
117 //printf("get_long %x %x %x %x\n",c3,c2,c1,c0);
119 // if (c0==0xff) return(EOF);
121 return(((long)c3<<24) + ((long)c2<<16) + ((long)c1<<8) + c0);
125 void parse_bmhd(FILE *ifile,long len,struct bitmap_header *bitmap_header)
127 len++; /* so no "parm not used" warning */
129 // debug("parsing bmhd len=%ld\n",len);
131 bitmap_header->w = get_word(ifile);
132 bitmap_header->h = get_word(ifile);
133 bitmap_header->x = get_word(ifile);
134 bitmap_header->y = get_word(ifile);
136 bitmap_header->nplanes = get_byte(ifile);
137 bitmap_header->masking = get_byte(ifile);
138 bitmap_header->compression = get_byte(ifile);
139 get_byte(ifile); /* skip pad */
141 bitmap_header->transparentcolor = get_word(ifile);
142 bitmap_header->xaspect = get_byte(ifile);
143 bitmap_header->yaspect = get_byte(ifile);
145 bitmap_header->pagewidth = get_word(ifile);
146 bitmap_header->pageheight = get_word(ifile);
148 // debug("w,h=%d,%d x,y=%d,%d\n",w,h,x,y);
149 // debug("nplanes=%d, masking=%d ,compression=%d, transcolor=%d\n",nplanes,masking,compression,transparentcolor);
154 // the buffer pointed to by raw_data is stuffed with a pointer to decompressed pixel data
155 int parse_body_pbm(FILE *ifile,long len,struct bitmap_header *bitmap_header)
157 unsigned char huge *p=bitmap_header->raw_data;
158 int width=bitmap_header->w;
164 if (bitmap_header->compression == cmpNone) { /* no compression */
167 for (y=bitmap_header->h;y;y--) {
168 for (x=bitmap_header->w;x;x--) *p++=getc(ifile);
169 if (bitmap_header->w & 1) ignore = getc(ifile);
173 else if (bitmap_header->compression == cmpByteRun1)
174 for (old_cnt=cnt=len,wid_cnt=width;cnt>0;) {
177 if (old_cnt-cnt > 2048) {
182 if (wid_cnt <= 0) wid_cnt = width;
185 if (n >= 0) { // copy next n+1 bytes from source, they are not compressed
189 if (wid_cnt==-1) --nn;
190 while (nn--) *p++=getc(ifile);
191 if (wid_cnt==-1) ignore = getc(ifile); /* extra char */
193 else if (n>=-127) { // next -n + 1 bytes are following byte
198 if (wid_cnt==-1) --nn;
204 if (len & 1) ignore = getc(ifile);
206 if (ignore) ignore++; // haha, suppress the evil warning message
211 // the buffer pointed to by raw_data is stuffed with a pointer to bitplane pixel data
212 int parse_body_ilbm(FILE *ifile,long len,struct bitmap_header *bitmap_header)
214 unsigned char huge *p=bitmap_header->raw_data;
215 int width=bitmap_header->w;
221 if (bitmap_header->compression == cmpNone) { /* no compression */
224 for (y=bitmap_header->h;y;y--) {
225 for (x=bitmap_header->w;x;x--) *p++=getc(ifile);
226 if (bitmap_header->w & 1) ignore = getc(ifile);
230 else if (bitmap_header->compression == cmpByteRun1)
231 for (old_cnt=cnt=len,wid_cnt=width;cnt>0;) {
234 if (old_cnt-cnt > 2048) {
239 if (wid_cnt <= 0) wid_cnt = width;
242 if (n >= 0) { // copy next n+1 bytes from source, they are not compressed
246 if (wid_cnt==-1) --nn;
247 while (nn--) *p++=getc(ifile);
248 if (wid_cnt==-1) ignore = getc(ifile); /* extra char */
250 else if (n>=-127) { // next -n + 1 bytes are following byte
255 if (wid_cnt==-1) --nn;
261 if (len & 1) ignore = getc(ifile);
263 if (ignore) ignore++; // haha, suppress the evil warning message
268 void skip_chunk(FILE *ifile,long len)
271 fseek(ifile,len,SEEK_CUR);
274 // Pass pointer to opened file, and to empty bitmap header.
275 int parse_iff(FILE *ifile,struct bitmap_header *bitmap_header)
277 long sig,form_len,len,form_type;
286 form_len = get_long(ifile);
287 form_len++; /* get rid of never used message */
289 form_type = get_sig(ifile);
291 // printf(" %ld ",form_len);
292 // printsig(form_type);
295 if ((form_type == pbm_sig) || (form_type == ilbm_sig)) {
297 if (form_type == pbm_sig)
298 bitmap_header->type = PBM_TYPE;
300 bitmap_header->type = ILBM_TYPE;
302 while ((sig=get_sig(ifile)) != EOF) {
308 // printf(" %ld\n",len);
314 parse_bmhd(ifile,len,bitmap_header);
316 if (! (bitmap_header->raw_data = farmalloc((long) bitmap_header->w * bitmap_header->h))) return IFF_NO_MEM;
322 int ncolors=(int) (len/3),cnum;
325 for (cnum=0;cnum<ncolors;cnum++) {
329 r >>= 2; bitmap_header->palette[cnum].r = r;
330 g >>= 2; bitmap_header->palette[cnum].g = g;
331 b >>= 2; bitmap_header->palette[cnum].b = b;
333 if (len & 1) ignore = getc(ifile);
343 if (!(r=parse_body_pbm(ifile,len,bitmap_header))) return r;
346 if (!(r=parse_body_ilbm(ifile,len,bitmap_header))) return r;
352 skip_chunk(ifile,len);
357 else return IFF_UNKNOWN_FORM;
360 {printf("Not an IFF file\n"); return IFF_NOT_IFF;}
362 if (ignore) ignore++;
364 return IFF_NO_ERROR; /* ok! */
369 int write_bmhd(FILE *ofile,struct bitmap_header *bitmap_header)
372 put_sig(bmhd_sig,ofile);
373 put_long((long) BMHD_SIZE,ofile);
375 put_word(bitmap_header->w,ofile);
376 put_word(bitmap_header->h,ofile);
377 put_word(bitmap_header->x,ofile);
378 put_word(bitmap_header->y,ofile);
380 put_byte(bitmap_header->nplanes,ofile);
381 put_byte(bitmap_header->masking,ofile);
382 put_byte(bitmap_header->compression,ofile);
383 put_byte(0,ofile); /* pad */
385 put_word(bitmap_header->transparentcolor,ofile);
386 put_byte(bitmap_header->xaspect,ofile);
387 put_byte(bitmap_header->yaspect,ofile);
389 put_word(bitmap_header->pagewidth,ofile);
390 put_word(bitmap_header->pageheight,ofile);
396 int write_huge(unsigned char huge *huge_ptr,long len,FILE *f)
398 unsigned char temp_buffer[256],*t;
400 //printf("write_huge %ld\n",len);
403 int n,wsize = (int) MIN(len,256);
405 //printf("len,wsize=%ld,%d\n",len,wsize);
406 for (t=temp_buffer,n=wsize;n--;) *t++ = *huge_ptr++;
408 fwrite(temp_buffer,wsize,1,f);
417 int write_pal(FILE *ofile,struct bitmap_header *bitmap_header)
421 int n_colors = 1<<bitmap_header->nplanes;
423 put_sig(cmap_sig,ofile);
424 // put_long(sizeof(struct pal_entry) * n_colors,ofile);
425 put_long(3 * n_colors,ofile);
427 //printf("new write pal %d %d\n",3,n_colors);
429 for (i=0; i<256; i++) {
431 r = bitmap_header->palette[i].r * 4;
432 g = bitmap_header->palette[i].g * 4;
433 b = bitmap_header->palette[i].b * 4;
439 //printf("write pal %d %d\n",sizeof(struct pal_entry),n_colors);
440 // fwrite(bitmap_header->palette,sizeof(struct pal_entry),n_colors,ofile);
445 #define EVEN(a) ((a+1)&0xfffffffel)
447 int write_body(FILE *ofile,struct bitmap_header *bitmap_header)
449 int w=bitmap_header->w,h=bitmap_header->h;
451 long len = EVEN(w) * h;
452 unsigned char huge *p=bitmap_header->raw_data;
454 put_sig(body_sig,ofile);
457 for (y=bitmap_header->h;y--;) {
459 write_huge(p,bitmap_header->w,ofile);
460 if (odd) putc(0,ofile);
468 int write_pbm(FILE *ofile,struct bitmap_header *bitmap_header) /* writes a pbm iff file */
470 long raw_size = EVEN(bitmap_header->w) * bitmap_header->h;
471 long pbm_size = 4 + BMHD_SIZE + 8 + EVEN(raw_size) + sizeof(struct pal_entry)*(1<<bitmap_header->nplanes)+8;
473 //printf("write_pbm\n");
475 put_sig(form_sig,ofile);
476 put_long(pbm_size+8,ofile);
477 put_sig(pbm_sig,ofile);
479 write_bmhd(ofile,bitmap_header);
481 write_pal(ofile,bitmap_header);
483 write_body(ofile,bitmap_header);