/* ** This Program created (under tremendous pressure) by Steve Berry ** with help and modifications by Mark Thompson and others. ** ** I hope you guys keep it clean. (If you don't, let me know :-) ** ** Status: PD all the way. ** ** Please read the file named DOC, that came with this distribution for ** information on how to use iff2sun. ** ** Limitations: ** I have only tested this on DPaintII images, it is ** very possible that it might break with other formats. ** Unlikely, but possible :*) ** ** CREDITS: ** Mark Thompson ** Steve (Raz) Berry ** ** Contacts: ** Steve Berry ...sun!kilowatt!raz or ** raz%kilowatt.EBay@sun.com ** BIX: razberry ** Mark Thompson ...decvax!savax!thompson ** ** Revision History: ** ** 10/31/88 First release, does only simple conversion and no color. ** ** 12/88 Re-released with color support. Unfortunately few if any ** one saw this release (it got lost on the way to the moderator) ** (This is Mark's claim to fame) ** ** 4/26/89 Added Extra-half-bright support, also looking for the ** best way to convert HAM (4096) to 8 bit (256) format. ** ** 5/26/89 Added HAM mode conversion (with convert) and fixed an iff ** parsing bug (parse()), and added new argument parsing supplied ** by Tony Schene. The original convert.c was supplied by ** Tony Kennedy as well as the bug report on DPaintIII images. */ #include #include #include #define HAM 0x800 /* Amiga Viewmodes */ #define HALF 0x80 #define HIRES 0x8000 #define LACE 0x4 #define TRUE 1 #define FALSE 0 /* Stupic C needs to be told about functions used before they are defined */ unsigned char RGBtoLuma(); long parse(); /* Some variables and arrays */ u_char rmap[128],rhmap[128]; u_char gmap[128],ghmap[128]; u_char bmap[128],bhmap[128]; u_char currentcolor[3]; u_char scanline[1024][6][128]; /* vert, planes, width (bytes) */ long width, hieght, planes, hammode, numcolors; long temp, compress, i, j, k, l; int colorpic=FALSE, halfb = FALSE, pixelrep = FALSE; char *Usage = "Usage: %s [ -chp ] [ infile ] [ outfile ]\n"; main(argc,argv) int argc; char **argv; { struct rasterfile header; unsigned char clr; long formsize, twidth, thieght; static char chunk[5]; FILE *inh, *outh; char *progname= argv[0]; char c; extern char *optarg; extern int optind; chunk[4] = 0; inh = stdin; outh = stdout; while ((c = getopt (argc, argv, "chp")) != -1) switch (c) { case 'c': colorpic = TRUE; fprintf(stderr,"Color output selected\n"); break; case 'h': halfb = TRUE; fprintf(stderr,"Extra Half-bright selected\n"); break; case 'p': pixelrep = TRUE; break; default: fprintf (stderr, Usage, argv[0]); exit (1); } if (optind < argc) inh = fopen(argv[optind],"r"); if (++optind < argc) outh = fopen(argv[optind],"w"); if (++optind < argc) { fprintf (stderr, Usage, argv[0]); exit (1); } if (inh == NULL){ perror(argv[1]); exit(-10); } if (outh == NULL){ perror(argv[2]); exit(-10); } /* Now comes the fun part... Reading the ILBM's */ if (parse(inh,"FORM")) { perror("I don't think that this is an IFF file"); exit(-10); } fread(&formsize, 4, 1, inh); /* length of the FORM */ if (parse(inh,"ILBM")) { perror("I don't think that this is an ILBM"); exit(-10); } if (parse(inh,"BMHD")) { perror("Bad format for ILBM."); exit(-10); } cc(chunk); fread(chunk, 4, 1, inh); /* length of the BMHD */ cc(chunk); fread(chunk, 2, 1, inh); /* width of bitmap */ width = *((short *)chunk); cc(chunk); fread(chunk, 2, 1, inh); /* Height of bitmap */ hieght = *((short *)chunk); fread(chunk, 4, 1, inh); /* Don't want the orgins */ cc(chunk); fread(chunk, 1, 1, inh); /* # of Planes */ planes = *((unsigned char *)chunk); fread(chunk, 1, 1, inh); /* Ignore the Mask */ cc(chunk); fread(chunk, 1, 1, inh); /* Compression? */ compress = *((unsigned char *)chunk); fread(chunk, 1, 1, inh); /* just a pad byte */ /*********************************************************************** ** DpaintII does not use the CAMG chunk, so we will have to ignore ** it for now... ***********************************************************************/ /* if (planes == 6) { perror("Sorry, I can't do HAM or Halfbright."); exit(0); } */ if (parse(inh,"CMAP")) { perror("Bad format for ILBM, couldn't find Color Map."); exit(-10); } cc(chunk); fread(chunk, 4, 1, inh); /* # of color registers */ numcolors = *((long *)chunk); for(i=0; i<64; i++) { rmap[i]= i; gmap[i]= i; bmap[i]= i; } numcolors = numcolors/3 ; for (i=0;i> 4) & 0x0f; chunk[2] = (chunk[2] >> 4) & 0x0f; chunk[1] = (chunk[1] >> 4) & 0x0f; if(colorpic==TRUE) { rmap[i] = (chunk[0] << 4) | chunk[0]; gmap[i] = (chunk[1] << 4) | chunk[1]; bmap[i] = (chunk[2] << 4) | chunk[2]; } else { rmap[i] = RGBtoLuma(chunk); gmap[i] = RGBtoLuma(chunk); bmap[i] = RGBtoLuma(chunk); } if (halfb == TRUE) { rhmap[i] = rmap[i]>>1; ghmap[i] = gmap[i]>>1; bhmap[i] = bmap[i]>>1; } } if (numcolors == 2) /* if a mono image, realign to long word */ fread(chunk,1,2,inh); if (parse(inh,"BODY")){ perror("No BODY data."); exit(0); } if ((planes == 6) && (halfb == TRUE) && (numcolors == 16) || (planes != 6) && (halfb == TRUE)){ perror("You specified Half-Bright, but file is not in the correct format\n"); exit(0); } if ((planes == 6) && (halfb != TRUE)) { fprintf(stderr, "Ham mode... raw color output initiated.\n"); hammode = TRUE; } fread(chunk, 4, 1, inh); /* length of body */ if (!hammode) { header.ras_magic= 0x59a66a95; if (pixelrep == FALSE) header.ras_width= width; else header.ras_width= width * 2; header.ras_height= hieght; header.ras_depth= 8; if (pixelrep == FALSE) header.ras_length= width * hieght; else header.ras_length= width * 2 * hieght; header.ras_type= RT_STANDARD; header.ras_maptype= RMT_EQUAL_RGB; header.ras_maplength= 3*256; /* Write out the rasterfile header to the ouput */ fwrite(&header, sizeof(header), 1, outh); /* Write out the red colormap to the ouput */ if (fwrite(rmap, sizeof(rmap), 1, outh) == 0) { perror(progname); exit(1); } if (halfb == TRUE) fwrite(rhmap, sizeof(rhmap), 1, outh); else fwrite(rmap, sizeof(rmap), 1, outh); /* Write out the green colormap to the ouput */ if (fwrite(gmap, sizeof(gmap), 1, outh) == 0) { perror(progname); exit(1); } if (halfb == TRUE) fwrite(ghmap, sizeof(ghmap), 1, outh); else fwrite(gmap, sizeof(gmap), 1, outh); /* Write out the blue colormap to the ouput */ if (fwrite(bmap, sizeof(bmap), 1, outh) == 0) { perror(progname); exit(1); } if (halfb == TRUE) fwrite(bhmap, sizeof(bhmap), 1, outh); else fwrite(bmap, sizeof(bmap), 1, outh); } else { twidth = width; if (pixelrep) { twidth = width * 2; } fwrite(&twidth, 4, 1, outh); fwrite(&hieght, 4, 1, outh); } /* This part does all the work */ /* Either we uncompress the file, or we read it in... */ if (compress == 1) uncompress(planes, width, inh); else for(k = 0;k 0){ if ((len = getc(inh)) >= 0){ bytesperrow -= ++len; fread(&scanline[i][j][count],len,1,inh); count += len; } else if (len == -128) ; else if (len < 0){ len = -len + 1; bytesperrow -= len; byte = getc(inh); while(--len >= 0) scanline[i][j][count++] = byte; } } if(bytesperrow) perror("Compression is messed."); } } } /* RGBtoLuma converts the colortable from the Amiga to Luminance information */ /* This routine was written by Mark Thompson */ unsigned char RGBtoLuma(color) unsigned char *color; { unsigned char r, g, b; unsigned char grey; float fgrey; r = (color[0] << 4) + color[0]; g = (color[1] << 4) + color[1]; b = (color[2] << 4) + color[2]; fgrey = 0.3 * r + 0.59 * g + 0.11 * b + 0.5; grey = fgrey; return grey; } /* Process the byte for the scanline */ /* Can you say shift 3 times fast? */ process_pixel(byte,scan,outh) FILE *outh; unsigned char byte; long scan; { long j, i, p, result = 0; unsigned char temp; temp = 0; result = 0; for(i=7;i>=0;i--){ for(p=0;p>i)<> 4; switch (temp){ case 0x0: temp = result & 0x0f; currentcolor[2] = bmap[temp]<<4; currentcolor[1] = gmap[temp]<<4; currentcolor[0] = rmap[temp]<<4; break; case 0x1: result = result & 0x0f; currentcolor[2] = result<<4; break; case 0x2: result = result & 0x0f; currentcolor[0] = result<<4; break; case 0x3: result = result & 0x0f; currentcolor[1] = result<<4; break; } fwrite(currentcolor, 1, 3, outh); if (pixelrep == TRUE) fwrite(currentcolor, 1, 3, outh); } else { fwrite(&temp, 1, 1, outh); if (pixelrep == TRUE) fwrite(&temp, 1, 1, outh); } result = 0; } } /* look for a chunk in the file */ long parse(inh, str) FILE *inh; char *str; { static char chunk[5]; chunk[4] = 0; while (1){ fread(chunk, 2, 1, inh); if (strncmp(chunk,str,2) == 0){ fread(chunk, 2, 1, inh); if (strncmp(chunk,&str[2],2) == 0) return FALSE; } if(feof(inh) != 0) return TRUE; } } /* Clear Chunk variable */ cc(chunk) char chunk[5]; { register int i; for(i=0;i<5;i++) chunk[i] = 0; }