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