home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / rayce27s / gif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-02  |  5.9 KB  |  296 lines

  1. /*
  2.  * gif.c -- read a gif file. scooped from the Linux gif viewer spic by
  3.  * Harm Hanemaayer <hhanemaa@cs.ruu.nl>
  4.  */
  5.  
  6. #include "ray.h"
  7. #include "proto.h"
  8. #include "extern.h"
  9. #include <string.h>
  10.  
  11.  
  12. /* Image data is raw byte(s)-per-pixel */
  13. PRIVATE char   *the_data;
  14.  
  15. #define __memcpy memcpy
  16. #define __memcpyb memcpy
  17.  
  18. #define byteindex  (bitindex >> 3)
  19. #define shift      (bitindex & 7)
  20.  
  21.  
  22. PRIVATE byte    buffer[258],
  23.                 rootsize,
  24.                 codesize;
  25. PRIVATE unsigned long blocklen,
  26.                 bitindex,
  27.                 code,
  28.                 old;
  29. PRIVATE byte    k;
  30. PRIVATE unsigned long mask,
  31.                 CC,
  32.                 EOI;
  33.  
  34. PRIVATE long    writebufferindex;
  35.  
  36. PRIVATE struct {
  37.     unsigned long   prefix;
  38.     unsigned long   k;
  39. }
  40.  
  41. codetable       [4096];
  42.  
  43. PRIVATE unsigned long tablelen;
  44.  
  45. PRIVATE void
  46. init_codetable()
  47. {
  48.     long            i;
  49.  
  50.     for (i = 0; i < CC; i++) {
  51.     codetable[i].prefix = 0xFFFF;
  52.     codetable[i].k = i;
  53.     }
  54.  
  55.     for (i = EOI + 1; i < 4096; i++) {
  56.     codetable[i].prefix = 0xFFFF;
  57.     codetable[i].k = 0;
  58.     }
  59.     tablelen = EOI + 1;
  60.     codesize = rootsize + 1;
  61.     mask = (1 << codesize) - 1;
  62. }
  63.  
  64. PRIVATE void
  65. reset_codetable()
  66. {
  67.     tablelen = EOI + 1;
  68.     codesize = rootsize + 1;
  69.     mask = (1 << codesize) - 1;
  70. }
  71.  
  72. PRIVATE char   *gifbuf;
  73.  
  74. PRIVATE void
  75. bread(char *b, long size, FILE * f)
  76. {
  77.     PRIVATE char   *bufp;
  78.     PRIVATE long    bufsize = 0;
  79.  
  80.     if (size > bufsize) {
  81.     long            count;
  82.  
  83.     if (bufsize)        /* copy remaining bytes to the front */
  84.         __memcpy(gifbuf, bufp, bufsize);
  85.     count = fread(gifbuf + bufsize, 1, BUFFERSIZE - bufsize, f);
  86.     bufsize += count;
  87.     bufp = gifbuf;
  88.     }
  89.     if (size == 1)
  90.     *b = *bufp;
  91.     else
  92.     __memcpy(b, bufp, size);
  93.     bufsize -= size;
  94.     bufp += size;
  95. }
  96.  
  97. PRIVATE void
  98. read_block(FILE * f)
  99. {
  100.     byte            count;
  101.  
  102.     bread(&count, 1, f);
  103.     bread(buffer + 2, count, f);
  104.     blocklen = count + 2;
  105. }
  106.  
  107. PRIVATE void
  108. get_string(unsigned long code, byte *s, unsigned long *len)
  109. {
  110.     unsigned long   i,
  111.                     j;
  112.     byte            stringbuf[4096];
  113.     long            stringlength;
  114.  
  115.     i = 1;
  116.     j = codetable[code].prefix;
  117.     stringbuf[0] = codetable[code].k;
  118.     s[0] = codetable[code].k;
  119.     while (j < 4096) {
  120.     stringbuf[i] = codetable[j].k;
  121.     j = codetable[j].prefix;
  122.     i++;
  123.     }
  124.     stringlength = i;
  125.  
  126.     /* reverse string */
  127.     while (i > 0) {
  128.     s[stringlength - i] = stringbuf[i - 1];
  129.     i--;
  130.     }
  131.     *len = stringlength;
  132. }
  133.  
  134. PRIVATE void
  135. output_string(byte *s, unsigned long len)
  136. {
  137.     __memcpyb(the_data + writebufferindex, s, len);
  138.  
  139.     writebufferindex += len * 1;/* one byte per pixel */
  140. }
  141.  
  142. PRIVATE void
  143. copystring(unsigned long code, unsigned long prefix, byte k)
  144. {
  145.     codetable[code].prefix = prefix;
  146.     codetable[code].k = k;
  147. }
  148.  
  149. PRIVATE void
  150. create_picture(FILE * f)
  151. {
  152.     long            quit;
  153.     byte            s[4096];
  154.     unsigned long   len;
  155.  
  156.     writebufferindex = 0;
  157.     fread(&rootsize, 1, 1, f);
  158.     CC = (1 << rootsize);
  159.     EOI = (1 << rootsize) + 1;
  160.     init_codetable();
  161.     read_block(f);
  162.     bitindex = 16 + codesize;    /* Skip first code.. should be CC */
  163.     quit = 0;
  164.  
  165.     for (;;) {
  166.     code = (unsigned long) (((*(unsigned long *) (buffer + byteindex)) >> shift) & mask);
  167.     bitindex += codesize;
  168.     if (code == CC)
  169.         reset_codetable();
  170.     else
  171.         output_string((byte *) (&code), 1);
  172.  
  173.     for (;;) {
  174.         if (bitindex + codesize >= blocklen * 8) {    /* New block */
  175.         bitindex -= (blocklen - 2) * 8;
  176.         *(short *) buffer = *(short *) (buffer + blocklen - 2);
  177.         read_block(f);
  178.         }
  179.         old = code;
  180.  
  181.         code = (unsigned long) (((*(unsigned long *) (buffer + byteindex)) >> shift) & mask);
  182.         bitindex += codesize;
  183.         if (code == CC) {
  184.         reset_codetable();
  185.         break;
  186.         }
  187.         if (code == EOI) {
  188.         quit = 1;
  189.         break;
  190.         }
  191.         if (code < tablelen) {    /* Code exists in table */
  192.         get_string(code, s, &len);
  193.         output_string(s, len);
  194.         k = s[0];
  195.         copystring(tablelen, old, k);
  196.         tablelen++;
  197.         } else {        /* Code does not yet exist */
  198.         get_string(old, s, &len);
  199.         k = s[0];
  200.         copystring(tablelen, old, k);
  201.         s[len++] = k;
  202.         output_string(s, len);
  203.         tablelen++;
  204.         }
  205.  
  206.         if ((tablelen == (1 << codesize)) && (codesize < 12)) {
  207.         codesize++;
  208.         mask = (1 << codesize) - 1;
  209.         }
  210.     }
  211.     if (quit)
  212.         break;
  213.     }
  214.  
  215. }
  216.  
  217.  
  218. /* load a gif into a pixmap data structure */
  219. PUBLIC void
  220. load_gif(struct pixel_data *image, FILE * f)
  221. {
  222.     size_t          s;
  223.     long            i,
  224.                     j;
  225.     char            buffer[256];
  226.     byte            c;
  227.     long            gct,
  228.                     gct_size,
  229.                     lct,
  230.                     lct_size;
  231.  
  232.     /* do buffering */
  233.     gifbuf = malloc(BUFFERSIZE * sizeof(char));
  234.  
  235.     CHECK_MEM(gifbuf, "gif buffer");
  236.  
  237.     /* Read Header */
  238.     fread(buffer, 6, 1, f);
  239.     if (memcmp(buffer, "GIF", 3))
  240.     errormsg("File not in GIF format.\n");
  241.  
  242.     /* Read Logical Screen Descriptor (LSD) */
  243.     fread(buffer, 7, 1, f);
  244.  
  245.     c = (byte) buffer[4];
  246.  
  247.     gct = buffer[4] & 128;    /* Global color table present ? */
  248.     gct_size = buffer[4] & 7;    /* Size of GCT */
  249.  
  250.     /* Read Image Descriptor */
  251.     if (gct) {            /* Skip GCT */
  252.     j = 2;
  253.     for (i = 0; i < gct_size; i++)
  254.         j *= 2;
  255.  
  256.     /* Palette data is 256 red, green and blue values (0-63) */
  257.     image->pal = (byte *) malloc(3 * j);
  258.     image->palsize = j;
  259.  
  260.     fread(image->pal, 3 * j, 1, f);
  261.     } else
  262.     image->palsize = 0;    /* is this ok? */
  263.  
  264.     fread(buffer, 10, 1, f);
  265.  
  266.     image->imagex = *(unsigned short *) (&(buffer[5]));
  267.     image->imagey = *(unsigned short *) (&(buffer[7]));
  268.  
  269.  
  270.     /* patch from spic 0.6 */
  271.     lct = buffer[9] & 128;    /* local color table present ? */
  272.     lct_size = buffer[9] & 7;    /* Size of LCT */
  273.     if (lct) {            /* Skip LCT */
  274.     j = 2;
  275.     if (lct_size > 0)
  276.         for (i = 0; i < lct_size; i++)
  277.         j *= 2;
  278.  
  279.     image->pal = (byte *) malloc(3 * j);
  280.     image->palsize = j;
  281.  
  282.     fread(image->pal, 3 * j, 1, f);
  283.     }
  284.     s = image->imagex * image->imagey;
  285.     the_data = (byte *) malloc(s);
  286.     CHECK_MEM(the_data, "gif pixels");
  287.  
  288.     create_picture(f);
  289.  
  290.     image->data = the_data;
  291.  
  292.     free(gifbuf);
  293. }
  294.  
  295. /* eof */
  296.