home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 274.lha / SimGen_Src / MYILBMR.c < prev    next >
C/C++ Source or Header  |  1989-07-26  |  7KB  |  252 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMR.C  Support routines for reading ILBM files.           11/27/85
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include <exec/memory.h>
  11. #include <graphics/rastport.h>
  12. #include <iff/packer.h>
  13. #include <iff/ilbm.h>
  14. #include <iff/readpict.h>
  15.  
  16. #include "picture.h"
  17. #include <mymacros.h>
  18.  
  19. /* ---------- GetCMAP ------------------------------------------------*/
  20. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  21.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  22. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
  23.     GroupContext    *ilbmContext;
  24.     WORD        *colorMap;
  25.     WORD        *pNColorRegs;
  26. {
  27.     register int    nColorRegs;   
  28.     register IFFP    iffp;
  29.     ColorRegister    colorReg;
  30.  
  31.     nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  32.     if (*pNColorRegs < nColorRegs) {
  33.         nColorRegs = *pNColorRegs;
  34.     }
  35.     *pNColorRegs = nColorRegs;    /* Set to the number actually there.*/
  36.  
  37.     for ( ;  nColorRegs > 0;  --nColorRegs)  {
  38.     iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
  39.     CheckIFFP();
  40.     *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
  41.               ( ( colorReg.green >> 4 ) << 4 ) |
  42.               ( ( colorReg.blue  >> 4 )      );
  43.     }
  44.     return(IFF_OKAY);
  45. }
  46.  
  47. /*---------- GetBODY ---------------------------------------------------*/
  48. /* NOTE: This implementation could be a LOT faster if it used more of the
  49.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  50.  * therefore to DOS Read) and to movemem. */
  51. IFFP GetBODY(context, ilbmframe, mask, buffer, bufsize, srcbm)
  52.     GroupContext    *context;
  53.     ILBMFrame    *ilbmframe;
  54.     BYTE        *mask;
  55.     BYTE        *buffer;
  56.     LONG        bufsize;
  57.     struct BitMap    *srcbm;
  58. {
  59.     register IFFP    iffp;
  60.     BitMapHeader    *bmHdr      = &ilbmframe->bmHdr;
  61.     UBYTE        srcPlaneCnt = bmHdr->nPlanes;
  62.     WORD        srcRowBytes = RowBytes(bmHdr->w);
  63.     LONG        bufRowBytes = MaxPackedSize(srcRowBytes);
  64.     int        nRows       = bmHdr->h;
  65.     Compression    compression = bmHdr->compression;
  66.     register int    iPlane, iRow, nEmpty;
  67.     register WORD    nFilled;
  68.     BYTE        *buf, *nullDest, *nullBuf, **pDest;
  69.     BYTE        *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  70.     long        gtemp;
  71.     NewImage    *ni         = ilbmframe->ni;
  72.     struct BitMap    *bitmap        = (struct BitMap *)ni->ImagePtr;
  73.     struct RastPort *rp         = (struct RastPort *)ni->ImagePtr;
  74.     BYTE        *gDest;
  75.  
  76. /**********************
  77.  **
  78.  ** Added for SimGen.
  79.  **
  80.  *********************/
  81.     AboutToLoadBody (ilbmframe);
  82.  
  83.     if (compression > cmpByteRun1)
  84.         return(CLIENT_ERROR);
  85.  
  86.    /*
  87.     *  if mode = CREATEPIC
  88.     *  Allocate and Initialize a bitmap for this picture
  89.     */
  90.  
  91.     if (ni->Flags & (NI_CREATEPIC | NI_CREATESHAPE)) {
  92.         int  i;
  93.         int  w;
  94.         int  h;
  95.  
  96.         if (ni->Flags & NI_CLIPIMAGE) {
  97.             w = ni->Width;
  98.             h = ni->Height;
  99.         } else {
  100.             w = bmHdr->w;
  101.             h = bmHdr->h;
  102.         }
  103.  
  104.         ni->Flags   |= NI_USEBITMAP;
  105.         bitmap       = &ilbmframe->pic->BitMap;
  106.         ni->ImagePtr = (APTR)bitmap;
  107.  
  108.         InitBitMap (bitmap, bmHdr->nPlanes, w, h);
  109.         for (i=0; i<bmHdr->nPlanes; i++) {
  110.             if (!( bitmap->Planes[i] = 
  111.                 (*ilbmframe->allocmem)(RASSIZE(w, h), MEMF_CHIP|MEMF_CLEAR))) {
  112.                 return (CLIENT_ERROR);
  113.                 }
  114.         }
  115.     } else {
  116.         if (!(ni->Flags & NI_USEBITMAP)) {
  117.             bitmap = rp->BitMap;
  118.         }
  119.     }
  120.  
  121.     /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  122.  
  123.     if (!ni->Flags & NI_CLIPIMAGE) {
  124.         if (srcPlaneCnt > MaxSrcPlanes ||
  125.             srcRowBytes > bitmap->BytesPerRow ||
  126.             nRows       > bitmap->Rows)
  127.             return (CLIENT_ERROR);
  128.     }
  129.  
  130.     /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  131.     for (iPlane = 0; iPlane < srcbm->Depth; iPlane++)
  132.         planes[iPlane] = (BYTE *)srcbm->Planes[iPlane];
  133.     for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  134.         planes[iPlane] = NULL;
  135.  
  136.     /* Copy any mask plane ptr into corresponding "planes" slot.*/
  137.     if (bmHdr->masking == mskHasMask) {
  138.         if (mask != NULL)
  139.             planes[srcPlaneCnt] = mask;
  140.             /* If there are more srcPlanes than
  141.              * dstPlanes, there will be NULL
  142.              * plane-pointers before this. */
  143.         else
  144.             planes[srcPlaneCnt] = NULL;
  145.             /* In case more dstPlanes than src.*/
  146.         srcPlaneCnt += 1;  /* Include mask plane in count.*/
  147.     }
  148.  
  149.     /* Setup a sink for dummy destination of rows from unwanted planes.*/
  150.     nullDest = buffer;
  151.     buffer  += srcRowBytes;
  152.     bufsize -= srcRowBytes;
  153.  
  154.     /* Read the BODY contents into client's bitmap.
  155.      * De-interleave planes and decompress rows.
  156.      * MODIFIES: Last iteration modifies bufsize.*/
  157.  
  158.     buf = buffer + bufsize;  /* Buffer is currently empty.*/
  159.     for (iRow = 0; iRow < nRows; iRow++)  {
  160.         for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  161.  
  162.             gDest = (BYTE *)srcbm->Planes[iPlane];
  163.             pDest = &gDest;
  164.  
  165.             /* Establish a sink for any unwanted plane.*/
  166.             if (*pDest == NULL) {
  167.                 nullBuf = nullDest;
  168.                 pDest   = &nullBuf;
  169.             }
  170.  
  171.             /* Read in at least enough bytes to
  172.                uncompress next row. */
  173.  
  174.             nEmpty  = buf - buffer;      /* size of empty part of buffer.*/
  175.             nFilled = bufsize - nEmpty;      /* this part has data.*/
  176.             if (nFilled < bufRowBytes) {
  177.                 /* Need to read more.*/
  178.  
  179.                 /* Move the existing data to the front of the buffer.*/
  180.                 /* Now covers range buffer[0]..buffer[nFilled-1].*/
  181.                 movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  182.  
  183.                 if (nEmpty > ChunkMoreBytes(context)) {
  184.                     /* There aren't enough bytes left to fill the buffer.*/
  185.                     nEmpty = ChunkMoreBytes(context);
  186.                     bufsize = nFilled + nEmpty;  /* heh-heh */
  187.                 }
  188.  
  189.                 /* Append new data to the existing data.*/
  190.                 iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
  191.                 CheckIFFP();
  192.     
  193.                 buf     = buffer;
  194.                 nFilled = bufsize;
  195.                 nEmpty  = 0;
  196.             }
  197.  
  198.             /* Copy uncompressed row to destination plane.*/
  199.             if (compression == cmpNone) {
  200.                 if (nFilled < srcRowBytes)  return(BAD_FORM);
  201.                 movmem(buf, *pDest, srcRowBytes);
  202.                 buf    += srcRowBytes;
  203.             } else {
  204.                 /* Decompress row to destination plane.*/
  205.  
  206.                 if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  207.                             /*  pSource, pDest, srcBytes, dstBytes  */
  208.                            return(BAD_FORM);
  209.             }
  210.         }
  211.         if (ni->Flags & NI_USEBITMAP) {
  212.             if (ni->Flags & NI_CLIPIMAGE) {
  213.                 if (iRow >= ni->FTop &&
  214.                     iRow < ni->FTop + ni->Height) {
  215.                     BltBitMap (srcbm,
  216.                         ni->FLeft,
  217.                         0,
  218.                         bitmap,
  219.                         ni->Left,
  220.                         ni->Top + iRow - ni->FTop,
  221.                         min(ni->Width, bmHdr->w), 1,
  222.                         0xC0, 0xFF, NULL);
  223.                 }
  224.             } else {
  225.                 BltBitMap (srcbm, 0, 0,
  226.                        bitmap, 0, iRow, bmHdr->w, 1,
  227.                        0xC0, 0xFF, NULL);
  228.             }
  229.         } else {
  230.             if (ni->Flags & NI_CLIPIMAGE) {
  231.                 if (iRow >= ni->FTop &&
  232.                     iRow < ni->FTop + ni->Height) {
  233.                     BltBitMapRastPort (srcbm,
  234.                         ni->FLeft,
  235.                         0,
  236.                         rp,
  237.                         ni->Left,
  238.                         ni->Top + iRow - ni->FTop,
  239.                         ni->Width, 1,
  240.                         0xC0, 0xFF, NULL);
  241.                 }
  242.             } else {
  243.                 BltBitMapRastPort (srcbm, 0, 0,
  244.                         rp, 0, iRow, bmHdr->w, 1,
  245.                         0xC0, 0xFF, NULL);
  246.             }
  247.         }
  248.     }
  249.     return(IFF_OKAY);
  250. }
  251.  
  252.