home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 375.lha / HAM-E_DEV_PACKAGE / iff.c < prev    next >
C/C++ Source or Header  |  1990-05-02  |  7KB  |  291 lines

  1. /*
  2.  * Dump rastport in IFF. Modified from matt Dillon's IFFENCODE program.
  3.  */
  4.  
  5. #include <exec/types.h>
  6. #include <exec/memory.h>
  7. #include <libraries/dos.h>
  8. #include <graphics/gfxbase.h>
  9. #include <graphics/rastport.h>
  10. #include <graphics/gfx.h>
  11. #include <graphics/view.h>
  12.  
  13. #include <intuition/intuition.h>
  14. #include <intuition/intuitionbase.h>
  15.  
  16. #define FLAG_NOCOMP  0x01
  17. #define FLAG_NOLACE  0x02
  18. #define FLAG_DEBUG   0x04
  19.  
  20. typedef struct Library        IBASE;
  21. typedef struct Library        GFXBASE;
  22. typedef struct Window         WIN;
  23. typedef struct Screen         SCR;
  24. typedef struct ViewPort       VP;
  25. typedef struct RastPort       RP;
  26. typedef struct ColorMap       CM;
  27. typedef struct BitMap         BM;
  28.  
  29. extern IBASE    *IntuitionBase;
  30. extern GFXBASE  *GraphicsBase;
  31.  
  32. extern int Ospeedsel,memsel;
  33.  
  34. extern struct Screen *scr;
  35.  
  36. USHORT Pulette[16];
  37.  
  38. #include "iff.h"
  39.  
  40. void Set_v_RGB4(vp,reg,red,green,blue)
  41.   struct ViewPort *vp;
  42.   int reg;
  43.   int red,green,blue;
  44.   {
  45.     /* this line updates the local color palette for IFF saves */
  46.     Pulette[reg] = (red << 8) + (green << 4) + (blue);
  47.     /* then we call setrgb4 like normal */
  48.     SetRGB4(vp,reg,red,green,blue);
  49.   }
  50.  
  51. void writeiff(name)
  52.   char *name;
  53.   {
  54.   long fi;
  55.     struct ColorMap cm;
  56.     cm.Flags=0;
  57.     cm.Type=0;     /* indicates that colormap is UWORDS */
  58.     cm.Count=16;   /* this many colors... */
  59.     cm.ColorTable = (APTR)&Pulette[0];
  60.     if (fi = xopen(&name[0],"w",8192))
  61.       {
  62.         xasync(fi, 1);
  63.         do_write(0,&scr->ViewPort,&cm,&scr->RastPort,fi);
  64.         xclose(fi);
  65.       }
  66.     else
  67.       {
  68.         printf("Unable to open '%s' for writing!\n",name);
  69.       }
  70.   }
  71.  
  72. /*
  73.  * flags = NULL;
  74.  * vp = ptr to ViewPort; cm = ptr to ColorMap; rp = ptr to RastPort, file
  75.  *
  76.  */
  77.  
  78. do_write(flags, vp, cm, rp, fi)
  79.   VP *vp;
  80.   CM *cm;
  81.   RP *rp;
  82.   long fi;
  83.     {
  84.       struct BitMap mybitmap;
  85.       BM *bm;
  86.       X_BMHD   x_bmhd;
  87.       X_CMAP   x_cmap[32];
  88.       X_CAMG   x_camg;
  89.       int cme, i, j;
  90.  
  91.       mybitmap = *((struct BitMap*)(rp->BitMap));
  92.       bm = &mybitmap;
  93.       x_bmhd.w                 = bm->BytesPerRow << 3;
  94.       x_bmhd.h                 = bm->Rows;
  95.       x_bmhd.x                 = x_bmhd.y = 0;
  96.       x_bmhd.planes            = bm->Depth;
  97.       x_bmhd.masking           = MA_NONE;
  98.       x_bmhd.compression       = (flags & FLAG_NOCOMP) ? CP_NONE : CP_BYTERUN1;
  99.       x_bmhd.transparent_color = 0;
  100.       x_bmhd.xaspect           = 10;
  101.       x_bmhd.yaspect           = 11;
  102.       x_bmhd.pagewidth         = x_bmhd.w;
  103.       x_bmhd.pageheight        = x_bmhd.h;
  104.  
  105.       j = 1 << x_bmhd.planes;
  106.  
  107.       if (j == 64) j = 32;
  108.       if (j > 32)
  109.         {
  110.           return(0);
  111.         }
  112.  
  113.         {
  114.         UWORD *w;
  115.           for (i = 0, w = (UWORD *)cm->ColorTable; i < j; ++i, ++w)
  116.             {
  117.               x_cmap[i][0] = ((*w >> 8) & 0x0F) << 4;
  118.               x_cmap[i][1] = ((*w >> 4) & 0x0F) << 4;
  119.               x_cmap[i][2] = ((*w) & 0x0F) << 4;
  120.             }
  121.           cme = j;
  122.         }
  123.  
  124.    x_camg.vpmodes = vp->Modes & (PFBA|DUALPF|HIRES|LACE|HAM);
  125.  
  126.    if ((flags & FLAG_NOLACE) && (x_camg.vpmodes & LACE))
  127.      {
  128.        x_camg.vpmodes &= ~LACE;
  129.        x_bmhd.h >>= 1;
  130.        x_bmhd.pageheight = x_bmhd.h; 
  131.      }
  132.  
  133.    iff_chunk(fi, IFF_FORM);
  134.    iff_type (fi, TYPE_ILBM);
  135.  
  136.       iff_chunk(fi, ILBM_BMHD);
  137.       xwrite(fi, &x_bmhd, sizeof(x_bmhd));
  138.       iff_chunk(fi, 0);
  139.  
  140.       iff_chunk(fi, ILBM_CMAP);
  141.       xwrite(fi, &x_cmap, sizeof(X_CMAP) * cme);
  142.       iff_chunk(fi, 0);
  143.  
  144.       iff_chunk(fi, ILBM_CAMG);
  145.       xwrite(fi, &x_camg, sizeof(x_camg));
  146.       iff_chunk(fi, 0);
  147.  
  148.       iff_chunk(fi, ILBM_BODY);
  149.       for (i = 0; ((i < x_bmhd.h) && (!checkbreak())); ++i)
  150.         {
  151.           for (j = 0; j < x_bmhd.planes; ++j)
  152.             {
  153.               dumprow(  fi,
  154.                         bm->Planes[j]+(i*bm->BytesPerRow),
  155.                         bm->BytesPerRow,
  156.                         flags  );
  157.             }
  158.         }
  159. outall:
  160.       iff_chunk(fi, 0);
  161.       iff_chunk(fi, 0);
  162.     }
  163.  
  164. /* fi    = special file pointer                   */
  165. /* ptr   = base of line to be written in bitplane */
  166. /* bytes = number of bytes in normal line         */
  167. /* flags = 0 for bare naked call                  */
  168.  
  169. dumprow(fi, ptr, bytes, flags)
  170.   int fi;
  171.   UBYTE *ptr;
  172.   int bytes,flags;
  173.   {
  174.   int i, j, k;            /* base, literal end, replicate end */
  175.   UBYTE ch;
  176.     if (flags & FLAG_NOCOMP)
  177.       {
  178.         return(xwrite(fi, ptr, bytes)); /* just write out the line bare */
  179.       }
  180.     if (flags & FLAG_DEBUG)
  181.       {
  182.         puts ("SCANLINE");
  183.       }
  184.     i = j = k = 0;
  185.     while (j < bytes)
  186.       {
  187.         if (checkbreak())
  188.           {
  189.             return(0);
  190.           }
  191.         for (k = j; k < bytes && ptr[j] == ptr[k]; ++k);
  192.         if (k - j >= 3)
  193.           {
  194.             while (j - i >= 128)
  195.               {
  196.                 ch = 127;
  197.                 xwrite(fi, &ch, 1);
  198.                 xwrite(fi, ptr + i, 128);
  199.                 i += 128;
  200.               }
  201.             if (j - i > 0)
  202.               {
  203.                 ch = (j - i - 1);
  204.                 xwrite(fi, &ch, 1);
  205.                 xwrite(fi, ptr + i, j - i);
  206.               }
  207.             while (k - j >= 128)
  208.               {
  209.                 ch = -127;
  210.                 xwrite(fi, &ch, 1);
  211.                 xwrite(fi, ptr + j, 1);
  212.                 j += 128;
  213.               }
  214.             if (k - j > 0)
  215.               {
  216.                 ch = -(k - j - 1);
  217.                 xwrite(fi, &ch, 1);
  218.                 xwrite(fi, ptr + j, 1);
  219.               }
  220.             i = j = k;
  221.           }
  222.         else
  223.           {
  224.             j = k;
  225.           }
  226.       }
  227.     /* NOTE: i=start  */
  228.     while (bytes - i >= 128)
  229.       {
  230.         ch = 127;
  231.         xwrite(fi, &ch, 1);
  232.         xwrite(fi, ptr + i, 128);
  233.         i += 128;
  234.       }
  235.     if (bytes - i > 0)
  236.       {
  237.         ch = (j - i - 1);
  238.         xwrite(fi, &ch, 1);
  239.         xwrite(fi, ptr + i, bytes - i);
  240.       }
  241.     /*
  242.     if (xseek(fi, 0, 0) & 1) {
  243.        ch = 0x80;
  244.        xwrite(fi, &ch, 1);
  245.     }
  246.     */
  247.     return (1);
  248.   }
  249.  
  250.  
  251. iff_type(fi, type)
  252.   {
  253.     xwrite(fi, &type, 4);
  254.     return(0);
  255.   }
  256.  
  257. iff_chunk(fi, type)
  258.   {
  259.   static long seeka[128];
  260.   static int idx;
  261.   long zero = 0;
  262.   long bytes;
  263.   long oldpos;
  264.  
  265.     if (type)
  266.       {
  267.         xwrite(fi, &type, 4);
  268.         xwrite(fi, &zero, 4);
  269.         seeka[idx++] = xseek(fi, 0, 0);
  270.       }
  271.     else
  272.       {
  273.         if (idx)
  274.           {
  275.             --idx;
  276.             oldpos = xseek(fi, 0, 0);
  277.             bytes = oldpos - seeka[idx];
  278.             if (oldpos & 1)
  279.               {
  280.                 xwrite(fi, &zero, 1);
  281.                 ++oldpos;
  282.               }
  283.             xseek(fi, seeka[idx] - 4, -1);
  284.             xwrite(fi, &bytes, 4);
  285.             xseek(fi, oldpos, -1);
  286.           }
  287.       }
  288.     return(0);
  289.   }
  290.  
  291.