home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / comm / misc / elcheapofax / rcs / iff2fax.c,v < prev    next >
Text File  |  1993-12-21  |  8KB  |  375 lines

  1. head    1.2;
  2. access;
  3. symbols
  4.     OCT93:1.2;
  5. locks;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.2
  10. date    93.06.11.16.33.37;    author Rhialto;    state Exp;
  11. branches;
  12. next    1.1;
  13.  
  14. 1.1
  15. date    93.06.11.14.53.53;    author Rhialto;    state Exp;
  16. branches;
  17. next    ;
  18.  
  19.  
  20. desc
  21. @Convert IFF ILBM to g3 files
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @First real RCS checkin
  28. @
  29. text
  30. @/*
  31.  * iff2fax.c
  32.  *
  33.  * Copyright (C) 1993 by Olaf 'Rhialto' Seibert. All rights reserved.
  34.  *
  35.  * $Id$
  36.  * $Log$
  37.  */
  38.  
  39. #include <stdlib.h>
  40.  
  41. #include "iffp/iff.h"
  42. #include "iffp/ilbm.h"
  43. #include "iffp/packer.h"
  44. #include "faxfile.h"
  45.  
  46. void           *IFFParseBase;
  47. struct ParseInfo ParseInfo;
  48. int        verbose;
  49. int        bodyskip;
  50. int        xoffset = 50;
  51. int        yoffset = 50;
  52. int        invert;
  53.  
  54. long props[] = { ID_ILBM, ID_BMHD, TAG_DONE };
  55. long stops[] = { ID_ILBM, ID_BODY, TAG_DONE };
  56.  
  57. /* Assumes malloc()ed pointer */
  58. void
  59. memor(unsigned char *d, unsigned char *s, int size)
  60. {
  61.     if (((long) d & 0x01) == 0) {
  62.     while (size >= 4) {
  63.         *(long *)d |= *(long *)s;
  64.         s += 4;
  65.         d += 4;
  66.         size -= 4;
  67.     }
  68.     }
  69.     while (size > 0) {
  70.     *d++ |= *s++;
  71.     size--;
  72.     }
  73. }
  74.  
  75. void
  76. meminvert(unsigned char *d, int size)
  77. {
  78.     if (((long) d & 0x01) == 0) {
  79.     while (size >= 4) {
  80.         *(long *)d ^= 0xFFFFFFFF;
  81.         d += 4;
  82.         size -= 4;
  83.     }
  84.     }
  85.     while (size > 0) {
  86.     *d++ ^= 0xFF;
  87.     size--;
  88.     }
  89. }
  90.  
  91. long
  92. dobody(struct ParseInfo *pi, void *faxp)
  93. {
  94.     BitMapHeader   *bmhd;
  95.     unsigned char  *plane1data,
  96.            *plane2data;
  97.     int         planedatasize;
  98.     int         bodydatabytes;
  99.     unsigned char  *bodydata,
  100.            *bodydata2;
  101.     int         bodydatasize;
  102.     int         bytexoffset;
  103.     int         line;
  104.     int         bodywidth;
  105.     int         plane;
  106.     int         maskplane = -1;
  107.     struct ContextNode *cn;
  108.     long        error;
  109.  
  110.     if (bodyskip) {
  111.     bodyskip--;
  112.     if (verbose)
  113.         printf("Skipping BODY.\n");
  114.     return 0;
  115.     }
  116.  
  117.     cn = CurrentChunk(pi->iff);
  118.     bmhd = (BitMapHeader *)findpropdata(pi->iff, ID_ILBM, ID_BMHD);
  119.     if (bmhd == NULL)
  120.     return IFFERR_MANGLED;
  121.  
  122.     error = 0;
  123.     /* Adjust for funny page sizes */
  124.     if (bmhd->pageWidth < bmhd->w)
  125.     bmhd->pageWidth = bmhd->w;
  126.     bmhd->pageWidth += bmhd->x + xoffset;
  127.     if (bmhd->pageWidth < LINE_BITS)
  128.     bmhd->pageWidth = LINE_BITS;
  129.     if (bmhd->pageHeight < bmhd->h)
  130.     bmhd->pageHeight = bmhd->h;
  131.     bmhd->pageHeight += bmhd->y + yoffset;
  132.     bodywidth = RowBytes(bmhd->w);
  133.     bytexoffset = (bmhd->x + xoffset + 7) / 8;
  134.  
  135.     if (bmhd->masking != mskNone) {
  136.     maskplane = bmhd->nPlanes++;
  137.     }
  138.  
  139.     if (verbose) {
  140.     printf("X: %d Y: %d W: %d H: %d Planes: %d\n",
  141.         bmhd->x, bmhd->y,
  142.         bmhd->w, bmhd->h,
  143.         bmhd->nPlanes);
  144.     }
  145.  
  146.     planedatasize = RowBytes(bmhd->pageWidth);
  147.     bodydatasize = 2048;    /* Arbitrary buffer size */
  148.  
  149.     plane1data = malloc(planedatasize + 4);
  150.     plane2data = malloc(planedatasize + 4);
  151.     bodydata = malloc(bodydatasize + 4);
  152.     bodydatabytes = 0;
  153.     if (plane1data == NULL || plane2data == NULL || bodydata == NULL) {
  154.     error = IFFERR_NOMEM;
  155.     goto fail;
  156.     }
  157.  
  158.     faxout_begin_page(faxp, 1);
  159.  
  160.     memset(bodydata, 0, bodydatasize);          /* not needed */
  161.  
  162.     if (yoffset) {
  163.     int        i;
  164.  
  165.     memset(plane1data, 0, planedatasize);
  166.     for (i = 0; i < yoffset; i++)
  167.         tofax(faxp, plane1data, bmhd->pageWidth);
  168.     }
  169.  
  170.     for (line = 0; line < bmhd->h; line++) {
  171.     memset(plane1data, 0, planedatasize);   /* not needed */
  172.     memset(plane2data, 0, planedatasize);
  173.  
  174.     for (plane = 0; plane < bmhd->nPlanes; plane++) {
  175.         /* Is the buffer half empty, and more data available? */
  176.         if (bodydatabytes <= (bodydatasize >> 1) &&
  177.         ChunkMoreBytes(cn)) {
  178.         /* Move remaining data to start of buffer */
  179.         memcpy(bodydata, bodydata2, bodydatabytes);
  180.         bodydata2 = bodydata;
  181.         error = ReadChunkBytes(pi->iff,
  182.                     bodydata + bodydatabytes,        /* buf */
  183.                     bodydatasize - bodydatabytes);  /* size */
  184.         if (error <= 0) {
  185.             fprintf(stderr, "Read: error %d\n", error);
  186.             faxout_end_page(faxp);
  187.             goto fail;
  188.         }
  189.         bodydatabytes += error;
  190.         }
  191.         if (bodydatabytes <= 0) {
  192.         error = IFFERR_MANGLED;
  193.         fprintf(stderr, "Out of data??\n");
  194.         faxout_end_page(faxp);
  195.         goto fail;
  196.         }
  197.         /* Uncompress to plane2data */
  198.         if (bmhd->compression == cmpNone) {
  199.         memcpy(plane2data, bodydata2 + bytexoffset, bodywidth);
  200.         bodydata2 += bodywidth;
  201.         bodydatabytes -= bodywidth;
  202.         } else {
  203.         unsigned char  *s, *d;
  204.  
  205.         s = bodydata2;
  206.         d = plane2data + bytexoffset;
  207.         UnPackRow(&bodydata2, &d,    bodydatabytes, bodywidth);
  208.             /* source      dest  source size    dest size */
  209.         bodydatabytes -= (bodydata2 - s);
  210.         }
  211.         /* OR this plane (plane2) with previous planes (plane1) */
  212.         if (plane == 0) {
  213.         memcpy(plane1data, plane2data, planedatasize);
  214.         } else if (plane != maskplane) {
  215.         memor(plane1data, plane2data, planedatasize);
  216.         }
  217.     } /* plane */
  218.     if (invert)
  219.         meminvert(plane1data + bytexoffset, bodywidth);
  220.  
  221.     tofax(faxp, plane1data, bmhd->pageWidth);
  222.     }
  223.     faxout_end_page(faxp);
  224.  
  225. fail:
  226.     if (plane1data)
  227.     free(plane1data);
  228.     if (plane2data)
  229.     free(plane2data);
  230.     if (bodydata)
  231.     free(bodydata);
  232.  
  233.     return error;
  234. }
  235.  
  236. long
  237. dofile(char *iffname, struct faxout *faxp)
  238. {
  239.     long        error;
  240.  
  241.     ParseInfo.iff = AllocIFF();
  242.     error = openifile(&ParseInfo, iffname, IFFF_READ);
  243.     if (error)
  244.     goto fail1;
  245.  
  246.     error = parseifile(&ParseInfo, ID_FORM, ID_ILBM, props, NULL, stops);
  247.     while (1) {
  248.     switch (error) {
  249.     case 0:     /* stop chunk (BODY). */
  250.         error = dobody(&ParseInfo, faxp);
  251.         break;
  252.     case IFFERR_EOC:
  253.         if (verbose) printf("End Of Context.\n");
  254.         break;
  255.     case IFFERR_EOF:
  256.         if (verbose) printf("EOF.\n");
  257.         goto eof;
  258.     default:
  259.         fprintf(stderr, "Iffparse error %d\n", error);
  260.         goto eof;
  261.     }
  262.     error = getcontext(ParseInfo.iff);
  263.     }
  264. eof:
  265.     closeifile(&ParseInfo);
  266. fail1:
  267.     FreeIFF(ParseInfo.iff);
  268.     ParseInfo.iff = NULL;
  269.  
  270.     return error;
  271. }
  272.  
  273. /*
  274.  * Clean up system stuff in case of exit
  275.  */
  276. void
  277. cleanup(void)
  278. {
  279.     if (IFFParseBase) {
  280.     if (ParseInfo.iff) {
  281.         closeifile(&ParseInfo);
  282.         FreeIFF(ParseInfo.iff);
  283.     }
  284.     CloseLibrary(IFFParseBase);
  285.     }
  286. }
  287.  
  288. int
  289. main(int argc, char **argv)
  290. {
  291.     char       *outfile = "ilbm.g3";
  292.     struct faxout  *faxp;
  293.     int         rawfax = 1;
  294.     int         append = 0;
  295.     extern char    *optarg;
  296.     extern int        optind;
  297.     extern int        getopt(int, char **, char *);
  298.     int         errflg = 0;
  299.     int         c;
  300.  
  301.     while ((c = getopt(argc, argv, "aio:rs:vx:y:")) != -1) {
  302.     switch (c) {
  303.     case 'a':
  304.         append = TRUE;
  305.         break;
  306.     case 'i':
  307.         invert = TRUE;
  308.         break;
  309.     case 'o':
  310.         outfile = optarg;
  311.         break;
  312.     case 'r':
  313.         rawfax++;
  314.         break;
  315.     case 's':
  316.         bodyskip = atoi(optarg);
  317.         break;
  318.     case 'v':
  319.         verbose = TRUE;
  320.         break;
  321.     case 'x':
  322.         xoffset = atoi(optarg);
  323.         break;
  324.     case 'y':
  325.         yoffset = atoi(optarg);
  326.         break;
  327.     case '?':
  328.         errflg++;
  329.         break;
  330.     }
  331.     }
  332.  
  333.     if (errflg || optind >= argc) {
  334.     printf(
  335. "Usage: iff2fax [-o fax-file (ilbm.g3)] [-r raw faxfile] [-a (append)]\n"
  336. "               [-sN skip N BODYs]\n"
  337. "               [-x/y x/y-offset (50)] [-v] [-i (invert)] iff-files\n");
  338.     exit(EXIT_FAILURE);
  339.     }
  340.  
  341.     atexit(cleanup);
  342.  
  343.     IFFParseBase = OpenLibrary("iffparse.library", 0);
  344.     if (IFFParseBase == NULL) {
  345.     printf("Needs iffparse.\n");
  346.     exit(10);
  347.     }
  348.  
  349.     faxp = faxout_open_fp(fopen(outfile, append? "ab": "wb"), rawfax);
  350.     if (faxp == NULL) {
  351.     fprintf(stderr, "can't open output file %s.\n", outfile);
  352.     goto fail;
  353.     }
  354.  
  355.     while (optind < argc) {
  356.     dofile(argv[optind], faxp);
  357.     optind++;
  358.     }
  359.  
  360.     faxout_close(faxp);
  361. fail:
  362.     /*CloseLibrary(IFFParseBase);*/
  363.     /* atexit function cleans up here */
  364. }
  365. @
  366.  
  367.  
  368. 1.1
  369. log
  370. @Initial revision
  371. @
  372. text
  373. @d5 3
  374. @
  375.