/**************************************************
 *
 * GIF.c (GIF module of FileID)
 *
 *    Disassemble GIF file
 *
 *    Copyright(c), 1990 Lloyd B. Eldred
 *                     & Fredrick R Homan
 *
 **************************************************/
#include <stdio.h>
#include <math.h>
#include <string.h>

typedef unsigned char UBYTE;     /* 8 bits unsigned */
typedef unsigned short UWORD;    /* 16 bits unsigned */
typedef short WORD;		 /* 16 bits signed */
typedef long LONG;               /* 32 bits signed */

#define TRUE 1
#define FALSE 0

void Gif_PlainText(picfile,PrintFlag)
FILE *picfile;
UBYTE PrintFlag;
{
    UBYTE bsize,c1,c2,c3,c4;
    UBYTE ccw,cch,tbi,tfi;
    char buf[256],coltext[512];
    UWORD tgl,tgt;
    int width,height,colwidth,tw;
    void fi_getc(FILE *,char *);

    if (PrintFlag) printf(" Plain Text\n");

    fi_getc(picfile,&bsize);     /* Block size = 12 ? */

    if (fread(buf,12,1,picfile) !=  1) {
      printf(" Unexpected end of file. (PT-2)\n");
      fclose(picfile);
      fi_exit();
      }

    c1 = buf[0];
    c2 = buf[1];
    c3 = buf[2];
    c4 = buf[3];

    tgl = (UWORD)(c1 + 256*c2);
    tgt = (UWORD)(c3 + 256*c4);

    c1 = buf[4];
    c2 = buf[5];
    c3 = buf[6];
    c4 = buf[7];

    width  = (int)(c1 + 256*c2);
    height = (int)(c3 + 256*c4);

    ccw = buf[8];
    cch = buf[9];
    tfi = buf[10];
    tbi = buf[11];

    colwidth = width / ccw;

    if (PrintFlag) printf("    Text left edge   : %d\n"
           "    Text top         : %d\n"
           "    Grid width       : %d\n"
           "    Grid height      : %d\n"
           "    Cell width       : %d\n"
           "    Cell height      : %d\n"
           "    Foreground color : %d\n"
           "    Background color : %d\n"
           ,tgl,tgt,width,height,ccw,cch,tfi,tbi);

    fi_getc(picfile,&bsize);        /* Block size */

    if (bsize != 0 && PrintFlag)
      printf("    ********** Text reads: **********\n");

    while (bsize != 0) {
      if (fread(buf, bsize, 1,picfile) != 1) {
	   fprintf(stderr, "Unexpected end of file. (PT-4)\n");
	   fclose(picfile);
		fi_exit();
      }

      buf[bsize]='\0';

      if (PrintFlag)
          for (tw = 0; tw < bsize; tw += colwidth) {
              strncpy (coltext, &buf[tw], colwidth);
              coltext[colwidth] = '\0';
              printf("%s\n",coltext);
          }
      fi_getc(picfile,&bsize);         /* Block size */

    } /* end of while() */

    if (PrintFlag) printf("\n");
    return;

} /* End of Plain Text Section */

void Gif_Application(picfile,PrintFlag)
FILE *picfile;
UBYTE PrintFlag;
 {
    UBYTE bsize;
    char buf[256];
    void fi_getc(FILE *,char *);
    
    printf(" Application specific\n");
    fi_getc(picfile,&bsize);     /* Block size = 11 ? */
    if (fread(buf,bsize,1,picfile) !=  1) {
      printf(" Unexpected end of file. (Appl-2)\n");
      fclose(picfile);
      fi_exit();
      }
                     
    /* write Application Identifier */                     
    if (PrintFlag) printf("    Application ID: %8s\n",buf);

    fi_getc(picfile,&bsize);

    while(bsize != 0){           
      if (fread(buf,bsize,1,picfile) !=  1) {
         printf(" Unexpected end of file. (Appl-4)\n");
         fclose(picfile);
         fi_exit();
         }
    fi_getc(picfile,&bsize);
    } /* end of while */                      
          
    return;
 } /* End of Application Specific Section */

void Gif_Comment(picfile,PrintFlag)
FILE *picfile;
UBYTE PrintFlag;
{
   UBYTE bsize;
   char buf[256];
   void fi_getc(FILE *,char *);
   
   fi_getc(picfile,&bsize);      /* Block size */
  
   if (bsize != 0 && PrintFlag) printf("   ********* Text reads: *********\n");
   
   while(bsize != 0){                 
	   if (fread(buf, bsize, 1,picfile) != 1) {
		   fprintf(stderr, "Unexpected end of file. (Com-2)\n");
			fclose(picfile);
			fi_exit();
         }

      buf[bsize]='\0';
                                          
      if (PrintFlag) printf("%s",buf);

      fi_getc(picfile,&bsize);      /* Block size */

      
   } /* end of while() */
      
   if (PrintFlag) printf("\n");
   return;
} /* end of dealing with comment */

