home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / dirs / dkbtrace_397.lzh / DKBTrace / DKBSource.LZH / gif.c < prev    next >
C/C++ Source or Header  |  1990-08-26  |  8KB  |  236 lines

  1. /*****************************************************************************
  2. *
  3. *                                     gif.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  Gif-format file reader.
  8. *
  9. *  NOTE:  Portions of this module were written by Steve Bennett and are used
  10. *         here with his permission.
  11. *
  12. * This software is freely distributable. The source and/or object code may be
  13. * copied or uploaded to communications services so long as this notice remains
  14. * at the top of each file.  If any changes are made to the program, you must
  15. * clearly indicate in the documentation and in the programs startup message
  16. * who it was who made the changes. The documentation should also describe what
  17. * those changes were. This software may not be included in whole or in
  18. * part into any commercial package without the express written consent of the
  19. * author.  It may, however, be included in other public domain or freely
  20. * distributed software so long as the proper credit for the software is given.
  21. *
  22. * This software is provided as is without any guarantees or warranty. Although
  23. * the author has attempted to find and correct any bugs in the software, he
  24. * is not responsible for any damage caused by the use of the software.  The
  25. * author is under no obligation to provide service, corrections, or upgrades
  26. * to this package.
  27. *
  28. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  29. * about them.  Also, if you have any comments or questions, you may contact me
  30. * at the following address:
  31. *
  32. *     David Buck
  33. *     22C Sonnet Cres.
  34. *     Nepean Ontario
  35. *     Canada, K2H 8W7
  36. *
  37. *  I can also be reached on the following bulleton boards:
  38. *
  39. *     ATX              (613) 526-4141
  40. *     OMX              (613) 731-3419
  41. *     Mystic           (613) 731-0088 or (613) 731-6698
  42. *
  43. *  Fidonet:   1:163/109.9
  44. *  Internet:  David_Buck@Carleton.CA
  45. *
  46. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  47. *
  48. *     Lattice BBS                      (708) 916-1200
  49. *     The Information Exchange BBS     (708) 945-5575
  50. *     Stillwaters BBS                  (708) 403-2826
  51. *
  52. *****************************************************************************/
  53.  
  54. /*
  55.    The following routines were borrowed freely from FRACTINT, and represent
  56.    a generalized GIF file decoder.  This seems the best, most universal format
  57.    for reading in Bitmapped images.  GIF is a Copyright of Compuserve, Inc.
  58.    Swiped and converted to entirely "C" coded routines by AAC for the most
  59.    in future portability!
  60. */
  61.  
  62. #include "frame.h"
  63. #include "dkbproto.h"
  64.  
  65. static IMAGE *Current_Image;  
  66. static int Bitmap_Line;
  67. static FILE *Bit_File;
  68. unsigned char *decoderline  /*  [2049] */ ;  /* write-line routines use this */
  69.  
  70. static IMAGE_COLOUR *gif_colour_map;
  71. static int colourmap_size;
  72.  
  73. int out_line (pixels, linelen)
  74.    unsigned char *pixels;
  75.    int linelen;
  76.    {
  77.    register int x;
  78.    register unsigned addr;
  79.  
  80.    addr = linelen * Bitmap_Line--;
  81.  
  82.    for (x = 0; x < linelen; x++) {
  83.       Current_Image->red[addr+x] = gif_colour_map[*pixels].Red;
  84.       Current_Image->green[addr+x] = gif_colour_map[*pixels].Green;
  85.       Current_Image->blue[addr+x] = gif_colour_map[*pixels].Blue;
  86.       pixels++;
  87.       }
  88.  
  89.    return (0);
  90.    }
  91.  
  92. #define READ_ERROR -1
  93.  
  94. int get_byte() /* get byte from file, return the next byte or an error */
  95.    {
  96.    register int byte;
  97.  
  98.    if ((byte = getc(Bit_File)) != EOF)
  99.       return (byte);
  100.    else {
  101.       printf ("Premature end of file reading GIF image\n");
  102.       exit (1);
  103.       }
  104.    return (0);  /* Keep the compiler happy */
  105.    }
  106.  
  107. /* Main GIF file decoder.  */
  108.  
  109. void read_gif_image(Image, filename)
  110.    IMAGE *Image;
  111.    char *filename;
  112.    {
  113.    register int i, j, status;
  114.    unsigned finished, planes;
  115.    unsigned char buffer[16];
  116.  
  117.    status = 0;
  118.    Current_Image = Image;
  119.  
  120.    if ((Bit_File = fopen(filename, "rb")) == NULL) {
  121.       printf ("Cannot open GIF file %s\n", filename);
  122.       exit(1);
  123.       }
  124.  
  125.    /* zero out the full write-line */
  126.    if ((decoderline = (unsigned char *) malloc (2049)) == NULL) {
  127.       printf ("Cannot allocate space for gif decoder line\n");
  128.       fclose (Bit_File);
  129.       exit (1);
  130.       }
  131.  
  132.    for (i = 0; i < 2049; i++)
  133.       decoderline[i] = (unsigned char) 0;
  134.  
  135.    /* Get the screen description */
  136.    for (i = 0; i < 13; i++)
  137.       buffer[i] = (unsigned char)get_byte();
  138.  
  139.    if (strncmp(buffer,"GIF87a",3) ||          /* use updated GIF specs */
  140.        buffer[3] < '0' || buffer[3] > '9' ||
  141.        buffer[4] < '0' || buffer[4] > '9' ||
  142.        buffer[5] < 'A' || buffer[5] > 'z' ) {
  143.  
  144.       printf ("Invalid GIF file format: %s\n", filename);
  145.       fclose(Bit_File);
  146.       exit (1);
  147.       }
  148.  
  149.    planes = ((unsigned)buffer[10] & 0x0F) + 1;
  150.    colourmap_size = (int)(1 << planes);
  151.    if ((gif_colour_map = (IMAGE_COLOUR *)
  152.          malloc (colourmap_size * sizeof (IMAGE_COLOUR))) == NULL) {
  153.       printf ("Cannot allocate gif colour map\n");
  154.       fclose (Bit_File);
  155.       exit (1);
  156.       }
  157.  
  158.    if ((buffer[10] & 0x80) == 0) {    /* color map (better be!) */
  159.       printf ("Invalid GIF file format: %s\n", filename);
  160.       fclose(Bit_File);
  161.       exit (1);
  162.       }
  163.  
  164.    for (i = 0; i < colourmap_size ; i++) {
  165.       gif_colour_map[i].Red = (unsigned char)get_byte();
  166.       gif_colour_map[i].Green = (unsigned char)get_byte();
  167.       gif_colour_map[i].Blue = (unsigned char)get_byte();
  168.       }
  169.  
  170.  /* Now display one or more GIF objects */
  171.    finished = FALSE;
  172.    while (!finished) {
  173.       switch (get_byte()) {
  174.          case ';':                /* End of the GIF dataset */
  175.             finished = TRUE;
  176.             status = 0;
  177.             break;
  178.  
  179.          case '!':                /* GIF Extension Block */
  180.             get_byte();           /* read (and ignore) the ID */
  181.             while ((i = get_byte()) > 0) /* get data len*/
  182.             for (j = 0; j < i; j++)
  183.                 get_byte(); /* flush data */
  184.             break;
  185.  
  186.          case ',': /* Start of image object. get description */
  187.             for (i = 0; i < 9; i++) {
  188.                if ((buffer[i] = (unsigned char)get_byte()) < 0) {
  189.                   status = -1;
  190.                   break;
  191.                   }
  192.                }
  193.  
  194.             if (status < 0) {
  195.                finished = TRUE;
  196.                break;
  197.                }
  198.  
  199.             Image->iwidth  = buffer[4] | (buffer[5] << 8);
  200.             Image->iheight = buffer[6] | (buffer[7] << 8);
  201.             Image->width = (DBL) Image->iwidth;
  202.             Image->height = (DBL) Image->iheight;
  203.  
  204.             if (Image->iwidth > BITMAP_X_SIZE ||
  205.                 Image->iheight > BITMAP_Y_SIZE) {
  206.                printf("\nBitmap File TOO BIG!!\n");
  207.                fclose(Bit_File);
  208.                exit (1);
  209.                }
  210.  
  211.             Bitmap_Line = Image->iheight - 1;
  212.  
  213.             if (((Image->red = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) ||
  214.                 ((Image->green = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) ||
  215.                 ((Image->blue = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL)) {
  216.                printf ("Cannot allocate memory for picture\n");
  217.                exit(1);
  218.                }
  219.  
  220.           /* Setup the color palette for the image */
  221.             status = decoder ((short) Image->iwidth); /*put bytes in Buf*/
  222.             finished = TRUE;
  223.             break;
  224.  
  225.          default:
  226.             status = -1;
  227.             finished = TRUE;
  228.             break;
  229.          }
  230.       }
  231.  
  232.    free (decoderline);
  233.    free (gif_colour_map);
  234.    fclose(Bit_File);
  235.    }
  236.