home *** CD-ROM | disk | FTP | other *** search
/ Chestnut's Multimedia Mania / MM_MANIA.ISO / graphics / povsrc20 / gif.c < prev    next >
C/C++ Source or Header  |  1993-07-28  |  7KB  |  238 lines

  1. /****************************************************************************
  2. *                   gif.c
  3. *
  4. *  Gif-format file reader.
  5. *
  6. *  NOTE:  Portions of this module were written by Steve Bennett and are used
  7. *         here with his permission.
  8. *
  9. *  from Persistence of Vision Raytracer
  10. *  Copyright 1993 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. *  NOTICE: This source code file is provided so that users may experiment
  13. *  with enhancements to POV-Ray and to port the software to platforms other 
  14. *  than those supported by the POV-Ray Team.  There are strict rules under
  15. *  which you are permitted to use this file.  The rules are in the file
  16. *  named POVLEGAL.DOC which should be distributed with this file. If 
  17. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  19. *  Forum.  The latest version of POV-Ray may be found there as well.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26.  
  27. /*
  28.    The following routines were borrowed freely from FRACTINT, and represent
  29.    a generalized GIF file decoder.  This seems the best, most universal format
  30.    for reading in Bitmapped images.  GIF is a Copyright of Compuserve, Inc.
  31.    Swiped and converted to entirely "C" coded routines by AAC for the most
  32.    in future portability!
  33. */
  34.  
  35. #include "frame.h"
  36. #include "povproto.h"
  37.  
  38. static IMAGE *Current_Image;  
  39. static int Bitmap_Line;
  40. static FILE *Bit_File;
  41. unsigned char *decoderline  /*  [2049] */ ;  /* write-line routines use this */
  42.  
  43. static IMAGE_COLOUR *gif_colour_map;
  44. static int colourmap_size;
  45.  
  46. int out_line (pixels, linelen)
  47. unsigned char *pixels;
  48. int linelen;
  49.   {
  50.   register int x;
  51.   register unsigned char *line;
  52.  
  53.   line = Current_Image->data.map_lines[Bitmap_Line++];
  54.  
  55.   for (x = 0; x < linelen; x++) 
  56.     {
  57.     if ((int)(*pixels) > Current_Image->Colour_Map_Size) 
  58.       {
  59.       fprintf (stderr, "Error - GIF Image Map Colour out of range\n");
  60.       exit(1);
  61.       }
  62.  
  63.     line[x] = *pixels;
  64.     pixels++;
  65.     }
  66.  
  67.   return (0);
  68.   }
  69.  
  70. #define READ_ERROR -1
  71.  
  72. int get_byte() /* get byte from file, return the next byte or an error */
  73.   {
  74.   register int byte;
  75.  
  76.   if ((byte = getc(Bit_File)) != EOF)
  77.     return (byte);
  78.   else 
  79.     {
  80.     fprintf (stderr, "Premature End Of File reading GIF image\n");
  81.     exit (1);
  82.     }
  83.   return (0);  /* Keep the compiler happy */
  84.   }
  85.  
  86.   /* Main GIF file decoder.  */
  87.  
  88.   void Read_Gif_Image(Image, filename)
  89.     IMAGE *Image;
  90. char *filename;
  91.   {
  92.   register int i, j, status;
  93.   unsigned finished, planes;
  94.   unsigned char buffer[16];
  95.  
  96.   status = 0;
  97.   Current_Image = Image;
  98.  
  99.   if ((Bit_File = Locate_File(filename, READ_FILE_STRING)) == NULL) 
  100.     {
  101.     fprintf (stderr, "Cannot open GIF file %s\n", filename);
  102.     exit(1);
  103.     }
  104.  
  105.   /* zero out the full write-line */
  106.   if ((decoderline = (unsigned char *) malloc (2049)) == NULL) 
  107.     {
  108.     fprintf (stderr, "Cannot allocate space for GIF decoder line\n");
  109.     fclose (Bit_File);
  110.     exit (1);
  111.     }
  112.  
  113.   for (i = 0; i < 2049; i++)
  114.     decoderline[i] = (unsigned char) 0;
  115.  
  116.   /* Get the screen description */
  117.   for (i = 0; i < 13; i++)
  118.     buffer[i] = (unsigned char)get_byte();
  119.  
  120.   if (strncmp((char *) buffer,"GIF",3) ||          /* use updated GIF specs */
  121.     buffer[3] < '0' || buffer[3] > '9' ||
  122.     buffer[4] < '0' || buffer[4] > '9' ||
  123.     buffer[5] < 'A' || buffer[5] > 'z' ) 
  124.     {
  125.  
  126.     fprintf (stderr, "Invalid GIF file format: %s\n", filename);
  127.     fclose(Bit_File);
  128.     exit (1);
  129.     }
  130.  
  131.   planes = ((unsigned)buffer[10] & 0x0F) + 1;
  132.   colourmap_size = (int)(1 << planes);
  133.  
  134.   if ((gif_colour_map = (IMAGE_COLOUR *)
  135.     malloc (colourmap_size * sizeof (IMAGE_COLOUR))) == NULL) 
  136.     {
  137.     fprintf (stderr, "Cannot allocate GIF Colour Map\n");
  138.     fclose (Bit_File);
  139.     exit (1);
  140.     }
  141.  
  142.   if ((buffer[10] & 0x80) == 0) 
  143.     {    /* color map (better be!) */
  144.     fprintf (stderr, "Invalid GIF file format: %s\n", filename);
  145.     fclose(Bit_File);
  146.     exit (1);
  147.     }
  148.  
  149.   for (i = 0; i < colourmap_size ; i++) 
  150.     {
  151.     gif_colour_map[i].Red = (unsigned char)get_byte();
  152.     gif_colour_map[i].Green = (unsigned char)get_byte();
  153.     gif_colour_map[i].Blue = (unsigned char)get_byte();
  154.     gif_colour_map[i].Filter = 0;
  155.     }
  156.  
  157.   /* Now display one or more GIF objects */
  158.   finished = FALSE;
  159.   while (!finished) 
  160.     {
  161.     switch (get_byte()) 
  162.     {
  163.     case ';':                /* End of the GIF dataset */
  164.       finished = TRUE;
  165.       status = 0;
  166.       break;
  167.  
  168.     case '!':                /* GIF Extension Block */
  169.       get_byte();           /* read (and ignore) the ID */
  170.       while ((i = get_byte()) > 0) /* get data len*/
  171.         for (j = 0; j < i; j++)
  172.         get_byte(); /* flush data */
  173.       break;
  174.  
  175.     case ',': /* Start of image object. get description */
  176.       for (i = 0; i < 9; i++) 
  177.         {
  178.         if ((j = get_byte()) < 0) 
  179.           {    /* EOF test (?) */
  180.           status = -1;
  181.           break;
  182.           }
  183.         buffer[i] = (unsigned char) j;
  184.         }
  185.  
  186.       /* Check "interlaced" bit */
  187.       if (j & 0x40)
  188.         Error ("Error!  Can't deal with interlaced GIF files.");
  189.  
  190.       if (status < 0) 
  191.         {
  192.         finished = TRUE;
  193.         break;
  194.         }
  195.  
  196.       Image->iwidth  = buffer[4] | (buffer[5] << 8);
  197.       Image->iheight = buffer[6] | (buffer[7] << 8);
  198.       Image->width = (DBL) Image->iwidth;
  199.       Image->height = (DBL) Image->iheight;
  200.  
  201.       Bitmap_Line = 0;
  202.  
  203.       Image->Colour_Map_Size = colourmap_size;
  204.       Image->Colour_Map = gif_colour_map;
  205.  
  206.       if ((Image->data.map_lines = (unsigned char **)
  207.         malloc(Image->iheight * sizeof (unsigned char *)))==NULL) 
  208.         {
  209.         fprintf (stderr, "Cannot allocate memory for picture\n");
  210.         exit(1);
  211.         }
  212.  
  213.       for (i = 0 ; i < Image->iheight ; i++) 
  214.         {
  215.         if ((Image->data.map_lines[i] = (unsigned char *) malloc(Image->iwidth))==NULL) 
  216.           {
  217.           fprintf (stderr, "Cannot allocate memory for picture\n");
  218.           exit(1);
  219.           }
  220.         }
  221.  
  222.       /* Setup the color palette for the image */
  223.       status = decoder ( Image->iwidth); /*put bytes in Buf*/
  224.       /* changed param to int */
  225.       finished = TRUE;
  226.       break;
  227.  
  228.     default:
  229.       status = -1;
  230.       finished = TRUE;
  231.       break;
  232.     }
  233.     }
  234.  
  235.   free (decoderline);
  236.   fclose(Bit_File);
  237.   }
  238.