home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 609b.lha / MandelSquare_v1.3 / Source.LZH / Source / SaveILBM.c < prev    next >
C/C++ Source or Header  |  1992-01-05  |  10KB  |  449 lines

  1. /** Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf `Olsen' Barthel, all rights reserved
  4.  *
  5.  *    Name .....: SaveILBM.c
  6.  *    Created ..: Monday 26-Aug-91 11:20
  7.  *    Revision .: 1
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    26-Aug-91    Olsen        Created this file!
  12.  *
  13.  ***************************************************************************/
  14.  
  15.     /* This is basically Jim Kent's IFF-ILBM writer code as published
  16.      * in `Plop', with changes for iffparse.library and 32 bit viewmode
  17.      * CAMG chunks. I also added a version chunk to be saved with each
  18.      * image.
  19.      */
  20.  
  21. #define DUMP    0
  22. #define RUN    1
  23.  
  24. #define MINRUN    3
  25. #define MAXRUN    128
  26. #define MAXDAT    128
  27.  
  28. #define IFF_SIZE    4096
  29.  
  30. STATIC UBYTE    IFFBuffer[IFF_SIZE];
  31. STATIC WORD    IFFSize;
  32.  
  33. STATIC BYTE __regargs
  34. FlushIFF(struct IFFHandle *IFFHandle)
  35. {
  36.     if(IFFSize)
  37.     {
  38.         if(WriteChunkBytes(IFFHandle,IFFBuffer,IFFSize) != IFFSize)
  39.         {
  40.             IFFSize = 0;
  41.             return(FALSE);
  42.         }
  43.  
  44.         IFFSize = 0;
  45.     }
  46.  
  47.     return(TRUE);
  48. }
  49.  
  50. STATIC BYTE __regargs
  51. PutIFF(struct IFFHandle *IFFHandle,UBYTE c)
  52. {
  53.     if(IFFSize == IFF_SIZE)
  54.         if(!FlushIFF(IFFHandle))
  55.             return(FALSE);
  56.  
  57.     IFFBuffer[IFFSize++] = c;
  58.  
  59.     return(TRUE);
  60. }
  61.  
  62. STATIC BYTE __regargs
  63. WriteIFF(struct IFFHandle *IFFHandle,UBYTE *Data,LONG Size)
  64. {
  65.     LONG Len;
  66.  
  67.     while(Size)
  68.     {
  69.         if(IFFSize == IFF_SIZE)
  70.             if(!FlushIFF(IFFHandle))
  71.                 return(FALSE);
  72.  
  73.         if((Len = Size) > IFF_SIZE - IFFSize)
  74.             Len = IFF_SIZE - IFFSize;
  75.  
  76.         CopyMem(&Data[0],&IFFBuffer[IFFSize],Len);
  77.  
  78.         IFFSize    += Len;
  79.         Size    -= Len;
  80.  
  81.         Data = &Data[Len];
  82.     }
  83.  
  84.     return(TRUE);
  85. }
  86.  
  87. STATIC LONG __regargs
  88. PackRow(struct IFFHandle *FileHandle,UBYTE *Source,LONG Size)
  89. {
  90.     UBYTE    c,LastByte = 0,LineBuf[MAXDAT * 3 / 2];
  91.     BYTE    CompMode = DUMP;
  92.     WORD    InBuf = 1,RunStart = 0;
  93.     LONG     PutSize = 0;
  94.  
  95.     LineBuf[0] = LastByte = *Source++;
  96.  
  97.     Size--;
  98.  
  99.     for( ; Size ; --Size)
  100.     {
  101.         LineBuf[InBuf++] = c = *Source++;
  102.  
  103.         switch(CompMode)
  104.         {
  105.             case DUMP:    if(InBuf > MAXDAT)
  106.                     {
  107.                         if(!PutIFF(FileHandle,InBuf-2))
  108.                             return(FALSE);
  109.  
  110.                         if(!WriteIFF(FileHandle,LineBuf,InBuf-1))
  111.                             return(0);
  112.  
  113.                         PutSize += InBuf;
  114.                         LineBuf[0] = c;
  115.                         InBuf = 1;
  116.                         RunStart = 0;
  117.                         break;
  118.                     }
  119.  
  120.                     if(c == LastByte)
  121.                     {
  122.                         if(InBuf - RunStart >= MINRUN)
  123.                         {
  124.                             if(RunStart > 0)
  125.                             {
  126.                                 if(!PutIFF(FileHandle,RunStart-1))
  127.                                     return(FALSE);
  128.  
  129.                                 if(!WriteIFF(FileHandle,LineBuf,RunStart))
  130.                                     return(0);
  131.  
  132.                                 PutSize += RunStart+1;
  133.                             }
  134.  
  135.                             CompMode = RUN;
  136.                         }
  137.                         else
  138.                         {
  139.                             if(!RunStart)
  140.                                 CompMode = RUN;
  141.                         }
  142.                     }
  143.                     else
  144.                         RunStart = InBuf - 1;
  145.  
  146.                     break;
  147.  
  148.             case RUN:    if((c != LastByte) || (InBuf - RunStart > MAXRUN))
  149.                     {
  150.                         if(!PutIFF(FileHandle,-(InBuf - RunStart - 2)))
  151.                             return(FALSE);
  152.  
  153.                         if(!PutIFF(FileHandle,LastByte))
  154.                             return(FALSE);
  155.  
  156.                         PutSize += 2;
  157.  
  158.                         LineBuf[0] = c;
  159.                         InBuf = 1;
  160.                         RunStart = 0;
  161.                         CompMode = DUMP;
  162.                     }
  163.  
  164.                     break;
  165.         }
  166.  
  167.         LastByte = c;
  168.     }
  169.  
  170.     switch(CompMode)
  171.     {
  172.         case DUMP:    if(!PutIFF(FileHandle,InBuf-1))
  173.                     return(FALSE);
  174.  
  175.                 if(!WriteIFF(FileHandle,LineBuf,InBuf))
  176.                     return(FALSE);
  177.  
  178.                 PutSize += InBuf+1;
  179.                 break;
  180.  
  181.         case RUN:    if(!PutIFF(FileHandle,-(InBuf - RunStart - 1)))
  182.                     return(FALSE);
  183.  
  184.                 if(!PutIFF(FileHandle,LastByte))
  185.                     return(FALSE);
  186.  
  187.                 PutSize += 2;
  188.                 break;
  189.     }
  190.  
  191.     return(PutSize);
  192. }
  193.  
  194. STATIC LONG __regargs
  195. PackBitMap(struct IFFHandle *FileHandle,struct BitMap *BitMap,LONG Height)
  196. {
  197.     LONG i,j,RowLength,CompressedLength = 0,PlaneOffset = 0;
  198.  
  199.     for(i = 0 ; i < Height ; i++)
  200.     {
  201.         for(j = 0 ; j < BitMap -> Depth ; j++)
  202.         {
  203.             if(!(RowLength = PackRow(FileHandle,BitMap -> Planes[j] + PlaneOffset,BitMap -> BytesPerRow)))
  204.                 return(0);
  205.  
  206.             CompressedLength += RowLength;
  207.         }
  208.  
  209.         PlaneOffset += BitMap -> BytesPerRow;
  210.     }
  211.  
  212.     return(CompressedLength);
  213. }
  214.  
  215. STATIC BYTE __regargs
  216. WriteILBM(UBYTE *FileName,UBYTE *Colours,struct BitMap *BitMap,LONG OffsetX,BYTE OffsetY,LONG Width,LONG Height,LONG Compressed,LONG PageWidth,LONG PageHeight,ULONG ViewModes,struct MandelInfo *MandelInfo)
  217. {
  218.     struct IFFHandle    *FileHandle;
  219.     struct BitMapHeader     BitMapHeader;
  220.     LONG             RowOffset;
  221.     LONG             i,j;
  222.     WORD             NumColours = 32;
  223.     BYTE             Success = TRUE;
  224.  
  225.     if(BitMap)
  226.     {
  227.         if((NumColours = 1 << BitMap -> Depth) > 32)
  228.             NumColours = 32;
  229.  
  230.         if(ViewModes & HAM)
  231.             NumColours = 16;
  232.     }
  233.  
  234.     if(FileHandle = AllocIFF())
  235.     {
  236.         if(FileHandle -> iff_Stream = Open(FileName,MODE_NEWFILE))
  237.         {
  238.             InitIFFasDOS(FileHandle);
  239.  
  240.             if(!OpenIFF(FileHandle,IFFF_WRITE))
  241.             {
  242.                 if(!PushChunk(FileHandle,'ILBM','FORM',IFFSIZE_UNKNOWN))
  243.                 {
  244.                     BitMapHeader . masking        = 0;
  245.                     BitMapHeader . pad1        = 0;
  246.                     BitMapHeader . transparentColor    = 0;
  247.  
  248.                     if(Compressed)
  249.                         BitMapHeader . compression = 1;
  250.                     else
  251.                         BitMapHeader . compression = 0;
  252.  
  253.                     BitMapHeader . pageWidth    = PageWidth;
  254.                     BitMapHeader . pageHeight    = PageHeight;
  255.                     BitMapHeader . yAspect        = 11;
  256.  
  257.                     ViewModes &= ~(SPRITES | VP_HIDE | GENLOCK_AUDIO | GENLOCK_VIDEO);
  258.  
  259.                     if((ViewModes & HIRES) && (ViewModes & LACE))
  260.                         BitMapHeader . xAspect = 10;
  261.  
  262.                     if(!(ViewModes & HIRES) && (ViewModes & LACE))
  263.                         BitMapHeader . xAspect = 20;
  264.  
  265.                     if((ViewModes & HIRES) && !(ViewModes & LACE))
  266.                         BitMapHeader . xAspect = 5;
  267.  
  268.                     if(!(ViewModes & HIRES) && !(ViewModes & LACE))
  269.                         BitMapHeader . xAspect = 10;
  270.  
  271.                     if(BitMap)
  272.                     {
  273.                         BitMapHeader . w    = Width;
  274.                         BitMapHeader . h    = Height;
  275.                         BitMapHeader . nPlanes    = BitMap -> Depth;
  276.                         BitMapHeader . x    = OffsetX;
  277.                         BitMapHeader . y    = OffsetY;
  278.                     }
  279.  
  280.                     if(!PushChunk(FileHandle,0,'BMHD',IFFSIZE_UNKNOWN))
  281.                     {
  282.                         if(WriteChunkBytes(FileHandle,&BitMapHeader,sizeof(BitMapHeader)) == sizeof(BitMapHeader))
  283.                         {
  284.                             if(!PopChunk(FileHandle))
  285.                             {
  286.                                 if(!PushChunk(FileHandle,0,'CMAP',IFFSIZE_UNKNOWN))
  287.                                 {
  288.                                     if(WriteChunkBytes(FileHandle,Colours,3 * NumColours) == 3 * NumColours)
  289.                                     {
  290.                                         if(!PopChunk(FileHandle))
  291.                                         {
  292.                                             if(!PushChunk(FileHandle,0,'CAMG',IFFSIZE_UNKNOWN))
  293.                                             {
  294.                                                 if(WriteChunkBytes(FileHandle,&ViewModes,sizeof(ULONG)) == sizeof(ULONG))
  295.                                                 {
  296.                                                     if(!PopChunk(FileHandle))
  297.                                                     {
  298.                                                         if(!PushChunk(FileHandle,0,'MAND',IFFSIZE_UNKNOWN))
  299.                                                         {
  300.                                                             if(WriteChunkBytes(FileHandle,MandelInfo,sizeof(struct MandelInfo)) == sizeof(struct MandelInfo))
  301.                                                             {
  302.                                                                 if(!PopChunk(FileHandle))
  303.                                                                 {
  304.                                                                     if(!PushChunk(FileHandle,0,'ANNO',IFFSIZE_UNKNOWN))
  305.                                                                     {
  306.                                                                         extern UBYTE    VersTag[];
  307.                                                                         UBYTE        Len;
  308.  
  309.                                                                         Len = strlen(&VersTag[1]);
  310.  
  311.                                                                         if(WriteChunkBytes(FileHandle,&VersTag[1],Len) != Len)
  312.                                                                             Success = FALSE;
  313.                                                                         else
  314.                                                                         {
  315.                                                                             if(PopChunk(FileHandle))
  316.                                                                                 Success = FALSE;
  317.                                                                         }
  318.                                                                     }
  319.  
  320.                                                                     if(Success)
  321.                                                                     {
  322.                                                                         if(!PushChunk(FileHandle,0,'BODY',IFFSIZE_UNKNOWN))
  323.                                                                         {
  324.                                                                             if(Compressed)
  325.                                                                             {
  326.                                                                                 if(!PackBitMap(FileHandle,BitMap,Height))
  327.                                                                                     Success = FALSE;
  328.                                                                                 else
  329.                                                                                 {
  330.                                                                                     if(!FlushIFF(FileHandle))
  331.                                                                                         Success = FALSE;
  332.                                                                                 }
  333.                                                                             }
  334.                                                                             else
  335.                                                                             {
  336.                                                                                 i = Height;
  337.                                                                                 RowOffset = 0;
  338.  
  339.                                                                                 while(--i >= 0 && Success)
  340.                                                                                 {
  341.                                                                                     for(j = 0 ; j < BitMap -> Depth ; j++)
  342.                                                                                     {
  343.                                                                                         if(WriteChunkBytes(FileHandle,BitMap -> Planes[j] + RowOffset,Height) != Height)
  344.                                                                                         {
  345.                                                                                             Success = FALSE;
  346.                                                                                             break;
  347.                                                                                         }
  348.  
  349.                                                                                         RowOffset += BitMap -> BytesPerRow;
  350.                                                                                     }
  351.                                                                                 }
  352.                                                                             }
  353.     
  354.                                                                             if(PopChunk(FileHandle))
  355.                                                                                 Success = FALSE;
  356.                                                                         }
  357.                                                                     }
  358.                                                                     else
  359.                                                                         Success = FALSE;
  360.                                                                 }
  361.                                                                 else
  362.                                                                     Success = FALSE;
  363.                                                             }
  364.                                                             else
  365.                                                                 Success = FALSE;
  366.                                                         }
  367.                                                         else
  368.                                                             Success = FALSE;
  369.                                                     }
  370.                                                     else
  371.                                                         Success = FALSE;
  372.                                                 }
  373.                                                 else
  374.                                                     Success = FALSE;
  375.                                             }
  376.                                             else
  377.                                                 Success = FALSE;
  378.                                         }
  379.                                         else
  380.                                             Success = FALSE;
  381.                                     }
  382.                                     else
  383.                                         Success = FALSE;
  384.                                 }
  385.                                 else
  386.                                     Success = FALSE;
  387.                             }
  388.                             else
  389.                                 Success = FALSE;
  390.                         }
  391.                         else
  392.                             Success = FALSE;
  393.                     }
  394.                     else
  395.                         Success = FALSE;
  396.  
  397.                     if(PopChunk(FileHandle))
  398.                         Success = FALSE;
  399.                 }
  400.                 else
  401.                     Success = FALSE;
  402.             }
  403.             else
  404.                 Success = FALSE;
  405.  
  406.             Close(FileHandle -> iff_Stream);
  407.         }
  408.         else
  409.             Success = FALSE;
  410.  
  411.         FreeIFF(FileHandle);
  412.     }
  413.     else
  414.         Success = FALSE;
  415.  
  416.     return(Success);
  417. }
  418.  
  419. LONG
  420. SaveBitMap(struct BitMap *BitMap,struct ViewPort *VPort,LONG LeftEdge,LONG TopEdge,LONG Width,LONG Height,LONG ParentWidth,LONG ParentHeight,STRPTR Name,struct MandelInfo *MandelInfo)
  421. {
  422.     extern struct GfxBase    *GfxBase;
  423.  
  424.     UBYTE             ColTable[32 * 3];
  425.     LONG             IFF_Result,i,r,g,b;
  426.  
  427.     IFFSize = 0;
  428.  
  429.     for(i = 0 ; i < 32 ; i++)
  430.     {
  431.         UWORD TmpCol = GetRGB4(VPort -> ColorMap,i);
  432.  
  433.         r = (TmpCol >> 8) & 0xF;
  434.         g = (TmpCol >> 4) & 0xF;
  435.         b = (TmpCol     ) & 0xF;
  436.  
  437.         ColTable[i * 3 + 0] = r << 4;
  438.         ColTable[i * 3 + 1] = g << 4;
  439.         ColTable[i * 3 + 2] = b << 4;
  440.     }
  441.  
  442.     if(!(IFF_Result = WriteILBM(Name,ColTable,BitMap,LeftEdge,TopEdge,Width,Height,TRUE,ParentWidth,ParentHeight,GetVPModeID(VPort),MandelInfo)))
  443.         DeleteFile(Name);
  444.     else
  445.         SetProtection(Name,FIBF_EXECUTE);
  446.  
  447.     return(IFF_Result);
  448. }
  449.