home *** CD-ROM | disk | FTP | other *** search
- /* PCXtoIFF.c - Converts IBM .PCX picture files to IFF format
- *
- * Written by David Godshall
- * Released into the Public Domain by David Godshall
- *
- * This little utility was written as the request of another BBS caller who
- * wanted to be able to view IBM .PCX type graphic files on his Amiga. He
- * uploaded the source to an IBM .PCX viewer which I used to determine the
- * format of PCX files in order to be able to write this. I was going to
- * write a PCX viewer, but decided it would be better to be able to convert
- * PCX files to IFF so more could be done with them then just viewing.
- */
-
- #include <exec/types.h>
- #include <stdio.h>
- #include <string.h>
-
- #define COMPRESS 1 /* Remove this line to disable compression */
-
- typedef struct {
- UBYTE red, green, blue;
- } TRIPLET;
-
- typedef struct { /* 128 byte header in PCX files */
- UBYTE maker; /* ??? */
- UBYTE version; /* PCX version */
- UBYTE code; /* ??? */
- UBYTE bpp; /* ??? */
- WORD x1,y1; /* Top, Left corner */
- WORD x2,y2; /* Bottom, Right corner */
- WORD hres, vres; /* Dots-Per-Inch */
- TRIPLET triple[16]; /* palette */
- UBYTE vmode; /* ??? */
- UBYTE nplanes; /* Number of bitplanes */
- UWORD bpl; /* Number of bytes per row */
- UBYTE pad[128-68];
- } PCXHDR;
-
- UBYTE Buffer[1024];
- int WriteSize,BodyPosition,BodySize;
-
- PCXHDR PCXHeader;
- int PCXWide,PCXHigh,PCXDeep,PCX_BPL,IFF_BPL;
-
- #define SwapWord(x) ((x) = ((x) & 0x00FF)<<8 | ((x) & 0xFF00)>>8)
-
-
- UBYTE ReadByte(fin)
-
- FILE *fin;
- {
- UBYTE data;
-
- if (fread((char *)&data,1,1,fin) != 1)
- {
- printf ("%% Error reading PCX file\n");
- exit(20);
- }
- return data;
- }
-
-
- void WriteLong(fout,data)
-
- FILE *fout;
- ULONG data;
- {
- if (fwrite((char *)&data,4,1,fout) != 1)
- {
- printf ("%% Error writing IFF file\n");
- exit(20);
- }
- WriteSize += 4;
- }
-
-
- void WriteWord(fout,data)
-
- FILE *fout;
- UWORD data;
- {
- if (fwrite((char *)&data,2,1,fout) != 1)
- {
- printf ("%% Error writing IFF file\n");
- exit(20);
- }
- WriteSize += 2;
- }
-
-
- void WriteByte(fout,data)
-
- FILE *fout;
- UBYTE data;
- {
- if (fwrite((char *)&data,1,1,fout) != 1)
- {
- printf ("%% Error writing IFF file\n");
- exit(20);
- }
- WriteSize += 1;
- }
-
-
- void WriteData(fout,data,size)
-
- FILE *fout;
- APTR data;
- int size;
- {
- if (fwrite((char *)data,size,1,fout) != 1)
- {
- printf ("%% Error writing IFF file\n");
- exit(20);
- }
- WriteSize += size;
- }
-
-
- void WriteIFFRow(fout,data,size)
-
- FILE *fout;
- UBYTE *data;
- int size;
- {
- #ifdef COMPRESS
- UBYTE *ptr,*maxptr;
- UBYTE ob,b;
- int len,pos;
-
- pos = WriteSize;
- ptr = data;
- maxptr = data+size;
- ob = *ptr++;
- while (data < maxptr)
- {
- b = *ptr++;
- while (b == ob && ptr < maxptr)
- b = *ptr++;
- len = ptr - data;
- if (ptr < maxptr)
- len--;
- while (len >= 128)
- {
- WriteByte(fout,257-128);
- WriteByte(fout,ob);
- len -= 128;
- data += 128;
- }
- if (len > 2)
- {
- WriteByte(fout,257-len);
- WriteByte(fout,ob);
- data += len;
- }
- else
- {
- ob = *data;
- while (ptr < maxptr)
- {
- if (b != ob)
- {
- ob = b;
- b = *ptr++;
- }
- else
- if (ptr+1 < maxptr)
- {
- if (*ptr == b)
- break;
- ob = b;
- b = *ptr++;
- }
- else
- break;
- }
- len = ptr-data-1;
- if (ptr < maxptr)
- len--;
- while (len > 128)
- {
- WriteByte(fout,127);
- WriteData(fout,data,128);
- len -= 128;
- data += 128;
- }
- if (len > 0)
- {
- WriteByte(fout,len-1);
- WriteData(fout,data,len);
- data += len;
- }
- }
- ob = *data;
- }
- /* if (WriteSize-pos & 1)
- WriteByte(fout,0); */
- #else
- WriteData(fout,data,size);
- #endif
- }
-
-
- int main(argc,argv)
-
- int argc;
- char *argv[];
- {
- FILE *fin,*fout;
- int x,y,n,b;
- int AllRows,oldperc,newperc;
- UBYTE *ptr;
-
- if (argc == 3)
- {
- fin = fopen(argv[1],"r");
- if (fin)
- {
- if (fread((char *)&PCXHeader,1,128,fin) == 128)
- {
- PCXWide = SwapWord(PCXHeader.x2)+1;
- PCXHigh = SwapWord(PCXHeader.y2)+1;
- PCXWide -= SwapWord(PCXHeader.x1);
- PCXHigh -= SwapWord(PCXHeader.y1);
- SwapWord(PCXHeader.hres);
- SwapWord(PCXHeader.vres);
- PCX_BPL = SwapWord(PCXHeader.bpl);
- IFF_BPL = PCX_BPL;
- if (IFF_BPL & 1)
- IFF_BPL++;
- PCXDeep = PCXHeader.nplanes;
-
- printf ("Converting %dx%dx%d from PCX to IFF... ",PCXWide,PCXHigh,PCXDeep);
-
- fout = fopen(argv[2],"w");
- if (fout)
- {
- WriteSize = 0;
- WriteData(fout,"FORM ILBMBMHD",16);
- WriteLong(fout,20);
- WriteWord(fout,PCXWide); /* Width */
- WriteWord(fout,PCXHigh); /* Height */
- WriteWord(fout,PCXHeader.x1); /* Xoffset */
- WriteWord(fout,PCXHeader.y1); /* Yoffset */
- WriteByte(fout,PCXDeep); /* Depth */
- WriteByte(fout,0); /* Masking */
- #ifdef COMPRESS
- WriteByte(fout,1); /* Compression on */
- #else
- WriteByte(fout,0); /* Compression off */
- #endif
- WriteByte(fout,0); /* pad */
- WriteWord(fout,0); /* Transparent Color */
- WriteByte(fout,10); /* XAspect, YAspect */
- WriteByte(fout,PCXHeader.hres*10 / PCXHeader.vres);
- WriteWord(fout,PCXWide); /* PageWidth */
- WriteWord(fout,PCXHigh); /* PageHeight */
- WriteData(fout,"CMAP",4);
- WriteLong(fout,(1<<PCXDeep)*3);
- WriteData(fout,&PCXHeader.triple,(1<<PCXDeep)*3);
- WriteData(fout,"BODY ",8);
- BodyPosition = WriteSize-4;
-
- AllRows = PCXHigh*PCXDeep;
- n = 0;
- ptr = Buffer;
- oldperc = -1;
- for (y=0; y<AllRows; y++)
- {
- newperc = (y*100)/AllRows;
- if (newperc != oldperc)
- printf ("%3d%%\b\b\b\b",newperc);
- oldperc = newperc;
- for (x=n; x<PCX_BPL; x+=n)
- {
- n = ReadByte(fin);
- if ((n & 0xC0) == 0xC0)
- {
- n &= 0x3F;
- b = ReadByte(fin);
- memset(ptr,b,n);
- ptr += n;
- }
- else
- {
- *ptr++ = n;
- n = 1;
- }
- }
- WriteIFFRow(fout,Buffer,IFF_BPL);
- ptr = Buffer;
- n = x-PCX_BPL;
- if (n > 0)
- {
- memset(ptr,b,n);
- ptr += n;
- }
- }
- BodySize = WriteSize - BodyPosition - 4;
- if (BodySize & 1)
- {
- WriteByte(fout,0);
- BodySize++;
- }
- fseek(fout,BodyPosition,0);
- WriteLong(fout,BodySize);
- fseek(fout,4,0);
- WriteLong(fout,BodyPosition+BodySize-4);
- printf ("Done!\n");
-
- return 0;
- }
- else
- printf ("%%%% Unable to open %s for output as IFF file\n",argv[2]);
- }
- else
- printf ("%%%% Invalid PCX file\n");
- }
- else
- printf ("%%%% Unable to open %s for input from PCX file\n",argv[1]);
- }
- else
- printf ("\nUsage:\n\n PCXTOIFF <sourcepcxfile> <destifffile>\n\n");
-
- return 20;
- }
-