home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------*
- * ILBMR.C Support routines for reading ILBM files. 11/27/85
- * (IFF is Interchange Format File.)
- *
- * By Jerry Morrison and Steve Shaw, Electronic Arts.
- * This software is in the public domain.
- *
- * This version for the Commodore-Amiga computer.
- *----------------------------------------------------------------------*/
- #include <exec/memory.h>
- #include <graphics/rastport.h>
- #include <iff/packer.h>
- #include <iff/ilbm.h>
- #include <iff/readpict.h>
-
- #include "picture.h"
- #include <mymacros.h>
-
- /* ---------- GetCMAP ------------------------------------------------*/
- /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
- * caller has space to hold. GetCMAP sets to the number actually read.*/
- IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)
- GroupContext *ilbmContext;
- WORD *colorMap;
- WORD *pNColorRegs;
- {
- register int nColorRegs;
- register IFFP iffp;
- ColorRegister colorReg;
-
- nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
- if (*pNColorRegs < nColorRegs) {
- nColorRegs = *pNColorRegs;
- }
- *pNColorRegs = nColorRegs; /* Set to the number actually there.*/
-
- for ( ; nColorRegs > 0; --nColorRegs) {
- iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
- CheckIFFP();
- *colorMap++ = ( ( colorReg.red >> 4 ) << 8 ) |
- ( ( colorReg.green >> 4 ) << 4 ) |
- ( ( colorReg.blue >> 4 ) );
- }
- return(IFF_OKAY);
- }
-
- /*---------- GetBODY ---------------------------------------------------*/
- /* NOTE: This implementation could be a LOT faster if it used more of the
- * supplied buffer. It would make far fewer calls to IFFReadBytes (and
- * therefore to DOS Read) and to movemem. */
- IFFP GetBODY(context, ilbmframe, mask, buffer, bufsize, srcbm)
- GroupContext *context;
- ILBMFrame *ilbmframe;
- BYTE *mask;
- BYTE *buffer;
- LONG bufsize;
- struct BitMap *srcbm;
- {
- register IFFP iffp;
- BitMapHeader *bmHdr = &ilbmframe->bmHdr;
- UBYTE srcPlaneCnt = bmHdr->nPlanes;
- WORD srcRowBytes = RowBytes(bmHdr->w);
- LONG bufRowBytes = MaxPackedSize(srcRowBytes);
- int nRows = bmHdr->h;
- Compression compression = bmHdr->compression;
- register int iPlane, iRow, nEmpty;
- register WORD nFilled;
- BYTE *buf, *nullDest, *nullBuf, **pDest;
- BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
- long gtemp;
- NewImage *ni = ilbmframe->ni;
- struct BitMap *bitmap = (struct BitMap *)ni->ImagePtr;
- struct RastPort *rp = (struct RastPort *)ni->ImagePtr;
- BYTE *gDest;
-
- /**********************
- **
- ** Added for SimGen.
- **
- *********************/
- AboutToLoadBody (ilbmframe);
-
- if (compression > cmpByteRun1)
- return(CLIENT_ERROR);
-
- /*
- * if mode = CREATEPIC
- * Allocate and Initialize a bitmap for this picture
- */
-
- if (ni->Flags & (NI_CREATEPIC | NI_CREATESHAPE)) {
- int i;
- int w;
- int h;
-
- if (ni->Flags & NI_CLIPIMAGE) {
- w = ni->Width;
- h = ni->Height;
- } else {
- w = bmHdr->w;
- h = bmHdr->h;
- }
-
- ni->Flags |= NI_USEBITMAP;
- bitmap = &ilbmframe->pic->BitMap;
- ni->ImagePtr = (APTR)bitmap;
-
- InitBitMap (bitmap, bmHdr->nPlanes, w, h);
- for (i=0; i<bmHdr->nPlanes; i++) {
- if (!( bitmap->Planes[i] =
- (*ilbmframe->allocmem)(RASSIZE(w, h), MEMF_CHIP|MEMF_CLEAR))) {
- return (CLIENT_ERROR);
- }
- }
- } else {
- if (!(ni->Flags & NI_USEBITMAP)) {
- bitmap = rp->BitMap;
- }
- }
-
- /* Complain if client asked for a conversion GetBODY doesn't handle.*/
-
- if (!ni->Flags & NI_CLIPIMAGE) {
- if (srcPlaneCnt > MaxSrcPlanes ||
- srcRowBytes > bitmap->BytesPerRow ||
- nRows > bitmap->Rows)
- return (CLIENT_ERROR);
- }
-
- /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
- for (iPlane = 0; iPlane < srcbm->Depth; iPlane++)
- planes[iPlane] = (BYTE *)srcbm->Planes[iPlane];
- for ( ; iPlane < MaxSrcPlanes; iPlane++)
- planes[iPlane] = NULL;
-
- /* Copy any mask plane ptr into corresponding "planes" slot.*/
- if (bmHdr->masking == mskHasMask) {
- if (mask != NULL)
- planes[srcPlaneCnt] = mask;
- /* If there are more srcPlanes than
- * dstPlanes, there will be NULL
- * plane-pointers before this. */
- else
- planes[srcPlaneCnt] = NULL;
- /* In case more dstPlanes than src.*/
- srcPlaneCnt += 1; /* Include mask plane in count.*/
- }
-
- /* Setup a sink for dummy destination of rows from unwanted planes.*/
- nullDest = buffer;
- buffer += srcRowBytes;
- bufsize -= srcRowBytes;
-
- /* Read the BODY contents into client's bitmap.
- * De-interleave planes and decompress rows.
- * MODIFIES: Last iteration modifies bufsize.*/
-
- buf = buffer + bufsize; /* Buffer is currently empty.*/
- for (iRow = 0; iRow < nRows; iRow++) {
- for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++) {
-
- gDest = (BYTE *)srcbm->Planes[iPlane];
- pDest = &gDest;
-
- /* Establish a sink for any unwanted plane.*/
- if (*pDest == NULL) {
- nullBuf = nullDest;
- pDest = &nullBuf;
- }
-
- /* Read in at least enough bytes to
- uncompress next row. */
-
- nEmpty = buf - buffer; /* size of empty part of buffer.*/
- nFilled = bufsize - nEmpty; /* this part has data.*/
- if (nFilled < bufRowBytes) {
- /* Need to read more.*/
-
- /* Move the existing data to the front of the buffer.*/
- /* Now covers range buffer[0]..buffer[nFilled-1].*/
- movmem(buf, buffer, nFilled); /* Could be moving 0 bytes.*/
-
- if (nEmpty > ChunkMoreBytes(context)) {
- /* There aren't enough bytes left to fill the buffer.*/
- nEmpty = ChunkMoreBytes(context);
- bufsize = nFilled + nEmpty; /* heh-heh */
- }
-
- /* Append new data to the existing data.*/
- iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
- CheckIFFP();
-
- buf = buffer;
- nFilled = bufsize;
- nEmpty = 0;
- }
-
- /* Copy uncompressed row to destination plane.*/
- if (compression == cmpNone) {
- if (nFilled < srcRowBytes) return(BAD_FORM);
- movmem(buf, *pDest, srcRowBytes);
- buf += srcRowBytes;
- } else {
- /* Decompress row to destination plane.*/
-
- if ( UnPackRow(&buf, pDest, nFilled, srcRowBytes) )
- /* pSource, pDest, srcBytes, dstBytes */
- return(BAD_FORM);
- }
- }
- if (ni->Flags & NI_USEBITMAP) {
- if (ni->Flags & NI_CLIPIMAGE) {
- if (iRow >= ni->FTop &&
- iRow < ni->FTop + ni->Height) {
- BltBitMap (srcbm,
- ni->FLeft,
- 0,
- bitmap,
- ni->Left,
- ni->Top + iRow - ni->FTop,
- min(ni->Width, bmHdr->w), 1,
- 0xC0, 0xFF, NULL);
- }
- } else {
- BltBitMap (srcbm, 0, 0,
- bitmap, 0, iRow, bmHdr->w, 1,
- 0xC0, 0xFF, NULL);
- }
- } else {
- if (ni->Flags & NI_CLIPIMAGE) {
- if (iRow >= ni->FTop &&
- iRow < ni->FTop + ni->Height) {
- BltBitMapRastPort (srcbm,
- ni->FLeft,
- 0,
- rp,
- ni->Left,
- ni->Top + iRow - ni->FTop,
- ni->Width, 1,
- 0xC0, 0xFF, NULL);
- }
- } else {
- BltBitMapRastPort (srcbm, 0, 0,
- rp, 0, iRow, bmHdr->w, 1,
- 0xC0, 0xFF, NULL);
- }
- }
- }
- return(IFF_OKAY);
- }
-
-