home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 011.lha / IFF / iffencode.c < prev    next >
C/C++ Source or Header  |  1986-11-10  |  8KB  |  366 lines

  1.  
  2. /*
  3.  * IFFENCODE
  4.  *
  5.  *        COMPILE W/ASTARTUP.OBJ and MY.LIB
  6.  *
  7.  * Grabs the highest screen and dumps it to a file in IFF.
  8.  *
  9.  * Screen-Finding routine taken from Carolyn's Printer Dump source.
  10.  *
  11.  *
  12.  */
  13.  
  14. #include <exec/types.h>
  15. #include <exec/memory.h>
  16. #include <libraries/dos.h>
  17. #include <graphics/gfxbase.h>
  18. #include <graphics/rastport.h>
  19. #include <graphics/gfx.h>
  20. #include <graphics/view.h>
  21.  
  22. #include <intuition/intuition.h>
  23. #include <intuition/intuitionbase.h>
  24.  
  25. #define FLAG_NOCOMP  0x01
  26. #define FLAG_NOLACE  0x02
  27. #define FLAG_DEBUG   0x04
  28.  
  29. typedef struct IntuitionBase  IBASE;
  30. typedef struct GfxBase        GFXBASE;
  31. typedef struct Window         WIN;
  32. typedef struct Screen         SCR;
  33. typedef struct ViewPort       VP;
  34. typedef struct RastPort       RP;
  35. typedef struct ColorMap       CM;
  36. typedef struct BitMap         BM;
  37.  
  38. IBASE    *IntuitionBase;
  39. GFXBASE  *GfxBase;
  40.  
  41. main(ac, av)
  42. char *av[];
  43. {
  44.    char notdone = 1;
  45.    char buf[80];
  46.    char flags = 0;
  47.    int i;
  48.    VP *vp;
  49.    RP *rp;
  50.    CM *cm;
  51.  
  52.    for (i = 1; i < ac; ++i) {
  53.       if (strcmp(av[i], "NOLACE") == 0)
  54.          flags |= FLAG_NOLACE;
  55.       else if (strcmp(av[i], "NOCOMP") == 0)
  56.          flags |= FLAG_NOCOMP;
  57.       else if (strcmp(av[i], "DEBUG") == 0)
  58.          flags |= FLAG_DEBUG;
  59.       else {
  60.          puts ("iffencode [NOLACE][NOCOMP]");
  61.          puts ("(c)1986 Matthew Dillon.  Public Domain V1.00");
  62.          puts ("");
  63.          puts ("NOLACE  -save only top half of screen if in interlace");
  64.          puts ("NOCOMP  -do NOT use BYTERUN1 compression");
  65.          exit(1);
  66.       }
  67.    }
  68.  
  69.    if ((IntuitionBase=(IBASE *)OpenLibrary("intuition.library",0)) == NULL)
  70.       cleanexit("Can't open Intuition.\n");
  71.    if ((GfxBase=(GFXBASE *)OpenLibrary("graphics.library",0)) == NULL)
  72.       cleanexit("Can't open Graphics.\nn");
  73.  
  74.    do_imopts(&vp, &cm, &rp);
  75.  
  76.    while(notdone) {
  77.       printf("\nSELECT: <W>rite, <N>ewImage, <Q>uit ?");
  78.       switch (getch()) {
  79.       case 'W':
  80.          printf ("\nWrite to file (leave blank to abort):");
  81.          gets(buf);
  82.          if (buf[0]) {
  83.             long fi = xopen(buf, "w", 8192);
  84.             if (fi) {
  85.                xasync(fi, 1);
  86.                do_write(flags, vp, cm, rp, fi);
  87.                xclose(fi);
  88.                if (checkbreak()) {
  89.                   puts ("*BREAK*, file deleted");
  90.                   resetbreak();
  91.                   DeleteFile(buf);
  92.                }
  93.                puts ("done");
  94.             } else {
  95.                puts ("could not open file");
  96.             }
  97.          }
  98.          break;
  99.       case 'N':
  100.          do_imopts(&vp, &cm, &rp);
  101.          break;
  102.       case 'Q':
  103.          notdone = 0;
  104.          break;
  105.       }
  106.    }
  107.    cleanup();
  108. }
  109.  
  110.  
  111.  
  112. do_imopts(r_vp, r_cm, r_rp)
  113. VP **r_vp;
  114. CM **r_cm;
  115. RP **r_rp;
  116. {
  117.    puts  ("Move Screens so Screen to grab is highest.");
  118.    printf("press <RET> when ready: ");
  119.    getch();
  120.    getPointers(r_vp, r_cm, r_rp);
  121. }
  122.  
  123.  
  124. getPointers(r_vp, r_cm, r_rp)
  125. VP **r_vp;
  126. CM **r_cm;
  127. RP **r_rp;
  128. {
  129.    SCR *firstscreen, *nextscreen, *highscreen;
  130.    int topEdge;
  131.  
  132.    Forbid();
  133.    firstscreen  = IntuitionBase->FirstScreen;
  134.    topEdge = 9999;
  135.    nextscreen = highscreen = firstscreen;
  136.    while(nextscreen) {
  137.       if(nextscreen->TopEdge < topEdge) {
  138.          topEdge = nextscreen->TopEdge;
  139.          highscreen = nextscreen;
  140.       }
  141.       nextscreen = nextscreen->NextScreen;
  142.    }
  143.    Permit();
  144.  
  145.    *r_vp = &(highscreen->ViewPort);
  146.    *r_cm = (*r_vp)->ColorMap;
  147.    *r_rp = &(highscreen->RastPort);
  148. }
  149.  
  150.  
  151. getch()
  152. {
  153.    char scr[80];
  154.    if (gets(scr)) {
  155.       if (scr[0] >= 'a' && scr[0] <= 'z')
  156.          scr[0] = scr[0] - 'a' + 'A';
  157.       return ((int)scr[0]);
  158.    }
  159.    return(' ');
  160. }
  161.  
  162. cleanexit(errMsg)
  163. char *errMsg;
  164. {
  165.    printf(errMsg);
  166.    cleanup();
  167.    exit(-1);
  168. }
  169.  
  170. cleanup()
  171. {
  172.    if (IntuitionBase)     CloseLibrary(IntuitionBase);
  173.    if (GfxBase)           CloseLibrary(GfxBase);
  174. }
  175.  
  176.  
  177. /*
  178.  * Dump rastport in IFF.
  179.  */
  180.  
  181.  
  182. #include "iff.h"
  183.  
  184. do_write(flags, vp, cm, rp, fi)
  185. VP *vp;
  186. CM *cm;
  187. RP *rp;
  188. long fi;
  189. {
  190.    BM *bm = rp->BitMap;
  191.    X_BMHD   x_bmhd;
  192.    X_CMAP   x_cmap[32];
  193.    X_CAMG   x_camg;
  194.    int cme, i, j;
  195.  
  196.    x_bmhd.w = bm->BytesPerRow << 3;
  197.    x_bmhd.h = bm->Rows;
  198.    x_bmhd.x = x_bmhd.y = 0;
  199.    x_bmhd.planes = bm->Depth;
  200.    x_bmhd.masking= MA_NONE;
  201.    x_bmhd.compression = (flags & FLAG_NOCOMP) ? CP_NONE : CP_BYTERUN1;
  202.    x_bmhd.transparent_color = 0;
  203.    x_bmhd.xaspect = 10;
  204.    x_bmhd.yaspect = 11;
  205.    x_bmhd.pagewidth = x_bmhd.w;
  206.    x_bmhd.pageheight= x_bmhd.h;
  207.  
  208.    j = 1 << x_bmhd.planes;
  209.  
  210.    if (j == 64)
  211.       j = 32;
  212.    if (j > 32) {
  213.       printf ("Illegal #colors/#planes: %ld/%ld\n", j, x_bmhd.planes);
  214.       return(0);
  215.    }
  216.  
  217.    {
  218.       UWORD *w;
  219.       for (i = 0, w = (UWORD *)cm->ColorTable; i < j; ++i, ++w) {
  220.          x_cmap[i][0] = ((*w >> 8) & 0x0F) << 4;
  221.          x_cmap[i][1] = ((*w >> 4) & 0x0F) << 4;
  222.          x_cmap[i][2] = ((*w) & 0x0F) << 4;
  223.       }
  224.       cme = j;
  225.    }
  226.  
  227.    x_camg.vpmodes = vp->Modes & (PFBA|DUALPF|HIRES|LACE|HAM);
  228.  
  229.    if ((flags & FLAG_NOLACE) && (x_camg.vpmodes & LACE)) {
  230.       x_camg.vpmodes &= ~LACE;
  231.       x_bmhd.h >>= 1;
  232.       x_bmhd.pageheight = x_bmhd.h;
  233.    }
  234.  
  235.    printf ("vpmode = (%ldx%ldx%ld) %8lx\n", x_bmhd.w, x_bmhd.h, x_bmhd.planes, x_camg.vpmodes);
  236.  
  237.    iff_chunk(fi, IFF_FORM);
  238.    iff_type (fi, TYPE_ILBM);
  239.  
  240.       iff_chunk(fi, ILBM_BMHD);
  241.       xwrite(fi, &x_bmhd, sizeof(x_bmhd));
  242.       iff_chunk(fi, 0);
  243.  
  244.       iff_chunk(fi, ILBM_CMAP);
  245.       xwrite(fi, &x_cmap, sizeof(X_CMAP) * cme);
  246.       iff_chunk(fi, 0);
  247.  
  248.       iff_chunk(fi, ILBM_CAMG);
  249.       xwrite(fi, &x_camg, sizeof(x_camg));
  250.       iff_chunk(fi, 0);
  251.  
  252.       iff_chunk(fi, ILBM_BODY);
  253.       for (i = 0; i < x_bmhd.h; ++i) {
  254.          for (j = 0; j < x_bmhd.planes; ++j) {
  255.             dumprow(fi, bm->Planes[j]+(i*bm->BytesPerRow), bm->BytesPerRow, flags);
  256.             if (checkbreak())
  257.                goto outall;
  258.          }
  259.       }
  260. outall:
  261.       iff_chunk(fi, 0);
  262.    iff_chunk(fi, 0);
  263. }
  264.  
  265.  
  266. dumprow(fi, ptr, bytes, flags)
  267. UBYTE *ptr;
  268. {
  269.    int i, j, k;            /* base, literal end, replicate end */
  270.    UBYTE ch;
  271.  
  272.    if (flags & FLAG_NOCOMP)
  273.       return(xwrite(fi, ptr, bytes));
  274.    if (flags & FLAG_DEBUG)
  275.       puts ("SCANLINE");
  276.    i = j = k = 0;
  277.    while (j < bytes) {
  278.       if (checkbreak())
  279.          return(0);
  280.       for (k = j; k < bytes && ptr[j] == ptr[k]; ++k);
  281.       if (k - j >= 3) {
  282.          while (j - i >= 128) {
  283.             ch = 127;
  284.             xwrite(fi, &ch, 1);
  285.             xwrite(fi, ptr + i, 128);
  286.             i += 128;
  287.          }
  288.          if (j - i > 0) {
  289.             ch = (j - i - 1);
  290.             xwrite(fi, &ch, 1);
  291.             xwrite(fi, ptr + i, j - i);
  292.          }
  293.  
  294.          while (k - j >= 128) {
  295.             ch = -127;
  296.             xwrite(fi, &ch, 1);
  297.             xwrite(fi, ptr + j, 1);
  298.             j += 128;
  299.          }
  300.  
  301.          if (k - j > 0) {
  302.             ch = -(k - j - 1);
  303.             xwrite(fi, &ch, 1);
  304.             xwrite(fi, ptr + j, 1);
  305.          }
  306.          i = j = k;
  307.       } else {
  308.          j = k;
  309.       }
  310.    }
  311.    /* NOTE: i=start  */
  312.    while (bytes - i >= 128) {
  313.       ch = 127;
  314.       xwrite(fi, &ch, 1);
  315.       xwrite(fi, ptr + i, 128);
  316.       i += 128;
  317.    }
  318.    if (bytes - i > 0) {
  319.       ch = (j - i - 1);
  320.       xwrite(fi, &ch, 1);
  321.       xwrite(fi, ptr + i, bytes - i);
  322.    }
  323.    /*
  324.    if (xseek(fi, 0, 0) & 1) {
  325.       ch = 0x80;
  326.       xwrite(fi, &ch, 1);
  327.    }
  328.    */
  329.    return (1);
  330. }
  331.  
  332.  
  333. iff_type(fi, type)
  334. {
  335.    xwrite(fi, &type, 4);
  336. }
  337.  
  338. iff_chunk(fi, type)
  339. {
  340.    static long seeka[128];
  341.    static int idx;
  342.    long zero = 0;
  343.    long bytes;
  344.    long oldpos;
  345.  
  346.    if (type) {
  347.       xwrite(fi, &type, 4);
  348.       xwrite(fi, &zero, 4);
  349.       seeka[idx++] = xseek(fi, 0, 0);
  350.    } else {
  351.       if (idx) {
  352.          --idx;
  353.          oldpos = xseek(fi, 0, 0);
  354.          bytes = oldpos - seeka[idx];
  355.          if (oldpos & 1) {
  356.             xwrite(fi, &zero, 1);
  357.             ++oldpos;
  358.          }
  359.          xseek(fi, seeka[idx] - 4, -1);
  360.          xwrite(fi, &bytes, 4);
  361.          xseek(fi, oldpos, -1);
  362.       }
  363.    }
  364. }
  365.  
  366.