home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / applications / xlispstat / src / src1.lzh / Amiga / ilbmw.c < prev    next >
C/C++ Source or Header  |  1990-10-05  |  5KB  |  153 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. #include <iff/packer.h>
  12. #include <iff/ilbm.h>
  13. #include <intuition/intuition.h>
  14.  
  15. /*---------- InitBMHdr -------------------------------------------------*/
  16. IFFP InitBMHdr(bmHdr0,bitmap,masking,compression,transparentColor,
  17.                w,h,pageWidth,pageHeight)
  18. BitMapHeader *bmHdr0;  struct BitMap *bitmap;
  19. WORD masking;     /* Masking */
  20. WORD compression;     /* Compression */
  21. WORD transparentColor;   /* UWORD */
  22. WORD pageWidth, pageHeight;
  23. int w,h;{
  24.    register BitMapHeader *bmHdr=bmHdr0;
  25.    bmHdr->w=RowBytes(w)<<3;              /* even number of bytes */
  26.    bmHdr->h=h;
  27.    bmHdr->x=0;
  28.    bmHdr->y=0;
  29.    bmHdr->nPlanes=bitmap->Depth;
  30.    bmHdr->masking=masking;
  31.    bmHdr->compression=compression;
  32.    bmHdr->pad1=0;
  33.    bmHdr->transparentColor=transparentColor;
  34.    bmHdr->xAspect=bmHdr->yAspect=1;
  35.    bmHdr->pageWidth=pageWidth;
  36.    bmHdr->pageHeight=pageHeight;
  37.    if(pageWidth==320)
  38.       switch(pageHeight){
  39.          case 200: bmHdr->xAspect=x320x200Aspect;
  40.                    bmHdr->yAspect=y320x200Aspect; break;
  41.          case 400: bmHdr->xAspect=x320x400Aspect;
  42.                    bmHdr->yAspect=y320x400Aspect; break;}
  43.    else if(pageWidth==640)
  44.       switch(pageHeight){
  45.          case 200: bmHdr->xAspect=x640x200Aspect;
  46.                    bmHdr->yAspect=y640x200Aspect; break;
  47.          case 400: bmHdr->xAspect=x640x400Aspect;
  48.                    bmHdr->yAspect=y640x400Aspect; break;}
  49.    return(IS_ODD(w)?CLIENT_ERROR:IFF_OKAY);}
  50.  
  51. /*---------- PutCMAP ---------------------------------------------------*/
  52. IFFP PutCMAP(context,colorMap,depth)   
  53. GroupContext *context;
  54. WORD *colorMap;
  55. UBYTE depth;{
  56.    register LONG nColorRegs;   
  57.    IFFP iffp;
  58.    ColorRegister colorReg;
  59.    if(depth>MaxAmDepth)depth=MaxAmDepth;
  60.    nColorRegs=1<<depth;
  61.    iffp=PutCkHdr(context,ID_CMAP,nColorRegs*sizeofColorRegister);
  62.    CheckIFFP();
  63.    for(;nColorRegs;--nColorRegs){
  64.       colorReg.red=(*colorMap>>4)&0xf0;
  65.       colorReg.green=(*colorMap)&0xf0;
  66.       colorReg.blue =(*colorMap<<4)&0xf0;
  67.       iffp=IFFWriteBytes(context,(BYTE *)&colorReg,sizeofColorRegister);
  68.       CheckIFFP();
  69.       ++colorMap;}
  70.    iffp=PutCkEnd(context);
  71.    return(iffp);}
  72.  
  73. /*---------- PutBODY ---------------------------------------------------*/
  74. /* NOTE: This implementation could be a LOT faster if it used more of the
  75.  * supplied buffer. It would make far fewer calls to IFFWriteBytes (and
  76.  * therefore to DOS Write). */
  77.  
  78. IFFP PutBODY(window,context,bitmap,mask,bmHdr,buffer,bufsize)
  79. struct Window *window;
  80. GroupContext *context;
  81. struct BitMap *bitmap;
  82. BYTE *mask;
  83. BitMapHeader *bmHdr;
  84. BYTE *buffer;
  85. LONG bufsize;{         
  86.    IFFP iffp;
  87.    LONG rowBytes=bitmap->BytesPerRow,rstart,readrow,rb;
  88.    int dstDepth=bmHdr->nPlanes;
  89.    Compression compression=bmHdr->compression;
  90.    int planeCnt;      /* number of bit planes including mask */
  91.    register int iPlane,iRow,i,sh1,sh2,sh;
  92.    register LONG packedRowBytes;
  93.    BYTE *buf,*b;
  94.    unsigned char buf1[80];
  95.    BYTE *planes[MaxAmDepth + 1],*pl;   /* array of ptrs to planes & mask */
  96.    if(bufsize<MaxPackedSize(rowBytes)||   /* Must buffer a comprsd row*/
  97.         compression>cmpByteRun1||         /* bad arg */
  98. /*      bitmap->Rows!=bmHdr->h||             inconsistent */
  99. /*      rowBytes!=RowBytes(bmHdr->w)||       inconsistent*/
  100.         bitmap->Depth<dstDepth||          /* inconsistent */
  101.         dstDepth>MaxAmDepth)              /* too many for this routine*/
  102.    return(CLIENT_ERROR);
  103.    planeCnt=dstDepth+(mask==NULL?0:1);
  104.  
  105. /* Copy the ptrs to bit & mask planes into local array "planes" */
  106.  
  107.    for(iPlane=0;iPlane<dstDepth;iPlane++){
  108.       planes[iPlane]=(BYTE *)bitmap->Planes[iPlane];}
  109.    if(mask!=NULL)planes[dstDepth]=mask;
  110.  
  111.    readrow=RowBytes(bmHdr->w);
  112.    rb=(readrow<<3)-bmHdr->w;
  113.    rstart=(window->LeftEdge+bmHdr->x)>>3;
  114.    sh=(window->LeftEdge+bmHdr->x)%8;
  115.    sh2=rb-sh;
  116.    if(sh2<0)sh2+=16;
  117.    if(sh2<9)sh1=0;
  118.    else {
  119.       sh1=sh2-8; sh2=8;}
  120.  
  121. /* Write out a BODY chunk header */
  122.  
  123.    iffp=PutCkHdr(context,ID_BODY,szNotYetKnown);
  124.    CheckIFFP();
  125.  
  126. /* Write out the BODY contents */
  127.  
  128.    for(iRow=0;iRow<bmHdr->h;iRow++){
  129.       for(iPlane=0;iPlane<planeCnt;iPlane++){
  130.          
  131. /* Write next row.*/
  132.  
  133.          pl=planes[iPlane]+rowBytes*(iRow+window->TopEdge+bmHdr->y);
  134.          for(i=0;i<readrow;i++)buf1[i]=pl[i+rstart];
  135.          buf1[0]<<=sh; buf1[0]>>=sh;
  136.          buf1[readrow-2]>>=sh1; buf1[readrow-2]<<=sh1;
  137.          buf1[readrow-1]>>=sh2; buf1[readrow-1]<<=sh2;
  138.          if(compression==cmpNone){
  139.             iffp=IFFWriteBytes(context,buf1,readrow);}
  140.  
  141. /* Compress and write next row.*/
  142.  
  143.          else{
  144.             buf=buffer; b=&buf1[0];
  145.             packedRowBytes=PackRow(&b,&buf,readrow);
  146.             iffp=IFFWriteBytes(context,buffer,packedRowBytes);}
  147.          CheckIFFP();}}
  148.  
  149. /* Finish the chunk */
  150.  
  151.    iffp=PutCkEnd(context);
  152.    return(iffp);}
  153.