home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / giftoeps < prev    next >
Text File  |  1991-03-13  |  13KB  |  395 lines

  1.  
  2. /* received on jan 29, 1991 from
  3. Bob Boag                                BITNET:   boag@marshall
  4. Senior Software Systems Analyst         Internet: boag@marshall.wvnet.edu
  5. Marshall University Computer Center     Phone:    (304)696-2624
  6. Huntington, WV 25755-5320               FAX:      (304)696-3601
  7. */
  8.  
  9. /*********************************************
  10.  *                                           *
  11.  *  January 31, 1991 (not much) by John Gay  *
  12.  *                                           *
  13.  * rehacked so that either giftops or        *
  14.  * giftoeps could be compiled.  giftops is   *
  15.  * the default unless the symbol EPS is      *
  16.  * defined.                                  *
  17.  *                                           *
  18.  *********************************************
  19.  *             GIFtoEPS Converter            *
  20.  *                                           *
  21.  *      July 10, 1990  by David S. Joerg     *
  22.  *                                           *
  23.  * cc -DEPS -O -s -o giftoeps \              *
  24.  *                      giftoeps.c -lsys_s   *
  25.  * will give you a nice little 16K binary.   *
  26.  *********************************************
  27.  * If giftoeps does something wrong, you can *
  28.  * email me at... joerg@alliant.mcs.anl.gov  *
  29.  * but I probably won't be much help, I have *
  30.  * no idea whatsoever how this beast really  *
  31.  * works, beacause it's just an overly       *
  32.  * simpleminded kludge of...                 *
  33.  *********************************************
  34.  *             GIFtoPS Converter             *
  35.  *                                           *
  36.  *      May 16, 1988  by Scott Hemphill      *
  37.  *                                           *
  38.  * I wrote this program, and hereby place it *
  39.  * in the public domain, i.e. there are no   *
  40.  * copying restrictions of any kind.         *
  41.  *********************************************/
  42.  
  43. #include <stdio.h>
  44. char *malloc();
  45. int strncmp();
  46.  
  47. #define min(x,y) ((x) < (y) ? (x) : (y))
  48. #define FALSE 0
  49. #define TRUE 1
  50.  
  51. typedef int bool;
  52. typedef struct codestruct {
  53.             struct codestruct *prefix;
  54.             unsigned char first,suffix;
  55.         } codetype;
  56.  
  57. FILE *infile;
  58. unsigned int screenwidth;           /* The dimensions of the screen */
  59. unsigned int screenheight;          /*   (not those of the image)   */
  60. bool global;                        /* Is there a global color map? */
  61. int globalbits;                     /* Number of bits of global colors */
  62. unsigned char globalmap[256][3];    /* RGB values for global color map */
  63. char colortable[256][3];            /* Hex intensity strings for an image */
  64. unsigned char *raster;              /* Decoded image data */
  65. codetype *codetable;                /* LZW compression code data */
  66. int datasize,codesize,codemask;     /* Decoder working variables */
  67. int clear,eoi;                      /* Special code values */
  68.  
  69. void usage()
  70. {
  71. #ifdef EPS
  72.         fprintf(stderr,"usage: giftoeps input-file > output-file\n");
  73. #else
  74.         fprintf(stderr,"usage: giftops input-file > output-file\n");
  75. #endif
  76.         exit(-1);
  77. }
  78.  
  79. void fatal(s)
  80. char *s;
  81. {
  82. #ifdef EPS
  83.         fprintf(stderr,"giftoeps: %s\n",s);
  84. #else
  85.         fprintf(stderr,"giftops: %s\n",s);
  86. #endif
  87.         exit(-1);
  88. }
  89.  
  90. void checksignature()
  91. {
  92.         char buf[6];
  93.  
  94.         fread(buf,1,6,infile);
  95.         if (strncmp(buf,"GIF",3)) fatal("file is not a GIF file");
  96.         if (strncmp(&buf[3],"87a",3)) fatal("unknown GIF version number");
  97. }
  98.  
  99. /* Get information which is global to all the images stored in the file */
  100.  
  101. void readscreen()
  102. {
  103.         unsigned char buf[7];
  104.  
  105.         fread(buf,1,7,infile);
  106.         screenwidth = buf[0] + (buf[1] << 8);
  107.         screenheight = buf[2] + (buf[3] << 8);
  108.         global = buf[4] & 0x80;
  109.         if (global) {
  110.             globalbits = (buf[4] & 0x07) + 1;
  111.             fread(globalmap,3,1<<globalbits,infile);
  112.         }
  113. }
  114.  
  115. /* Convert a color map (local or global) to an array of two character
  116.    hexadecimal strings, stored in colortable.  RGB is converted to
  117.    8-bit grayscale using integer arithmetic. */
  118.  
  119. void initcolors(colortable,colormap,ncolors)
  120. char colortable[256][3];
  121. unsigned char colormap[256][3];
  122. int ncolors;
  123. {
  124.         static char hextab[] = {'0','1','2','3','4','5','6','7',
  125.                                 '8','9','A','B','C','D','E','F'};
  126.         register unsigned color;
  127.         register i;
  128.  
  129.         for (i = 0; i < ncolors; i++) {
  130.             color = 77*colormap[i][0] + 150*colormap[i][1] + 29*colormap[i][2];
  131.             color >>= 8;
  132.             colortable[i][0] = hextab[color >> 4];
  133.             colortable[i][1] = hextab[color & 15];
  134.             colortable[i][2] = '\0';
  135.         }
  136. }
  137.  
  138. /* Write a postscript header to the standard output.  Standard paper size
  139.    (8.5 by 11) is hard-coded, as is the whole initialization sequence.  */
  140. /* (DSJ) - Write an EPS header, try not to hardcode anything. */
  141.  
  142. void writeheader(left,top,width,height)
  143. unsigned left,top,width,height;
  144. {
  145. #ifndef EPS
  146.         double scale;
  147.         int scaledwidth,scaledheight;
  148.  
  149.         scale = min(648.0/screenwidth, 468.0/screenheight);
  150.         scaledwidth = (int)(scale*screenwidth+0.5);
  151.         scaledheight = (int)(scale*screenheight+0.5);
  152.  
  153.         printf("currentscreen /proc exch def /angle exch def /frequency exch def\n");
  154.         printf("/angle 90 def /frequency 60 def\n");
  155.         printf("frequency angle /proc load setscreen\n");
  156. #else
  157.         printf("%%!PS-Adobe-2.0 EPSF-2.0\n");
  158.         printf("%%%%Creator:giftoeps\n");
  159.         printf("%%%%BoundingBox: %f %f %f %f\n\n", 0.0, 0.0, (double)width, (double)height);
  160.         printf("currentscreen 3 1 roll pop pop 60 90 3 -1 roll setscreen\n");
  161. #endif
  162.         printf("/picstr %d string def\n",width);
  163.         printf("/screen {%d %d 8 [%d 0 0 -%d 0 %d]\n",width,height,width,height,height);
  164.         printf("   {currentfile picstr readhexstring pop} image} def\n");
  165. #ifdef EPS
  166.         printf("%d %d scale screen\n", width, height);
  167. #else
  168.         printf("%d %d translate 90 rotate %d %d scale screen\n",
  169.                306+(scaledheight>>1),396-(scaledwidth>>1),
  170.                scaledwidth, scaledheight);
  171. #endif
  172. }
  173.  
  174. /* Output the bytes associated with a code to the raster array */
  175.  
  176. void outcode(p,fill)
  177. register codetype *p;
  178. register unsigned char **fill;
  179. {
  180.         if (p->prefix) outcode(p->prefix,fill);
  181.         *(*fill)++ = p->suffix;
  182. }
  183.  
  184. /* Process a compression code.  "clear" resets the code table.  Otherwise
  185.    make a new code table entry, and output the bytes associated with the
  186.    code. */
  187.  
  188. void process(code,fill)
  189. register code;
  190. unsigned char **fill;
  191. {
  192.         static avail,oldcode;
  193.         register codetype *p;
  194.  
  195.         if (code == clear) {
  196.             codesize = datasize + 1;
  197.             codemask = (1 << codesize) - 1;
  198.             avail = clear + 2;
  199.             oldcode = -1;
  200.         } else if (code < avail) {
  201.             outcode(&codetable[code],fill);
  202.             if (oldcode != -1) {
  203.                 p = &codetable[avail++];
  204.                 p->prefix = &codetable[oldcode];
  205.                 p->first = p->prefix->first;
  206.                 p->suffix = codetable[code].first;
  207.                 if ((avail & codemask) == 0 && avail < 4096) {
  208.                     codesize++;
  209.                     codemask += avail;
  210.                 }
  211.             }
  212.             oldcode = code;
  213.         } else if (code == avail && oldcode != -1) {
  214.             p = &codetable[avail++];
  215.             p->prefix = &codetable[oldcode];
  216.             p->first = p->prefix->first;
  217.             p->suffix = p->first;
  218.             outcode(p,fill);
  219.             if ((avail & codemask) == 0 && avail < 4096) {
  220.                 codesize++;
  221.                 codemask += avail;
  222.             }
  223.             oldcode = code;
  224.         } else {
  225.             fatal("illegal code in raster data");
  226.         }
  227. }
  228.  
  229. /* Decode a raster image */
  230.  
  231. void readraster(width,height)
  232. unsigned width,height;
  233. {
  234.         unsigned char *fill = raster;
  235.         unsigned char buf[255];
  236.         register bits=0;
  237.         register unsigned count,datum=0;
  238.         register unsigned char *ch;
  239.         register int code;
  240.  
  241.         datasize = getc(infile);
  242.         clear = 1 << datasize;
  243.         eoi = clear+1;
  244.         codesize = datasize + 1;
  245.         codemask = (1 << codesize) - 1;
  246.         codetable = (codetype*)malloc(4096*sizeof(codetype));
  247.         if (!codetable) fatal("not enough memory for code table");
  248.         for (code = 0; code < clear; code++) {
  249.             codetable[code].prefix = (codetype*)0;
  250.             codetable[code].first = code;
  251.             codetable[code].suffix = code;
  252.         }
  253.         for (count = getc(infile); count > 0; count = getc(infile)) {
  254.             fread(buf,1,count,infile);
  255.             for (ch=buf; count-- > 0; ch++) {
  256.                 datum += *ch << bits;
  257.                 bits += 8;
  258.                 while (bits >= codesize) {
  259.                     code = datum & codemask;
  260.                     datum >>= codesize;
  261.                     bits -= codesize;
  262.                     if (code == eoi) goto exitloop;  /* This kludge put in
  263.                                                         because some GIF files
  264.                                                         aren't standard */
  265.                     process(code,&fill);
  266.                 }
  267.             }
  268.         }
  269. exitloop:
  270.         if (fill != raster + width*height) fatal("raster has the wrong size");
  271.         free(codetable);
  272. }
  273.  
  274. /* Read a row out of the raster image and write it to the output file */
  275.  
  276. void rasterize(row,width)
  277. int row,width;
  278. {
  279.         register unsigned char *scanline;
  280.         register i;
  281.  
  282.         scanline = raster + row*width;
  283.         for (i = 0; i < width; i++) {
  284.             if (i % 40 == 0) printf("\n");  /* break line every 80 chars */
  285.             fputs(colortable[*scanline++],stdout);
  286.         }
  287.         printf("\n");
  288. }
  289.  
  290. /* write image trailer to standard output */
  291.  
  292. void writetrailer()
  293. {
  294.         printf("showpage\n");
  295. }
  296.  
  297. /* Read image information (position, size, local color map, etc.) and convert
  298.    to postscript. */
  299.  
  300. void readimage()
  301. {
  302.         unsigned char buf[9];
  303.         unsigned left,top,width,height;
  304.         bool local,interleaved;
  305.         char localmap[256][3];
  306.         int localbits;
  307.         int *interleavetable;
  308.         register row;
  309.         register i;
  310.  
  311.         fread(buf,1,9,infile);
  312.         left = buf[0] + (buf[1] << 8);
  313.         top = buf[2] + (buf[3] << 8);
  314.         width = buf[4] + (buf[5] << 8);
  315.         height = buf[6] + (buf[7] << 8);
  316.         local = buf[8] & 0x80;
  317.         interleaved = buf[8] & 0x40;
  318.         if (local) {
  319.             localbits = (buf[8] & 0x7) + 1;
  320.             fread(localmap,3,1<<localbits,infile);
  321.             initcolors(colortable,localmap,1<<localbits);
  322.         } else if (global) {
  323.             initcolors(colortable,globalmap,1<<globalbits);
  324.         } else {
  325.             fatal("no colormap present for image");
  326.         }
  327.         writeheader(left,top,width,height);
  328.         raster = (unsigned char*)malloc(width*height);
  329.         if (!raster) fatal("not enough memory for image");
  330.         readraster(width,height);
  331.         if (interleaved) {
  332.             interleavetable = (int*)malloc(height*sizeof(int));
  333.             if (!interleavetable) fatal("not enough memory for interleave table");
  334.             row = 0;
  335.             for (i = top; i < top+height; i += 8) interleavetable[i] = row++;
  336.             for (i = top+4; i < top+height; i += 8) interleavetable[i] = row++;
  337.             for (i = top+2; i < top+height; i += 4) interleavetable[i] = row++;
  338.             for (i = top+1; i < top+height; i += 2) interleavetable[i] = row++;
  339.             for (row = top; row < top+height; row++) rasterize(interleavetable[row],width);
  340.             free(interleavetable);
  341.         } else {
  342.             for (row = top; row < top+height; row++) rasterize(row,width);
  343.         }
  344.         free(raster);
  345.         writetrailer();
  346. }
  347.  
  348. /* Read a GIF extension block (and do nothing with it). */
  349.  
  350. void readextension()
  351. {
  352.         unsigned char code,count;
  353.         char buf[255];
  354.  
  355.         code = getc(infile);
  356.         while (count = getc(infile)) fread(buf,1,count,infile);
  357. }
  358.  
  359. main(argc,argv)
  360. int argc;
  361. char *argv[];
  362. {
  363.         int quit = FALSE;
  364.         char ch;
  365.  
  366.         if (argc != 2) usage();
  367.         infile = fopen(argv[1],"r");
  368.         if (!infile) {
  369. #ifdef EPS
  370.             perror("giftoeps");
  371. #else
  372.             perror("giftops");
  373. #endif
  374.             exit(-1);
  375.         }
  376.         checksignature();
  377.         readscreen();
  378.         do {
  379.             ch = getc(infile);
  380.             switch (ch) {
  381.                 case '\0':  break;  /* this kludge for non-standard files */
  382.                 case ',':   readimage();
  383.                             break;
  384.                 case ';':   quit = TRUE;
  385.                             break;
  386.                 case '!':   readextension();
  387.                             break;
  388.                 default:    fatal("illegal GIF block type");
  389.                             break;
  390.             }
  391.         } while (!quit);
  392. }
  393.  
  394.  
  395.