home *** CD-ROM | disk | FTP | other *** search
- /*
- * ifficon.c V1.4
- *
- * IFF brush handling
- *
- * (c) 1991 by Stefan Becker
- *
- */
- #include "ToolManager.h"
-
- /* Our own DiskObject definition */
- struct IFFDObj {
- struct DiskObject id_dobj;
- struct Image id_img;
- ULONG id_size; /* size of image */
- };
-
- /* Bitmap header (BMHD) structure */
- struct BitMapHeader {
- UWORD w,h; /* Width, height in pixels */
- WORD x,y;
- UBYTE nplanes; /* Number of planes */
- UBYTE Masking; /* Masking */
- UBYTE Compression; /* Compression algorithm */
- UBYTE pad1;
- UWORD TransparentColor;
- UBYTE XAspect,YAspect;
- WORD PageWidth, PageHeight;
- };
- #define MSK_HASMASK 1
- #define COMP_NO 0
- #define COMP_BYTERUN1 1
- #define BPR(w) ((((w)+15)>>4)<<1) /* Bytes per row formula */
-
- /* IFF ID's */
- #define ID_ILBM MAKE_ID('I','L','B','M')
- #define ID_BMHD MAKE_ID('B','M','H','D')
- #define ID_BODY MAKE_ID('B','O','D','Y')
-
- /* miscellaneous */
- struct Library *IFFParseBase;
-
- /* Read BODY chunk into memory and convert it to an image */
- static BOOL ReadBODY(struct IFFHandle *iff, struct BitMapHeader *bmhd,
- UBYTE *dest, ULONG bpr, ULONG planeoff)
- {
- register UBYTE *sp,*dp;
- register ULONG row;
- UBYTE *src;
- ULONG planes=bmhd->nplanes;
- ULONG size=CurrentChunk(iff)->cn_Size;
- BOOL ncomp=bmhd->Compression==COMP_NO;
- BOOL mask=bmhd->Masking==MSK_HASMASK;
- BOOL rc=TRUE;
-
- /* Get memory for BODY chunk contents */
- if (!(sp=src=malloc(size))) goto rbe1;
-
- /* Read in the complete BODY chunk */
- if (ReadChunkBytes(iff,src,size)!=size) goto rbe2;
-
- for (row=0; row<bmhd->h; row++) /* Read data row by row */
- {
- register ULONG pl,rem;
- register char k;
-
- for (pl=0; pl<planes; pl++) /* Read data plane by plane */
- {
- dp=dest+pl*planeoff+row*bpr; /* Calculate destination pointer */
-
- if (ncomp)
- for (k=bpr; k--;) *dp++=*sp++; /* No compression */
- else
- { /* Byte Run compression */
- rem=bpr;
-
- while (rem) /* Row not completed */
- {
- k=*sp++; /* Read compression code */
-
- if (k>=0)
- { /* Literal copy */
- if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
-
- while (k--) *dp++=*sp++; /* Copy the following k+1 bytes */
- }
- else if (k!=-128) /* Code -128 == No Operation */
- { /* Byte run encoded */
- register UBYTE byte;
-
- k=-k;
- if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
-
- byte=*sp++; /* Get byte */
- while (k--) *dp++=byte; /* Copy this byte -k+1 times */
- }
- }
- }
- }
-
- if (mask) /* Skip mask plane */
- if (ncomp)
- sp+=bpr; /* No compression */
- else
- { /* Byte Run compression */
- rem=bpr;
-
- while (rem) /* Row not completed */
- {
- k=*sp++; /* Read compression code */
-
- if (k>=0)
- { /* Literal copy */
- if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
- sp+=k; /* Skip the following k+1 bytes */
- }
- else if (k!=-128) /* Code -128 == No Operation */
- { /* Byte run encoded */
- k=-k;
- if ((rem-=++k)<0) goto rbe2; /* Error in de-compression? */
- sp++; /* Skip this byte */
- }
- }
- }
- }
-
- /* All OK */
- rc=FALSE;
-
- rbe2: free(src);
- rbe1: return(rc);
- }
-
- /* Load an IFF brush and create a DiskObject */
- struct DiskObject *LoadIFFIcon(char *name)
- {
- register struct IFFHandle *iff;
- register struct IFFDObj *id=NULL;
- struct ContextNode *cn;
- struct StoredProperty *sp;
- struct BitMapHeader *bmhd;
- ULONG bpr,planeoff;
- BOOL error=TRUE;
-
- /* Open IFF parsing library */
- if (!(IFFParseBase=OpenLibrary("iffparse.library",0))) goto lie1;
-
- /* Get memory for DiskObject and clear it */
- if (!(id=calloc(sizeof(struct IFFDObj),1))) goto lie2;
- id->id_dobj.do_Version=WB_DISKVERSION;
- id->id_dobj.do_Gadget.GadgetRender=&id->id_img;
- id->id_dobj.do_Gadget.UserData=(APTR) WB_DISKREVISION;
-
- /* Alloc IFF handle */
- if (!(iff=AllocIFF())) goto lie3;
-
- /* Open IFF file and init IFF handle */
- if (!(iff->iff_Stream=Open(name,MODE_OLDFILE))) goto lie4;
- InitIFFasDOS(iff);
-
- /* Declare ILBM property & stop chunks. Open IFF context */
- if (PropChunk(iff,ID_ILBM,ID_BMHD)) goto lie5;
- if (StopChunk(iff,ID_ILBM,ID_BODY)) goto lie5;
- if (StopOnExit(iff,ID_ILBM,ID_FORM)) goto lie5;
- if (OpenIFF(iff,IFFF_READ)) goto lie5;
-
- /* Start parsing */
- if (ParseIFF(iff,IFFPARSE_STEP)) goto lie6;
-
- /* Check for FORM ILBM chunk */
- if (!(cn=CurrentChunk(iff))) goto lie6;
- if ((cn->cn_ID!=ID_FORM) || (cn->cn_Type!=ID_ILBM)) goto lie6;
-
- /* Continue parsing until BODY chunk is found */
- if (ParseIFF(iff,IFFPARSE_SCAN)) goto lie6;
-
- /* BMHD chunk found? */
- if (!(sp=FindProp(iff,ID_ILBM,ID_BMHD))) goto lie6;
- bmhd=(struct BitMapHeader *) sp->sp_Data;
-
- /* Check compression type */
- if ((bmhd->Compression!=COMP_NO) && (bmhd->Compression!=COMP_BYTERUN1))
- goto lie6;
-
- /* Retrieve BMHD chunk values */
- id->id_dobj.do_Gadget.Width=bmhd->w;
- id->id_dobj.do_Gadget.Height=bmhd->h+1;
- id->id_img.Width=bmhd->w;
- id->id_img.Height=bmhd->h;
- id->id_img.Depth=bmhd->nplanes;
- id->id_img.PlanePick=(1<<bmhd->nplanes)-1;
-
- /* Allocate chip memory for image data */
- bpr=BPR(bmhd->w); /* Bytes per row */
- planeoff=bpr*bmhd->h; /* Bytes per plane */
- id->id_size=planeoff*bmhd->nplanes; /* Bytes for image */
- if (!(id->id_img.ImageData=AllocMem(id->id_size,
- MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR)))
- goto lie6;
-
- /* Read ImageData */
- error=ReadBODY(iff,bmhd,(UBYTE *) id->id_img.ImageData,bpr,planeoff);
-
- if (error) FreeMem(id->id_img.ImageData,id->id_size);
- lie6: CloseIFF(iff);
- lie5: Close(iff->iff_Stream);
- lie4: FreeIFF(iff);
- lie3: if (error)
- {
- free(id);
- id=NULL;
- }
- lie2: CloseLibrary(IFFParseBase);
- lie1: return(id);
- }
-
- /* Free an IFF icon */
- void FreeIFFIcon(struct DiskObject *dobj)
- {
- register struct IFFDObj *id=dobj;
-
- FreeMem(id->id_img.ImageData,id->id_size);
- free(id);
- }
-