void Gif_Image(picfile,PrintFlag)
FILE *picfile;
UBYTE PrintFlag;
{
   UBYTE c1,c2,c3,c4,bsize,LZW_size;
   char buf[256];
   UWORD ilp,itp;
   int planes,color,offset,width,height,i;
   void fi_getc(FILE *,char *);
      
   if (PrintFlag) printf("  Image Descriptor:\n");
	if (fread(buf, 9, 1,picfile) != 1) {
	   fprintf(stderr, "Unexpected end of file. (I-1)\n");
		fclose(picfile);
		fi_exit();
      }
   c1 = buf[0];
   c2 = buf[1];
   c3 = buf[2];
   c4 = buf[3];
          
   ilp = (UWORD)(c1 + 256*c2);
   itp = (UWORD)(c3 + 256*c4);            
            
   c1 = buf[4];
   c2 = buf[5];
   c3 = buf[6];
   c4 = buf[7];
            
   width  = (int)(c1 + 256*c2);
   height = (int)(c3 + 256*c4);
            
   if (PrintFlag) printf("    Image left edge: %d\n"
          "    Image top      : %d\n"
          "    Image width    : %d\n"
          "    Image height   : %d\n",ilp,itp,width,height);
           
   c1 = buf[8];
   
   if(PrintFlag){         
      if(c1 & 0x40) 
         printf("    Image is interlaced.\n");
      else
         printf("    Image is not interlaced.\n");
                              
      if(c1 & 0x18)
         printf("    Uses bits reserved for future"
                " expansion as of the GIF89a standard.\n");
      }
            
      if(c1 & 0x80){
         if(c1 & 0x20)
            if(PrintFlag)printf("    Uses Local Color Table (sorted)\n");
         else
            if(PrintFlag)printf("    Uses Local Color Table (unsorted)\n");
                       
     planes =(int)(c1 & 0x07) +1;
	  color=1;
	  for(i=0; i<planes ; i++) color = color * 2;
   
     if(PrintFlag) printf("       size: %d colors\n",color);
     offset = 3 * color;
               
   /* Skip the Local Color Table */
                            
   if (fseek(picfile,offset,1) == -1){
      printf(" Unexpected end of file. (I-2)\n");  
      fclose(picfile);
      fi_exit();
   }
               
   } /* End of Local Color Table stuff */
            
   else
      if (PrintFlag) printf("    Uses Global Color Table.\n");
            
   /* Skip over the actual image data */
            
	fi_getc(picfile,&LZW_size);      /* LZW Code Size */
   fi_getc(picfile,&bsize);         /* Block size */                        
            
   while(bsize !=0){
      if (fseek(picfile,bsize,1) == -1){
         printf(" Unexpected end of file. (I-5)\n");  
            fclose(picfile);
            fi_exit();
            }
               
      fi_getc(picfile,&bsize);      /* Next block size */
                                 
    } /* End of while() */
    return;        
}    /* End of Image Data */

void Gif_Graphic(picfile,PrintFlag)
FILE *picfile;
UBYTE PrintFlag;
{
   UBYTE c1,c2,bsize,fields,trans;
   UWORD delay;
   int disp;
   void fi_getc(FILE *,char *);
   
   if (PrintFlag) printf(" Graphic Control\n");
   
   fi_getc(picfile,&bsize);         /* Block size = 4 ? */
   
   while(bsize != 0){
      fi_getc(picfile,&fields);        /* Packed fields */
      if(fields & 0xe0) 
         if (PrintFlag) printf("    Bits reserved as of GIF89a standard are being used.\n");
               
      disp = (int)(fields & 0x1c)>>2;
      if (PrintFlag) {
         if(disp == 0)
            printf("    No disposal information given for"
                   " the following graphic.\n");
         if(disp == 1)
            printf("    Following graphic is not to be"
                   " disposed of after being displayed.\n");
         if(disp == 2)
             printf("    The area used by the following graphic"
                   " is to be restored to the background\n"
                   "    color after being displayed.\n");
         if(disp == 3)
            printf("    The area used by the following graphic"
                   " is to be restored to the previous\n"
                   "    image after being displayed.\n");
         if(disp >3 && disp <8)
            printf("    The area used by the following graphic"
                   " is to be disposed of in a method\n"
                   "    NOT defined by the GIF89a standard.\n");
      }
      if(fields & 0x02)
         if (PrintFlag) printf("    User Input is expected.\n");
      else
         if (PrintFlag) printf("    User Input is not expected.\n");
               
      trans = fields & 0x01;
      
      fi_getc(picfile,&c1);      /* Delay pt 1 */
      fi_getc(picfile,&c2);      /* Delay pt 2 */
      delay = (UWORD)(c1 + 256*c2);
      if(delay != 0)
         if (PrintFlag) printf("    Delay time: %d hundreths of a second"
                                ".\n",delay);
      
      fi_getc(picfile,&c1);      /* Transparent index */
      if((trans) && (PrintFlag)) printf("    Color %d is to be treated as"
                       " transparent.\n",c1);
      
      fi_getc(picfile,&bsize);       /* Next block size */
      } /* End of while(bsize != 0) */               
      return;
} /* end of graphic control section */

void fi_getc(picfile,c)
FILE *picfile;
char *c;
{
      if (fread(c, 1, 1,picfile) != 1) { 
         printf(" Unexpected end of file.\n");
         fclose(picfile);  
         fi_exit();
      }
   return;
}