home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / vg-2.03 / gif / gif.c next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  14.3 KB  |  749 lines

  1. /*
  2.  * Copyright (C) 1990-1992 Michael Davidson.
  3.  * All rights reserved.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software
  6.  * and its documentation for any purpose and without fee is hereby
  7.  * granted, provided that the above copyright notice appear in all
  8.  * copies and that both that copyright notice and this permission
  9.  * notice appear in supporting documentation.
  10.  *
  11.  * This software is provided "as is" without express or implied warranty.
  12.  */
  13.  
  14. /*
  15.  * The Graphics Interchange Format(c) is the Copyright property
  16.  * of CompuServe Incorporated.
  17.  *
  18.  * GIF(sm) is a Service Mark property of CompuServe Incorporated.
  19.  */
  20.  
  21. #include    <stdio.h>
  22. #include    <stdlib.h>
  23. #include    <string.h>
  24.  
  25. #include    "image.h"
  26.  
  27. #ifndef    STATIC
  28. #define    STATIC    static
  29. #endif
  30.  
  31. /*
  32.  * GIF file definitions
  33.  */
  34. #define    GIF_IMAGE_SEPARATOR    ','
  35. #define    GIF_EXTENSION        '!'
  36. #define    GIF_TERMINATOR        ';'
  37.  
  38. #define    GIF_PLAIN_TEXT_EXT        0x01
  39. #define    GIF_GRAPHICS_CONTROL_EXT    0xf9
  40. #define    GIF_COMMENT_EXT            0xfe
  41. #define    GIF_APPLICATION_EXT        0xff
  42.  
  43. /*
  44.  * GIF flags
  45.  */
  46. #define    GIF_INTERLACE        0x40
  47.  
  48. /*
  49.  * globals describing the GIF file
  50.  */
  51.  
  52. /*
  53.  * GIF Screen Descriptor
  54.  */
  55. STATIC    int    GIFScreenWidth;
  56. STATIC    int    GIFScreenHeight;
  57. STATIC    int    GIFScreenDepth;
  58. STATIC    int    GIFScreenFlags;
  59. STATIC    int    GIFScreenBackground;
  60. STATIC    int    GIFScreenAspectRatio;
  61.  
  62. /*
  63.  * GIF Global Color Map
  64.  */
  65. STATIC    int        GIFGlobalColors;
  66. STATIC  unsigned char    GIFGlobalColorMap[256][3];
  67.  
  68. /*
  69.  * GIF Local Color Map
  70.  */
  71. STATIC    int        GIFLocalColors;
  72. STATIC    unsigned char    GIFLocalColorMap[256][3];
  73.  
  74. /*
  75.  * GIF Graphics controls
  76.  */
  77. STATIC unsigned    DisposalMethod;
  78. STATIC unsigned    UserInputFlag;
  79. STATIC unsigned    TransparentColorFlag;
  80. STATIC unsigned    DelayTime;
  81. STATIC unsigned    TransparentColorIndex;
  82.  
  83. /*
  84.  * Disposal methods
  85.  */
  86. #define    NO_DISPOSAL        0
  87. #define    LEAVE_IN_PLACE        1
  88. #define    RESTORE_BG        2
  89. #define    RESTORE_PREVIOUS    3
  90.  
  91. /*
  92.  * the GIF image itself
  93.  */
  94. STATIC image_t    *GIFImage;
  95.  
  96. STATIC int    gifReadImage(FILE *fp);
  97. STATIC int    gifReadExtension(FILE *fp);
  98. STATIC int    gifDecode(FILE *fp, int, int, int, int, int, int (*)());
  99. STATIC int    gifComment(FILE *fp);
  100. STATIC int    gifPlainText(FILE *fp);
  101. STATIC int    gifApplication(FILE *fp);
  102. STATIC void    gifSkipBlocks(FILE *fp);
  103. STATIC int    gifGraphicsControl(FILE *fp);
  104. STATIC int    gifReadByte(FILE *fp);
  105. STATIC int    gifReadWord(FILE *fp);
  106.  
  107. char    *
  108. gifInfo(
  109.     FILE    *fp
  110.     )
  111. {
  112.     static char    info[40];
  113.     int        width;
  114.     int        height;
  115.     int        colors;
  116.     int        flags;
  117.  
  118.     if (fread(info, 6, 1, fp) != 1)
  119.     return NULL;
  120.  
  121.     if (strncmp(info, "GIF87a", 6) != 0 && strncmp(info, "GIF89a", 6) != 0)
  122.     return NULL;
  123.  
  124.     width    = gifReadWord(fp);
  125.     height    = gifReadWord(fp);
  126.     flags    = gifReadByte(fp);
  127.     colors    = 1 << ((flags & 7) + 1);
  128.  
  129.     sprintf(&info[6], " %dx%d %d colors", width, height, colors);
  130.  
  131.     return info;
  132. }
  133.  
  134. int
  135. gifRead(
  136.     char    *name,
  137.     FILE    *fp
  138.     )
  139. {
  140.     int        c;
  141.     char    header[6];
  142.     int        r;
  143.  
  144.     if (fread(header, sizeof(header), 1, fp) != 1)
  145.     return imageError("can't read GIF header");
  146.  
  147.     if (  strncmp(header, "GIF87a", sizeof(header)) != 0
  148.        && strncmp(header, "GIF89a", sizeof(header)) != 0  )
  149.     return imageError("not a GIF file");
  150.  
  151.     GIFScreenWidth    = gifReadWord(fp);
  152.     GIFScreenHeight    = gifReadWord(fp);
  153.     GIFScreenFlags    = gifReadByte(fp);
  154.     GIFScreenBackground    = gifReadByte(fp);
  155.     GIFScreenAspectRatio= gifReadByte(fp);
  156.  
  157.     GIFScreenDepth    = (GIFScreenFlags & 7) + 1;
  158.     GIFGlobalColors    = (GIFScreenFlags & 0x80) ? (1 << GIFScreenDepth) : 0;
  159.  
  160.     if ((GIFImage = imageStart(name, GIFScreenWidth, GIFScreenHeight,
  161.         GIFScreenDepth, GIFScreenBackground)) == NULL)
  162.     return imageError("can't allocate %d x %d GIF image",
  163.         GIFScreenWidth, GIFScreenHeight);
  164.  
  165.     if (GIFGlobalColors != 0)
  166.     {
  167.     if (fread(GIFGlobalColorMap, 3, GIFGlobalColors, fp) != GIFGlobalColors)
  168.         return imageError("can't read global color map");
  169.  
  170.     imageSetColorMap(0, GIFGlobalColorMap, GIFGlobalColors);
  171.     }
  172.  
  173.     imageShowInfo(1);
  174.  
  175.     /*
  176.      * set default graphics controls
  177.      */
  178.     DisposalMethod        = NO_DISPOSAL;
  179.     UserInputFlag        = 0;
  180.     TransparentColorFlag    = 0;
  181.     DelayTime            = 0;
  182.     TransparentColorIndex    = 0;
  183.  
  184.     while ((c = gifReadByte(fp)) != GIF_TERMINATOR)
  185.     { 
  186.     switch (c)
  187.     {
  188.         case GIF_IMAGE_SEPARATOR:
  189.         if ( (r = gifReadImage(fp)) != 0)
  190.             return r;
  191.         break;
  192.  
  193.         case GIF_EXTENSION:
  194.         if ( (r = gifReadExtension(fp)) != 0)
  195.             return r;
  196.         break;
  197.  
  198.         case EOF:
  199.         return gifCorruptFile();
  200.  
  201.         default:
  202.         return gifCorruptFile();
  203.     }
  204.     }
  205.   
  206.     return imageEnd();
  207. }
  208.  
  209. gifCorruptFile()
  210. {
  211.     int        r;
  212.  
  213.     if ( (r = imageWarning("corrupt or truncated file")) != 0)
  214.     return r;
  215.     else
  216.     return imageEnd();
  217. }
  218.  
  219. int
  220. gifPutPixels(
  221.     int            x,
  222.     int            y,
  223.     unsigned char    *pixels,
  224.     int            count
  225.     )
  226. {
  227.     if (TransparentColorFlag)
  228.     {
  229.     register unsigned char    c, *p, *q;
  230.     register int        n;
  231.  
  232.     c = TransparentColorIndex;
  233.     n = count;
  234.  
  235.     for (p = pixels, q = &GIFImage->pixels[y][x]; --n >= 0; p++, q++)
  236.         if (*p != c)
  237.         *q = *p;
  238.     }
  239.     else
  240.     {
  241.     memcpy(&GIFImage->pixels[y][x], pixels, count);
  242.     }
  243.  
  244.     return imageRefresh(x, y, count, 1);
  245. }
  246.  
  247. int
  248. gifReadImage(
  249.     FILE    *fp
  250.     )
  251. {
  252.     int        GIFImageLeft;
  253.     int        GIFImageTop;
  254.     int        GIFImageWidth;
  255.     int        GIFImageHeight;
  256.     int        GIFImageDepth;
  257.     int        GIFImageFlags;
  258.     int        r;
  259.  
  260.     GIFImageLeft    = gifReadWord(fp);
  261.     GIFImageTop        = gifReadWord(fp);
  262.     GIFImageWidth    = gifReadWord(fp);
  263.     GIFImageHeight    = gifReadWord(fp);
  264.     GIFImageFlags    = gifReadByte(fp);
  265.  
  266.     /*
  267.      * check that the image fits within the screen
  268.      */
  269.     if (GIFImageWidth > GIFScreenWidth || GIFImageHeight > GIFScreenHeight)
  270.     return imageError("GIF image exceeds screen dimensions");
  271.  
  272.     /*
  273.      * check that the image position is OK and adjust if necessary
  274.      * (some GIF encoders get this wrong ......)
  275.      */
  276.     if (GIFImageLeft + GIFImageWidth > GIFScreenWidth)
  277.     GIFImageLeft = GIFScreenWidth - GIFImageWidth;
  278.  
  279.     if (GIFImageTop + GIFImageHeight > GIFScreenHeight)
  280.     GIFImageTop = GIFScreenHeight - GIFImageHeight;
  281.  
  282.     GIFImageDepth    = (GIFImageFlags & 7) + 1;
  283.     GIFLocalColors    = (GIFImageFlags & 0x80) ? (1 << GIFImageDepth) : 0;
  284.  
  285.     if (GIFLocalColors != 0)
  286.     {
  287.     if (fread(GIFLocalColorMap, 3, GIFLocalColors, fp) != GIFLocalColors)
  288.         return imageError("can't read local color map");
  289.  
  290.     imageSetColorMap(1, GIFLocalColorMap, GIFLocalColors);
  291.     }
  292.  
  293.     r = gifDecode(fp, GIFImageLeft, GIFImageTop, GIFImageWidth, GIFImageHeight,
  294.         GIFImageFlags & 0x40, gifPutPixels);
  295.  
  296.     return (r < 0) ? gifCorruptFile() : r;
  297. }
  298.  
  299. /*
  300.  *  LZW decoding routines
  301.  */
  302.  
  303. #define    MAXCODESIZE    12
  304. #define    TABLESIZE    (1 << MAXCODESIZE)
  305.  
  306. struct    code
  307. {
  308.     struct code        *previous;
  309.     short        length;
  310.     unsigned char    c;
  311. };
  312.  
  313.  
  314. #define    GIFGetCode()  ( (*(unsigned long *)(Bits + (BitIndex >> 3))) \
  315.             >> (BitIndex & 7) )
  316. /*
  317.  * GIFDecode()    - decodes the actual image data
  318.  */
  319.  
  320. gifDecode(
  321.     FILE    *fp,
  322.     int        left,
  323.     int        top,
  324.     int        width,
  325.     int        height,
  326.     int        interlace,
  327.     int        (*putpixels)()
  328.     )
  329. {
  330.     unsigned char    Bits[260];
  331.     unsigned        BitIndex;
  332.     unsigned        BitCount;
  333.  
  334.     unsigned        InitCodeSize;
  335.     unsigned        CodeSize;
  336.     unsigned        CodeMask;
  337.     struct code        Codes[TABLESIZE+2];
  338.     register struct code    *CodeP;
  339.     struct code        *NextCodeP;
  340.     struct code        *PrevCodeP;
  341.     struct code        *LastCodeP;
  342.     struct code        *ClearCodeP;
  343.     struct code        *EOFCodeP;
  344.     unsigned char    buf[8192];
  345.     register unsigned char    *BufP;
  346.     unsigned char    *limit;
  347.  
  348.     unsigned        Code;
  349.     int            x, y;
  350.     int            step;
  351.     int            npixels;
  352.     int            r;
  353.  
  354.     /*
  355.      * get initial code size
  356.      */
  357.     if ((r = gifReadByte(fp)) < 1 || r > 8)
  358.     return -1;
  359.  
  360.     InitCodeSize = r + 1;
  361.     CodeSize     = InitCodeSize;
  362.  
  363.     /*
  364.      * set up pointers to special code values
  365.      */
  366.     ClearCodeP    = &Codes[1 << (CodeSize - 1)];
  367.     EOFCodeP    = ClearCodeP + 1;
  368.     NextCodeP    = EOFCodeP;
  369.     PrevCodeP    = ClearCodeP;
  370.     LastCodeP    = &Codes[1 << CodeSize];
  371.     CodeMask    = (1 << CodeSize) - 1;
  372.  
  373.     /*
  374.      * set up all of the single byte entries in the decode table
  375.      */
  376.     for (Code = 0, CodeP = Codes; CodeP < ClearCodeP; Code++, CodeP++)
  377.     {
  378.     CodeP->previous    = NULL;
  379.     CodeP->length    = 1;
  380.     CodeP->c    = (unsigned char) Code;
  381.     }
  382.  
  383.     ClearCodeP->previous= NULL;
  384.     ClearCodeP->length    = 0;
  385.     ClearCodeP->c    = 0;
  386.  
  387.     EOFCodeP->previous    = NULL;
  388.     EOFCodeP->length    = 0;
  389.     EOFCodeP->c        = 0;
  390.  
  391.     BitIndex    =
  392.     BitCount    = 0;
  393.  
  394.     x        = 0;
  395.     y        = 0;
  396.     step    = interlace ? 8 : 1;
  397.     BufP    = &buf[0];
  398.     limit    = BufP + 4096;
  399.  
  400.     for (;;)
  401.     {
  402.     while (BitCount >= CodeSize && BufP < limit)
  403.     {
  404.         Code    = GIFGetCode();
  405.         Code    &= CodeMask;
  406.         BitCount    -= CodeSize;
  407.         BitIndex    += CodeSize;
  408.         CodeP    = &Codes[Code];
  409.  
  410.         if (CodeP < ClearCodeP)
  411.         {
  412.         NextCodeP->previous    = PrevCodeP;
  413.         NextCodeP->length    = PrevCodeP->length + 1;
  414.         NextCodeP->c        = (unsigned char) Code;
  415.         *BufP++            = (unsigned char) Code;
  416.         PrevCodeP        = CodeP;
  417.         
  418.         if (++NextCodeP >= LastCodeP)
  419.         {
  420.             if (CodeSize < MAXCODESIZE)
  421.             {
  422.             ++CodeSize;
  423.             LastCodeP    = &Codes[1 << CodeSize];
  424.             CodeMask    = (1 << CodeSize) - 1;
  425.             }
  426.             else
  427.             NextCodeP = LastCodeP;
  428.         }
  429.         }
  430.         else if (CodeP > EOFCodeP)
  431.         {
  432.         unsigned char    *p;
  433.         int        length;
  434.  
  435.         NextCodeP->previous    = PrevCodeP;
  436.         NextCodeP->length    = PrevCodeP->length + 1;
  437.  
  438.         if (CodeP >= NextCodeP)
  439.         {
  440.             CodeP    = NextCodeP;
  441.             CodeP->c    = (CodeP-1)->c;
  442.         }
  443.  
  444.         PrevCodeP    = CodeP;
  445.         length        = CodeP->length;
  446.         p        = BufP;
  447.         BufP        += length;
  448.  
  449.         switch (length & 7)
  450.         {
  451.             do
  452.             {
  453.             case 0: *--BufP = CodeP->c; CodeP = CodeP->previous;
  454.             case 7: *--BufP = CodeP->c; CodeP = CodeP->previous;
  455.             case 6: *--BufP = CodeP->c; CodeP = CodeP->previous;
  456.             case 5: *--BufP = CodeP->c; CodeP = CodeP->previous;
  457.             case 4: *--BufP = CodeP->c; CodeP = CodeP->previous;
  458.             case 3: *--BufP = CodeP->c; CodeP = CodeP->previous;
  459.             case 2: *--BufP = CodeP->c; CodeP = CodeP->previous;
  460.             case 1: *--BufP = CodeP->c; CodeP = CodeP->previous;
  461.             } while (BufP > p);
  462.         }
  463.  
  464.         NextCodeP->c    = *BufP;    /* now set real suffix value    */
  465.         BufP        += length;
  466.     
  467.         if (++NextCodeP >= LastCodeP)
  468.         {
  469.             if (CodeSize < MAXCODESIZE)
  470.             {
  471.             ++CodeSize;
  472.             LastCodeP    = &Codes[1 << CodeSize];
  473.             CodeMask    = (1 << CodeSize) - 1;
  474.             }
  475.             else
  476.             NextCodeP = LastCodeP;
  477.         }
  478.             }
  479.         else if (CodeP == ClearCodeP)
  480.         {
  481.         CodeSize    = InitCodeSize;
  482.         LastCodeP    = &Codes[1 << CodeSize];
  483.         CodeMask    = (1 << CodeSize) - 1;
  484.         NextCodeP    = EOFCodeP;
  485.         PrevCodeP    = ClearCodeP;
  486.         }
  487.         else if (CodeP == EOFCodeP)
  488.         break;
  489.     }
  490.  
  491.     /*
  492.      * get here if:
  493.      *    Bitcount < Codesize    -> need more bits
  494.      *    BufP     >= limit    -> need to flush buffer
  495.      *    code     == eof        -> all done
  496.      */
  497.  
  498.     /*
  499.      * first put out any pixels in case we just hit EOF
  500.      */
  501.     npixels    = BufP - buf;
  502.     BufP    = buf;
  503.  
  504.     while (npixels > 0)
  505.     {
  506.         int        n;
  507.  
  508.         n = width - x;
  509.         if (npixels < n)
  510.         n = npixels;
  511.  
  512.         if ((r = putpixels(left + x, top + y, BufP, n)) != 0)
  513.         return r;
  514.  
  515.         if ((x += n) >= width)
  516.         {
  517.         x = 0;
  518.         if ((y += step) >= height)
  519.         {
  520.             step = step - (y & (step - 1));
  521.             y    = step / 2;
  522.         }
  523.         }
  524.         npixels    -= n;
  525.         BufP    += n;
  526.     }
  527.     BufP    = buf;
  528.  
  529.      /*
  530.      * if we are at EOF bail out
  531.      */
  532.     if (CodeP == EOFCodeP)
  533.         break;
  534.  
  535.     /*
  536.      * now get more code bits if necessary
  537.      */
  538.     if (BitCount < CodeSize)
  539.         {
  540.         int        len;
  541.         int        i;
  542.  
  543.         len = (BitCount + 7) >> 3;
  544.         for (i = 0; i < len; i++)
  545.         Bits[i] = Bits[(BitIndex >> 3) + i];
  546.         BitIndex &= 7;
  547.  
  548.         do
  549.         {
  550.         if ((len = getc(fp)) == EOF)
  551.             return -1;
  552.  
  553.         if (len == 0 || fread(&Bits[i], 1, len, fp) != len)
  554.             return -1;
  555.  
  556.         BitCount += len * 8;
  557.         i     += len;
  558.         } while (BitCount < CodeSize);
  559.     }
  560.  
  561.     }
  562.     /*
  563.      * seen EOF code - check for 0 length data block at end of encoded data
  564.      */
  565.  
  566.     if (getc(fp) != 0)
  567.     return    -1;
  568.  
  569.     return 0;
  570. }
  571.  
  572. int
  573. gifReadExtension(
  574.     FILE    *fp
  575.     )
  576. {
  577.     int        c;
  578.  
  579.     c    = gifReadByte(fp);
  580.  
  581.     switch (c)
  582.     {
  583.     case 0xf9:        /* graphics control    */
  584.         gifGraphicsControl(fp);
  585.         break;
  586.  
  587.     case 0xfe:        /* comment        */
  588.         gifComment(fp);
  589.         break;
  590.  
  591.     case 0x01:        /* plain text        */
  592.         gifPlainText(fp);
  593.         break;
  594.  
  595.     case 0xff:        /* application        */
  596.         gifApplication(fp);
  597.         break;
  598.  
  599.     default:        /* unknown extension    */
  600.         gifSkipBlocks(fp);
  601.         break;
  602.  
  603.     }
  604.     return 0;
  605. }
  606.  
  607. STATIC int
  608. gifGraphicsControl(
  609.     FILE    *fp
  610.     )
  611. {
  612.     int        flags;
  613.  
  614.     if (gifReadByte(fp) != 4)            /* check block size    */
  615.     return -1;
  616.  
  617.     flags        = gifReadByte(fp);
  618.  
  619.     DisposalMethod    = (flags >> 2) & 7;
  620.     UserInputFlag    = flags & 0x02;
  621.     TransparentColorFlag= flags & 0x01;
  622.  
  623.     DelayTime        = gifReadWord(fp);
  624.     TransparentColorIndex= gifReadByte(fp);
  625.  
  626.     if (gifReadByte(fp) != 0 || ferror(fp))    /* check terminator    */
  627.     return -1;
  628.  
  629.     return 0;
  630. }
  631.  
  632. STATIC int
  633. gifComment(
  634.     FILE    *fp
  635.     )
  636. {
  637.     int        len;
  638.     char    buf[255];
  639.  
  640.     while ((len = gifReadByte(fp)) != 0 && len != EOF)
  641.     {
  642.     if (fread(buf, 1, len, fp) != len)
  643.         break;
  644.  
  645. #if 0
  646.     PutComment(buf, len);
  647. #endif
  648.     }
  649.  
  650.     return (len == 0) ? 0 : -1;
  651. }
  652.  
  653. STATIC int
  654. gifPlainText(
  655.     FILE    *fp
  656.     )
  657. {
  658.     int        TextGridLeft;
  659.     int        TextGridTop;
  660.     int        TextGridWidth;
  661.     int        TextGridHeight;
  662.     int        CharCellWidth;
  663.     int        CharCellHeight;
  664.     int        TextForeground;
  665.     int        TextBackground;
  666.     int        len;
  667.     char    buf[255];
  668.  
  669.     if (gifReadByte(fp) != 12)            /* check block size    */
  670.     return -1;
  671.  
  672.     TextGridLeft    = gifReadWord(fp);
  673.     TextGridTop        = gifReadWord(fp);
  674.     TextGridWidth    = gifReadWord(fp);
  675.     TextGridHeight    = gifReadWord(fp);
  676.     CharCellWidth    = gifReadByte(fp);
  677.     CharCellHeight    = gifReadByte(fp);
  678.     TextForeground    = gifReadByte(fp);
  679.     TextBackground    = gifReadByte(fp);
  680.  
  681.     while ((len = gifReadByte(fp)) != 0 && len != EOF)
  682.     {
  683.     if (fread(buf, 1, len, fp) != len)
  684.         break;
  685.     /*
  686.      * do text rendering here
  687.      */
  688.     }
  689.  
  690.     return (len == 0) ? 0 : -1;
  691. }
  692.  
  693. STATIC int
  694. gifApplication(
  695.     FILE    *fp
  696.     )
  697. {
  698.     char    AppID[8];
  699.     char    AppAuthCode[3];
  700.     char    AppData[255];
  701.     int        len;
  702.  
  703.     if (gifReadByte(fp) != 11)            /* check block size    */
  704.     return -1;
  705.  
  706.     if (fread(AppID, sizeof(AppID), 1, fp) != 1)
  707.     return -1;
  708.  
  709.     if (fread(AppAuthCode, sizeof(AppAuthCode), 1, fp) != 1)
  710.     return -1;
  711.  
  712.     while ((len = gifReadByte(fp)) != 0 && len != EOF)
  713.     {
  714.     if (fread(AppData, 1, len, fp) != len)
  715.         break;
  716.     }
  717.  
  718.     return (len == 0) ? 0 : -1;
  719. }
  720.  
  721. STATIC void
  722. gifSkipBlocks(fp)
  723.     FILE    *fp;
  724. {
  725.     int        len;
  726.  
  727.     while ((len = gifReadByte(fp)) != 0 && len != EOF)
  728.     fseek(fp, (long)len, 1);
  729. }
  730.  
  731. STATIC int
  732. gifReadByte(fp)
  733.     FILE    *fp;
  734. {
  735.     return getc(fp);
  736. }
  737.  
  738. STATIC int
  739. gifReadWord(fp)
  740.     FILE    *fp;
  741. {
  742.     int        w;
  743.  
  744.     w    =  getc(fp);
  745.     w    |= getc(fp) << 8;
  746.  
  747.     return  w;
  748. }
  749.