home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 523b.lha / Drawmap_v2.25d / Sources.LZH / Sources / ilbmw.c < prev    next >
C/C++ Source or Header  |  1991-06-10  |  5KB  |  155 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMW.C  Support routines for writing ILBM files.            1/23/86
  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. #define FDwAT
  11. #ifdef LATTICE
  12. #include "proto/dos.h"
  13. #endif
  14. #include "iff/packer.h"
  15. #include "iff/ilbm.h"
  16. #include "iffw.c"
  17. #include "packer.c"
  18. /*---------- InitBMHdr -------------------------------------------------*/
  19. IFFP InitBMHdr(bmHdr, bitmap, masking, compression, transparentColor,
  20.             pageWidth, pageHeight)
  21.         BitMapHeader *bmHdr; struct BitMap *bitmap;
  22.         int masking;           /* Masking */
  23.         int compression;       /* Compression */
  24.         int transparentColor;  /* UWORD */
  25.         WORD pageWidth, pageHeight;
  26.     {
  27.     WORD rowBytes = bitmap->BytesPerRow;
  28.  
  29.     bmHdr->w = rowBytes << 3;
  30.     bmHdr->h = bitmap->Rows;
  31.     bmHdr->x = bmHdr->y = 0;    /* Default position is (0,0).*/
  32.     bmHdr->nPlanes = bitmap->Depth;
  33.     bmHdr->masking = masking;
  34.     bmHdr->compression = compression;
  35.     bmHdr->pad1 = 0;
  36.     bmHdr->transparentColor = transparentColor;
  37.     bmHdr->xAspect = bmHdr->yAspect = 1;
  38.     bmHdr->pageWidth = pageWidth;
  39.     bmHdr->pageHeight = pageHeight;
  40.  
  41.     if (pageWidth = 320)
  42.         switch (pageHeight) {
  43.             case 200: {bmHdr->xAspect = x320x200Aspect;
  44.                        bmHdr->yAspect = y320x200Aspect; break;}
  45.             case 400: {bmHdr->xAspect = x320x400Aspect;
  46.                        bmHdr->yAspect = y320x400Aspect; break;}
  47.             }
  48.     else if (pageWidth = 640)
  49.         switch (pageHeight) {
  50.             case 200: {bmHdr->xAspect = x640x200Aspect;
  51.                        bmHdr->yAspect = y640x200Aspect; break;}
  52.             case 400: {bmHdr->xAspect = x640x400Aspect;
  53.                        bmHdr->yAspect = y640x400Aspect; break;}
  54.             }
  55.  
  56.     return( IS_ODD(rowBytes) ? CLIENT_ERROR : IFF_OKAY );
  57.     }
  58.  
  59. /*---------- PutCMAP ---------------------------------------------------*/
  60. IFFP PutCMAP(context, colorMap, depth)
  61.       GroupContext *context;  WORD *colorMap;  UBYTE depth;
  62.    {
  63.    LONG nColorRegs;
  64.    IFFP iffp;
  65.    ColorRegister colorReg;
  66.  
  67.    if (depth > MaxAmDepth)   depth = MaxAmDepth;
  68.    nColorRegs = 1 << depth;
  69.  
  70.    iffp = PutCkHdr(context, ID_CMAP, nColorRegs * sizeofColorRegister);
  71.    CheckIFFP();
  72.  
  73.    for ( ;  nColorRegs;  --nColorRegs)  {
  74.       colorReg.red   = ( *colorMap >> 4 ) & 0xf0;
  75.       colorReg.green = ( *colorMap      ) & 0xf0;
  76.       colorReg.blue  = ( *colorMap << 4 ) & 0xf0;
  77.       iffp = IFFWriteBytes(context, (BYTE *)&colorReg, sizeofColorRegister);
  78.       CheckIFFP();
  79.       ++colorMap;
  80.       }
  81.  
  82.    iffp = PutCkEnd(context);
  83.    return(iffp);
  84.    }
  85.  
  86. /*---------- PutBODY ---------------------------------------------------*/
  87. /* NOTE: This implementation could be a LOT faster if it used more of the
  88.  * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
  89.  * therefore to DOS Write). */
  90. IFFP PutBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  91.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  92.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  93.    {
  94.    IFFP iffp;
  95.    LONG rowBytes = bitmap->BytesPerRow;
  96.    int dstDepth = bmHdr->nPlanes;
  97.    Compression compression = bmHdr->compression;
  98.    int planeCnt;                /* number of bit planes including mask */
  99.    int iPlane, iRow;
  100.    LONG packedRowBytes;
  101.    BYTE *buf;
  102.    BYTE *planes[MaxAmDepth + 1]; /* array of ptrs to planes & mask */
  103.  
  104.    if ( bufsize < MaxPackedSize(rowBytes)  ||   /* Must buffer a comprsd row*/
  105.         compression > cmpByteRun1  ||           /* bad arg */
  106.         rowBytes != RowBytes(bmHdr->w)  ||      /* inconsistent*/
  107.         bitmap->Depth < dstDepth   ||           /* inconsistent */
  108.         dstDepth > MaxAmDepth )                 /* too many for this routine*/
  109.       return(CLIENT_ERROR);
  110.  
  111.    planeCnt = dstDepth + (mask == NULL ? 0 : 1);
  112.  
  113.    /* Copy the ptrs to bit & mask planes into local array "planes" */
  114.    for (iPlane = 0; iPlane < dstDepth; iPlane++){
  115.         planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  116.         /* add offset to get to correct bmHdr Y position*/
  117.         planes[iPlane] += rowBytes*bmHdr->y;
  118.         /* add offset to get to X pos. at BYTE boundary
  119.              (i.e. at next even multiple of 8) */
  120.         planes[iPlane] += (bmHdr->x)/8;
  121.         }
  122.    if (mask != NULL)
  123.       planes[dstDepth] = mask;
  124.  
  125.    /* Write out a BODY chunk header */
  126.    iffp = PutCkHdr(context, ID_BODY, szNotYetKnown);
  127.    CheckIFFP();
  128.  
  129.  
  130.    /* Write out the BODY contents */
  131.    for (iRow = bmHdr->h; iRow > 0; iRow--)  {
  132.       for (iPlane = 0; iPlane < planeCnt; iPlane++)  {
  133.  
  134.          /* Write next row.*/
  135.          if (compression == cmpNone) {
  136.             iffp = IFFWriteBytes(context, planes[iPlane], rowBytes);
  137.             planes[iPlane] += rowBytes;
  138.             }
  139.  
  140.          /* Compress and write next row.*/
  141.          else {
  142.             buf = buffer;
  143.             packedRowBytes = PackRow(&planes[iPlane], &buf, rowBytes);
  144.             iffp = IFFWriteBytes(context, buffer, packedRowBytes);
  145.             }
  146.  
  147.          CheckIFFP();
  148.          }
  149.       }
  150.  
  151.    /* Finish the chunk */
  152.    iffp = PutCkEnd(context);
  153.    return(iffp);
  154.    }
  155.