home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 004.lha / Dpaintx_source / ilbmr.c < prev    next >
C/C++ Source or Header  |  1986-03-02  |  6KB  |  194 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMR.C  Support routines for reading ILBM files.           11/11/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.  *  ( expects packer.h and ilbm.h in include/iff/ )
  11.  *----------------------------------------------------------------------*/
  12. #include "exec/types.h"
  13. #include "iff/packer.h"
  14. #include "iff/ilbm.h"
  15.  
  16.  
  17. /* ---------- GetCMAP ------------------------------------------------*/
  18. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  19.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  20. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
  21.       GroupContext *ilbmContext;  WORD *colorMap;  UBYTE *pNColorRegs;
  22.    {
  23.    register int nColorRegs;   
  24.    register IFFP iffp;
  25.    ColorRegister colorReg;
  26.  
  27.    nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  28.    if (*pNColorRegs < nColorRegs)   nColorRegs = *pNColorRegs;
  29.    *pNColorRegs = nColorRegs;   /* Set to the number actually there.*/
  30.  
  31.    for ( ;  nColorRegs > 0;  --nColorRegs)  {
  32.       iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
  33.       CheckIFFP();
  34.       *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
  35.           ( ( colorReg.green >> 4 ) << 4 ) |
  36.           ( ( colorReg.blue  >> 4 )      );
  37.       }
  38.    return(IFF_OKAY);
  39.    }
  40.  
  41. /*---------- GetBODY ---------------------------------------------------*/
  42. /* NOTE: This implementation could be a LOT faster if it used more of the
  43.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  44.  * therefore to DOS Read) and to movemem. */
  45. IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  46.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  47.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  48.    {
  49.    register IFFP iffp;
  50.    UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
  51.    LONG srcRowBytes = RowBytes(bmHdr->w);
  52.    LONG bufRowBytes = MaxPackedSize(srcRowBytes);
  53.    int nRows = bmHdr->h;
  54.    Compression compression = bmHdr->compression;
  55.    register int iPlane, iRow, nEmpty, nFilled;
  56.    BYTE *buf, *nullDest, *nullBuf, **pDest;
  57.    BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  58.  
  59. #ifdef DALEDEBUG
  60.    printf("in GetBODY\n");
  61. #endif
  62.    if (compression > cmpByteRun1)
  63.       return(CLIENT_ERROR);
  64.  
  65.    /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  66.    if ( srcRowBytes  !=  bitmap->BytesPerRow  ||
  67.          bufsize < bufRowBytes * 2  ||
  68.          srcPlaneCnt > MaxSrcPlanes )
  69.       return(CLIENT_ERROR);
  70.  
  71.    if (nRows > bitmap->Rows)
  72.       nRows = bitmap->Rows;
  73. #ifdef DALEDEBUG
  74.    printf("GetBODY: initialize array planes\n");
  75. #endif
  76.    
  77.    /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  78.    for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
  79.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  80.    for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  81.       planes[iPlane] = NULL;
  82. #ifdef DALEDEBUG
  83.    printf("GetBODY: copy mask plane ptr\n");
  84. #endif
  85.  
  86.    /* Copy any mask plane ptr into corresponding "planes" slot.*/
  87.    if (bmHdr->masking == mskHasMask) {
  88.       if (mask != NULL)
  89.          planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
  90.                * dstPlanes, there will be NULL plane-pointers before this.*/
  91.       else
  92.          planes[srcPlaneCnt] = NULL;  /* In case more dstPlanes than src.*/
  93.       srcPlaneCnt += 1;  /* Include mask plane in count.*/
  94.       }
  95.  
  96.    /* Setup a sink for dummy destination of rows from unwanted planes.*/
  97.    nullDest = buffer;
  98.    buffer  += srcRowBytes;
  99.    bufsize -= srcRowBytes;
  100. #ifdef DALEDEBUG
  101.    printf("GetBODY: read body contents\n");
  102. #endif
  103.  
  104.    /* Read the BODY contents into client's bitmap.
  105.     * De-interleave planes and decompress rows.
  106.     * MODIFIES: Last iteration modifies bufsize.*/
  107.    buf = buffer + bufsize;  /* Buffer is currently empty.*/
  108.    for (iRow = nRows; iRow > 0; iRow--)  {
  109.       for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  110.  
  111.          pDest = &planes[iPlane];
  112.  
  113.          /* Establish a sink for any unwanted plane.*/
  114. #ifdef DALEDEBUG
  115.    printf("GetBODY:do sink pDest=%lx\n",pDest);
  116. #endif
  117.          if (*pDest == NULL) {
  118.        nullBuf = nullDest;
  119.             pDest   = &nullBuf;
  120.             }
  121.  
  122. #ifdef DALEDEBUG
  123.    printf("GetBODY:after sink\n");
  124. #endif
  125.  
  126.          /* Read in at least enough bytes to uncompress next row.*/
  127.          nEmpty  = buf - buffer;     /* size of empty part of buffer.*/
  128.          nFilled = bufsize - nEmpty;     /* this part has data.*/
  129.     if (nFilled < bufRowBytes) {
  130.        /* Need to read more.*/
  131. #ifdef DALEDEBUG
  132.    printf("GetBODY:need to read more\n");
  133. #endif
  134.  
  135.        /* Move the existing data to the front of the buffer.*/
  136.        /* Now covers range buffer[0]..buffer[nFilled-1].*/
  137. #ifdef DALEDEBUG
  138.    printf("GetBODY:movem(%lx,%lx,%lx)\n",buf, buffer, nFilled);
  139. #endif
  140.             movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  141.  
  142. #ifdef DALEDEBUG
  143.    printf("GetBODY:chunk more bytes\n");
  144. #endif
  145.             if (nEmpty > ChunkMoreBytes(context)) {
  146.                /* There aren't enough bytes left to fill the buffer.*/
  147.                nEmpty = ChunkMoreBytes(context);
  148.                bufsize = nFilled + nEmpty;  /* heh-heh */
  149.                }
  150.  
  151.        /* Append new data to the existing data.*/
  152. #ifdef DALEDEBUG
  153.    printf("GetBODY:IFFReadBytes\n");
  154. #endif
  155.             iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
  156. #ifdef DALEDEBUG
  157.    printf("GetBODY:CheckIFFP\n");
  158. #endif
  159.             CheckIFFP();
  160. #ifdef DALEDEBUG
  161.    printf("GetBODY:after CheckIFFP\n");
  162. #endif
  163.  
  164.             buf     = buffer;
  165.        nFilled = bufsize;
  166.        nEmpty  = 0;
  167.        }
  168.  
  169. #ifdef DALEDEBUG
  170.    printf("GetBODY:copy uncompressed\n");
  171. #endif
  172.          /* Copy uncompressed row to destination plane.*/
  173.          if (compression == cmpNone) {
  174.             if (nFilled < srcRowBytes)  return(BAD_FORM);
  175.        movmem(buf, *pDest, srcRowBytes);
  176.        buf    += srcRowBytes;
  177.             *pDest += srcRowBytes;
  178.             }
  179.     else
  180.          /* Decompress row to destination plane.*/
  181.             if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  182.                     /*  pSource, pDest, srcBytes, dstBytes  */
  183.                return(BAD_FORM);
  184.          }
  185.       }
  186.  
  187. #ifdef DALEDEBUG
  188.    printf("GetBODY: return\n");
  189. #endif
  190.  
  191.    return(IFF_OKAY);
  192.    }
  193.  
  194.