home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / gfx / dkb212sr.lzh / gif.c < prev    next >
C/C++ Source or Header  |  1991-04-30  |  8KB  |  242 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. *     OMX              (613) 731-3419
  40. *     Mystic           (613) 596-4249  or  (613) 596-4772
  41. *
  42. *  Fidonet:   1:163/109.9
  43. *  Internet:  dbuck@ccs.carleton.ca
  44. *  The "You Can Call Me RAY" BBS    (708) 358-5611
  45. *
  46. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  47. *
  48. *     The "You Can Call Me RAY" BBS (708) 358-5611
  49. *     The Information Exchange BBS  (708) 945-5575
  50. *
  51. *****************************************************************************/
  52.  
  53. /*
  54.    The following routines were borrowed freely from FRACTINT, and represent
  55.    a generalized GIF file decoder.  This seems the best, most universal format
  56.    for reading in Bitmapped images.  GIF is a Copyright of Compuserve, Inc.
  57.    Swiped and converted to entirely "C" coded routines by AAC for the most
  58.    in future portability!
  59. */
  60.  
  61. #include "frame.h"
  62. #include "dkbproto.h"
  63.  
  64. static IMAGE *Current_Image;  
  65. static int Bitmap_Line;
  66. static FILE *Bit_File;
  67. unsigned char *decoderline  /*  [2049] */ ;  /* write-line routines use this */
  68.  
  69. static IMAGE_COLOUR *gif_colour_map;
  70. static int colourmap_size;
  71.  
  72. int out_line (pixels, linelen)
  73.    unsigned char *pixels;
  74.    int linelen;
  75.    {
  76.    register int x;
  77.    register unsigned char *line;
  78.  
  79.    line = Current_Image->data.map_lines[Bitmap_Line++];
  80.  
  81.    for (x = 0; x < linelen; x++) {
  82.       if ((int)(*pixels) > Current_Image->Colour_Map_Size) {
  83.          fprintf (stderr, "Error - GIF Image Map Colour out of range\n");
  84.          exit(1);
  85.       }
  86.  
  87.       line[x] = *pixels;
  88.       pixels++;
  89.       }
  90.  
  91.    return (0);
  92.    }
  93.  
  94. #define READ_ERROR -1
  95.  
  96. int get_byte() /* get byte from file, return the next byte or an error */
  97.    {
  98.    register int byte;
  99.  
  100.    if ((byte = getc(Bit_File)) != EOF)
  101.       return (byte);
  102.    else {
  103.       fprintf (stderr, "Premature End Of File reading GIF image\n");
  104.       exit (1);
  105.       }
  106.    return (0);  /* Keep the compiler happy */
  107.    }
  108.  
  109. /* Main GIF file decoder.  */
  110.  
  111. void Read_Gif_Image(Image, filename)
  112.    IMAGE *Image;
  113.    char *filename;
  114.    {
  115.    register int i, j, status;
  116.    unsigned finished, planes;
  117.    unsigned char buffer[16];
  118.  
  119.    status = 0;
  120.    Current_Image = Image;
  121.  
  122.    if ((Bit_File = Locate_File(filename, "rb")) == NULL) {
  123.       fprintf (stderr, "Cannot open GIF file %s\n", filename);
  124.       exit(1);
  125.       }
  126.  
  127.    /* zero out the full write-line */
  128.    if ((decoderline = (unsigned char *) malloc (2049)) == NULL) {
  129.       fprintf (stderr, "Cannot allocate space for GIF decoder line\n");
  130.       fclose (Bit_File);
  131.       exit (1);
  132.       }
  133.  
  134.    for (i = 0; i < 2049; i++)
  135.       decoderline[i] = (unsigned char) 0;
  136.  
  137.    /* Get the screen description */
  138.    for (i = 0; i < 13; i++)
  139.       buffer[i] = (unsigned char)get_byte();
  140.  
  141.    if (strncmp((char *) buffer,"GIF",3) ||          /* use updated GIF specs */
  142.        buffer[3] < '0' || buffer[3] > '9' ||
  143.        buffer[4] < '0' || buffer[4] > '9' ||
  144.        buffer[5] < 'A' || buffer[5] > 'z' ) {
  145.  
  146.       fprintf (stderr, "Invalid GIF file format: %s\n", filename);
  147.       fclose(Bit_File);
  148.       exit (1);
  149.       }
  150.  
  151.    planes = ((unsigned)buffer[10] & 0x0F) + 1;
  152.    colourmap_size = (int)(1 << planes);
  153.  
  154.    if ((gif_colour_map = (IMAGE_COLOUR *)
  155.          malloc (colourmap_size * sizeof (IMAGE_COLOUR))) == NULL) {
  156.       fprintf (stderr, "Cannot allocate GIF Colour Map\n");
  157.       fclose (Bit_File);
  158.       exit (1);
  159.       }
  160.  
  161.    if ((buffer[10] & 0x80) == 0) {    /* color map (better be!) */
  162.       fprintf (stderr, "Invalid GIF file format: %s\n", filename);
  163.       fclose(Bit_File);
  164.       exit (1);
  165.       }
  166.  
  167.    for (i = 0; i < colourmap_size ; i++) {
  168.       gif_colour_map[i].Red = (unsigned char)get_byte();
  169.       gif_colour_map[i].Green = (unsigned char)get_byte();
  170.       gif_colour_map[i].Blue = (unsigned char)get_byte();
  171.       gif_colour_map[i].Alpha = 0;
  172.       }
  173.  
  174.  /* Now display one or more GIF objects */
  175.    finished = FALSE;
  176.    while (!finished) {
  177.       switch (get_byte()) {
  178.          case ';':                /* End of the GIF dataset */
  179.             finished = TRUE;
  180.             status = 0;
  181.             break;
  182.  
  183.          case '!':                /* GIF Extension Block */
  184.             get_byte();           /* read (and ignore) the ID */
  185.             while ((i = get_byte()) > 0) /* get data len*/
  186.             for (j = 0; j < i; j++)
  187.                 get_byte(); /* flush data */
  188.             break;
  189.  
  190.          case ',': /* Start of image object. get description */
  191.             for (i = 0; i < 9; i++) {
  192.                if ((j = get_byte()) < 0) {    /* EOF test (?) */
  193.                   status = -1;
  194.                   break;
  195.                   }
  196.            buffer[i] = (unsigned char) j;
  197.                }
  198.  
  199.             if (status < 0) {
  200.                finished = TRUE;
  201.                break;
  202.                }
  203.  
  204.             Image->iwidth  = buffer[4] | (buffer[5] << 8);
  205.             Image->iheight = buffer[6] | (buffer[7] << 8);
  206.             Image->width = (DBL) Image->iwidth;
  207.             Image->height = (DBL) Image->iheight;
  208.  
  209.         Bitmap_Line = 0;
  210.  
  211.             Image->Colour_Map_Size = colourmap_size;
  212.             Image->Colour_Map = gif_colour_map;
  213.  
  214.             if ((Image->data.map_lines = (unsigned char **)
  215.                  malloc(Image->iheight * sizeof (unsigned char *)))==NULL) {
  216.                fprintf (stderr, "Cannot allocate memory for picture\n");
  217.                exit(1);
  218.                }
  219.  
  220.             for (i = 0 ; i < Image->iheight ; i++) {
  221.                if ((Image->data.map_lines[i] = (unsigned char *) malloc(Image->iwidth))==NULL) {
  222.                   fprintf (stderr, "Cannot allocate memory for picture\n");
  223.                   exit(1);
  224.                   }
  225.                }
  226.  
  227.           /* Setup the color palette for the image */
  228.             status = decoder ((short) Image->iwidth); /*put bytes in Buf*/
  229.             finished = TRUE;
  230.             break;
  231.  
  232.          default:
  233.             status = -1;
  234.             finished = TRUE;
  235.             break;
  236.          }
  237.       }
  238.  
  239.    free (decoderline);
  240.    fclose(Bit_File);
  241.    }
  242.