/*:*************************************************************************/ /* */ /* IFF routines. Written by Tom Hudson Rev. 7/15/86 */ /* */ /* START magazine, Fall 1986. Copyright 1986 by Antic Publishing */ /* */ /* To promote the IFF standard, this program is freeware. NOT to be sold. */ /* */ /***************************************************************************/ #include ; #define cmpNone 0 /* No compression */ #define cmpByteRun1 1 /* Run-length encoding compression */ /*************************************************/ /* My IFF read/write routine error codes */ /*************************************************/ #define NotForm -1 /* File is not a FORM type */ #define NoHead -2 /* File does not have a BMHD header */ #define NoData -3 /* File has no image data */ #define Incomplete -4 /* Incomplete image data */ /*************************************************/ /* GLOBAL DATA AREA */ /*************************************************/ int Syspal[16]; /* ST hardware palette array */ int Gempal[16][3]; /* GEM palette data array */ int xparent; /* transparent color index */ /*************************************************/ /* MODULE DATA AREA */ /*************************************************/ static long FORM = 0x464f524d; /* "FORM" */ static long BODY = 0x424f4459; /* "BODY" */ static long BMHD = 0x424d4844; /* "BMHD" */ static long CMAP = 0x434d4150; /* "CMAP" */ static long ILBM = 0x494c424d; /* "ILBM" */ static long form_size,BMHD_size; struct BMHD_data { int w,h; /* width & height of block */ int x,y; /* X & Y coord within block */ char nPlanes; /* number of bit planes */ char masking; /* masking (ignored) */ char compression; /* compression flag */ char padding; /* unused filler byte */ int transcolor; /* transparent color number */ char xAspect,yAspect; /* pixel aspect ratios */ int pageWidth,pageHeight; /* width & height of page */ }; struct BMHD_data bmhd; struct Chunk { long chk_ID; /* 4-character chunk ID */ long chk_size; /* chunk size in bytes */ }; struct Chunk chk; /*************************************************/ /* Read an IFF identifier and size into memory */ /* */ /* Format: */ /* iff_id(fhand) */ /* */ /* Where: */ /* fhand = handle of file opened for input */ /* */ /* Returns: */ /* 0 = OK (no error) */ /* -1 = Read error has occurred */ /* */ /*************************************************/ iff_id(fhand) int fhand; { if(Fread(fhand,8L,&chk)==8L) return(0); return(-1); } /*************************************************/ /* Read an IFF color map into memory and change */ /* it into a form we can use. */ /* */ /* Format: */ /* proc_CMAP(fhand) */ /* */ /* Where: */ /* fhand = handle of file opened for input */ /* */ /* Returns: */ /* 0 = OK (no error) */ /* -1 = Error has occurred */ /* */ /* Alters: */ /* Syspal array contains system format palette */ /* Gempal array contains GEM palette data */ /* */ /*************************************************/ proc_CMAP(fhand) int fhand; { register int pal_ix,pal_odd; static char R_G_B[3]; /* GEM palette entry offsets */ static int paloff[16]= { 0,2,3,6,4,7,5,8,9,10,11,14,12,15,13,1 }; pal_odd=chk.chk_size & 1; pal_ix=0; while(chk.chk_size>0L && pal_ix<16) { if(Fread(fhand,3L,R_G_B)<3L) return(-1); Syspal[pal_ix]=(((int)R_G_B[0] << 3) & 0x0700) | (((int)R_G_B[1] >> 1) & 0x0070) | (((int)R_G_B[2] >> 5) & 0x0007); Gempal[paloff[pal_ix]][0]=(((int)R_G_B[0] >> 5) & 7) * 142; Gempal[paloff[pal_ix]][1]=(((int)R_G_B[1] >> 5) & 7) * 142; Gempal[paloff[pal_ix++]][2]=(((int)R_G_B[2] >> 5) & 7) * 142; chk.chk_size-=3; } Fseek((long)(chk.chk_size+pal_odd),fhand,1); return(0); } /*************************************************/ /* Read a compressed IFF BODY scan line and */ /* place it into the memory form designated by */ /* user. */ /* */ /* Format: */ /* decompress(fhand,mfdb,use,row,plane,RAMptr) */ /* */ /* Where: */ /* fhand = handle of file opened for input */ /* mfdb = standard GEM MFDB for bit block */ /* use = 1 to use data, 0 to ignore */ /* row = word row to read */ /* plane = plane to read */ /* RAMptr= pointer to form buffer */ /* */ /*************************************************/ decompress(fhand,mfdb,use,row,plane,RAMptr) int fhand,mfdb[16],use; unsigned row,plane; char RAMptr[]; { register int ix; register unsigned offset,offinc; static int dccount,dcptr,ffbytes; static char decombuf[160],comp_flg,comp_byte; dccount=(((bmhd.w+15)>>4)<<1); dcptr=0; while(dccount) { if(Fread(fhand,1L,&comp_flg)<1) return(-1); if(comp_flg>=0) { comp_flg++; dccount-=comp_flg; if(Fread(fhand,(long)comp_flg,&decombuf[dcptr])<(long)comp_flg) return(-1); dcptr+=comp_flg; } else if(comp_flg != -128) { comp_flg= -comp_flg+1; dccount-=comp_flg; if(Fread(fhand,1L,&comp_byte)<1L) return(-1); for(ix=0; ix>4)<<1); if(Fread(fhand,(long)dccount,decombuf)<(long)dccount) return(-1); if(use) toraster(mfdb,row,plane,decombuf,RAMptr); return(0); } /*************************************************/ /* Write a scan line to the IFF-format file (no */ /* compression) */ /* */ /* Format: */ /* rawwrite(fhand,mfdb,row,plane,RAMptr) */ /* */ /* Where: */ /* fhand = handle of file opened for output */ /* mfdb = standard GEM MFDB for bit block */ /* row = row to write */ /* plane = plane to write */ /* RAMptr= pointer to form buffer */ /* */ /*************************************************/ rawwrite(fhand,mfdb,row,plane,RAMptr) int fhand,mfdb[]; unsigned row,plane; char RAMptr[]; { long dccount; static char decombuf[160]; dccount=(long)(((bmhd.w+15)>>4)<<1); fmraster(mfdb,row,plane,decombuf,RAMptr); if(Fwrite(fhand,dccount,decombuf)15) xparent=0; CMAP_BODY: if(iff_id(fhand)<0) return(NoHead); if(chk.chk_ID==CMAP) { if(proc_CMAP(fhand)<0) return(Incomplete); goto CMAP_BODY; } else if(chk.chk_ID!=BODY) { Fseek(chk.chk_size,fhand,1); goto CMAP_BODY; } /* Got BODY Header, process into MFDB data */ mfdb[5]=mfdb[7]=mfdb[8]=mfdb[9]=0; mfdb[2]=bmhd.w; mfdb[3]=bmhd.h; mfdb[4]=(mfdb[2]+15)/16; mfdb[6]=bmhd.nPlanes; /* Return to caller */ return(0); } /*************************************************/ /* Do phase 2 IFF file read. */ /* */ /* Format: */ /* iff_rd2(fhand,mfdb) */ /* */ /* Where: */ /* fhand = handle of file opened for input */ /* mfdb = standard GEM MFDB for bit block */ /* */ /* Returns: */ /* 0 = OK (no error) */ /* <0 = IFF read error code */ /* */ /*************************************************/ int iff_rd2(fhand,mfdb) int fhand,mfdb[16]; { register int ix,useit,bytect; register unsigned row,plane; register char *RAMptr; RAMptr=(char *)(((long)mfdb[0]<<16) | (((long)mfdb[1]) & 0x0000ffffL)); bytect=mfdb[3]*mfdb[4]*mfdb[6]*2; /* Clear memory form to zeroes */ for(ix=0; ix> 3) & 0x00e0; rgb_buf[1]=(palette[ix] << 1) & 0x00e0; rgb_buf[2]=(palette[ix] << 5) & 0x00e0; Fwrite(fhand,3L,rgb_buf); form_size+=3L; } Fwrite(fhand,4L,&BODY); bodysize=((mfdb[2]+15)/16)*2*mfdb[6]*mfdb[3]; Fwrite(fhand,4L,&bodysize); form_size+=8L; RAMptr=(char *)(((long)mfdb[0]<<16) | (((long)mfdb[1]) & 0x0000ffffL)); for(row=0; row