home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff223.lzh
/
Iff2Sun
/
iff2sun.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-25
|
11KB
|
479 lines
/*
** 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 <sys/types.h>
#include <stdio.h>
#include <rasterfile.h>
#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<numcolors;i++){
fread(chunk, 3, 1, inh);
chunk[3] = 0; chunk[4] = 0;
chunk[0] = (chunk[0] >> 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<hieght;k++)
for(i = 0;i<planes;i++) {
for(j=0;j<width/8;j++){
cc(chunk);
if(feof(inh))
continue;
fread(chunk, 1, 1, inh);
scanline[k][i][j] = *((unsigned char *)chunk);
}
}
/* Here we take the data and output it (finally!) */
currentcolor[0] = rmap[0];
currentcolor[1] = gmap[0];
currentcolor[2] = bmap[0];
for(j = 0;j<hieght;j++){
for(i = 0;i<width/8;i++)
process_pixel(i,j,outh);
}
fclose(inh);
fclose(outh);
} /* end of main */
/* The uncompression routine */
/* Here we uncompress the data for the number of planes */
/* and store it in the global array scanline[][][] */
/* Credits: Leo (the great Caped one) was the originator of the */
/* code I ripped this off from. */
uncompress(planes, width, inh)
FILE *inh;
long planes, width;
{
long i,j,count,bytesperrow;
char len;
unsigned char byte;
for(i=0;i<hieght;i++){
for(j=0;j<planes;j++){
count = 0;
bytesperrow = width / 8;
while(bytesperrow > 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<planes;p++)
result = ((((1 << i) & scanline[scan][p][byte])>>i)<<p) | result;
result = result & 0x3f;
temp = result;
if (hammode) {
temp = (result & 0x30) >> 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;
}