home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / pcutils / os2 / imshow / source / giflib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  12.1 KB  |  338 lines

  1. /*******************  Module "GIFLIB.C" Source code file  ******************/
  2. /*                                                                         */
  3. /* MODULE: GIFLIB.C (Procedures to manipulate GIF files)                   */
  4. /*                                                                         */
  5. /*                                                                         */
  6. /* DEVELOPED BY:                                                           */
  7. /* -------------                                                           */
  8. /*  Martin Erzberger, 1989/93                                              */
  9. /*                                                                         */
  10. /*                                                                         */
  11. /* VERSION:                                                                */
  12. /* --------                                                                */
  13. /*  - 2.02, 1/93                                                           */
  14. /*                                                                         */
  15. /*                                                                         */
  16. /* PURPOSE OF MODULE:                                                      */
  17. /* ------------------                                                      */
  18. /*  - Procedures to read GIF images.                                       */
  19. /*                                                                         */
  20. /*                                                                         */
  21. /***************************************************************************/
  22.  
  23.  
  24. #define INCL_GPIBITMAPS            /* Used for bitmaps                     */
  25. #define INCL_BITMAPFILEFORMAT      /* Used for bitmap files                */
  26.  
  27. #define MAX_LWZ_BITS 12
  28.  
  29. #include <os2.h>                   /* OS/2 headerfile                      */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35. #include "imshow.h"
  36.  
  37. static ULONG  ulBytesPerLine;      /* Number of bytes per scanline         */
  38.        ULONG  ulBytesRead;         /* Dummy for DosRead                    */
  39.  
  40. int GetCode (HFILE, int, int);
  41. int LWZReadByte(HFILE, int, int);
  42.  
  43. /**********************  Start of procedure gifopen  ***********************/
  44. /*                                                                         */
  45. /* Gifopen opens a gif file to read and gives back its handler.            */
  46. /* If the file isn't a GIF or can't be opened at all, it gives back NULL.  */
  47. /*                                                                         */
  48. /***************************************************************************/
  49. HFILE gifopen (CHAR *szFileName, CHAR *szMode)
  50. {
  51.   HFILE   fGif;                                  /* Filehandler            */
  52.   ULONG   ulActionTaken;                         /* For DosRead            */
  53.   CHAR    buf[6];                                /* Buffer                 */
  54.  
  55.   if (!strcmp (szMode, "rb")) {                   /* Open to read          */
  56.     DosOpen (szFileName, &fGif, &ulActionTaken, 0L, 0,
  57.              OPEN_ACTION_OPEN_IF_EXISTS |
  58.              OPEN_ACTION_FAIL_IF_NEW,
  59.              OPEN_ACCESS_READONLY       |
  60.              OPEN_SHARE_DENYNONE        |
  61.              OPEN_FLAGS_NOINHERIT       |
  62.              OPEN_FLAGS_NO_CACHE        |       
  63.              OPEN_FLAGS_SEQUENTIAL,             
  64.              0L);
  65.  
  66.     if (fGif == 0)                               /* Couldn't open          */
  67.       return 0;                                  /* Give back NULL         */
  68.  
  69.     DosRead (fGif, buf, 6, &ulBytesRead);        /* Header  */
  70.     if (strncmp (buf, "GIF87a", 6) != 0)
  71.       return 0;
  72.     else return fGif;
  73.   } else
  74.     return 0;
  75. }
  76. /***********************  End of procedure gifopen  ************************/
  77.  
  78.  
  79.  
  80. /**********************  Start of procedure gifclose  **********************/
  81. /*                                                                         */
  82. /* Gifclose closes an opened GIF file. The returnvalue is undefined.       */
  83. /*                                                                         */
  84. /***************************************************************************/
  85. VOID gifclose (HFILE fGif)                       /* Filehandler            */
  86. {
  87.   if (fGif != 0)
  88.     DosClose (fGif);
  89. }
  90. /************************  End of procedure gifclose  **********************/
  91.  
  92.  
  93.  
  94. /**********************  Start of procedure gifrhdr  ***********************/
  95. /*                                                                         */
  96. /* Gifrhdr reads in the GIF header. Returnvalue is 0 if successful.        */
  97. /*                                                                         */
  98. /***************************************************************************/
  99. LONG gifrhdr (HFILE hImage, PBITMAPINFO2 pbmiBitmap)
  100. {
  101.   USHORT            i;                              /* Loop counter        */
  102.   CHAR              buf[16];
  103.  
  104.   DosRead (hImage, buf, 7, &ulBytesRead);
  105.   memset (pbmiBitmap, 0, 64);
  106.   pbmiBitmap->cbFix = 64;
  107.   pbmiBitmap->cx = (ULONG) ((buf[1]<<8) | buf[0]);
  108.   pbmiBitmap->cy = (ULONG) ((buf[3]<<8) | buf[2]);
  109.   pbmiBitmap->cPlanes = 1;
  110.   pbmiBitmap->cBitCount = (USHORT)((buf[4]&0x07) + 1);
  111.  
  112.   if ((buf[4]&0x80) == 0x80)
  113.     for (i=0; i<(1<<pbmiBitmap->cBitCount);i++) {
  114.       DosRead (hImage, buf, 3, &ulBytesRead);
  115.       pbmiBitmap->argbColor[i].bRed   = buf[0];
  116.       pbmiBitmap->argbColor[i].bGreen = buf[1];
  117.       pbmiBitmap->argbColor[i].bBlue  = buf[2];
  118.     }
  119.  
  120.     DosRead (hImage, buf, 1, &ulBytesRead);
  121.     if (ulBytesRead == 0)
  122.       return (-IDS_GIF_NOIMG);
  123.     if (buf[0] == ';')
  124.       return (-IDS_GIF_BOGUS);
  125.     if (buf[0] == '!')
  126.       return (-IDS_GIF_BOGUS);
  127.     if (buf[0] != ',')
  128.       return (-IDS_GIF_BOGUS);
  129.  
  130.     DosRead (hImage, buf, 9, &ulBytesRead);
  131.     if ((buf[8] & 0x40) == 0x40)              /* Interlaced */
  132.       return (-IDS_GIF_INTL);
  133.     pbmiBitmap->cx = (ULONG) ((buf[5]<<8) | buf[4]);
  134.     pbmiBitmap->cy = (ULONG) ((buf[7]<<8) | buf[6]);
  135.     if ((buf[8] & 0x80) == 0x80) {
  136.       pbmiBitmap->cBitCount = (USHORT)((buf[8] & 0x07) + 1);
  137.       for (i=0; i<(1<<pbmiBitmap->cBitCount);i++) {
  138.         DosRead (hImage, buf, 3, &ulBytesRead);
  139.         pbmiBitmap->argbColor[i].bRed   = buf[0];
  140.         pbmiBitmap->argbColor[i].bGreen = buf[1];
  141.         pbmiBitmap->argbColor[i].bBlue  = buf[2];
  142.       }
  143.     }
  144.  
  145.   ulBytesPerLine = ((pbmiBitmap->cBitCount * pbmiBitmap->cx + 31) / 32)
  146.                    * pbmiBitmap->cPlanes * 4;
  147.  
  148.   if (DosRead(hImage, buf, 1, &ulBytesRead))
  149.     return (-IDS_GIF_NOIMG);
  150.   if (LWZReadByte (hImage, TRUE, buf[0])<0)
  151.     return (-IDS_GIF_BOGUS);
  152.  
  153.   return(0);
  154. }
  155. /************************  End of procedure gifrhdr ************************/
  156.  
  157.  
  158.  
  159. /***********************  Start of procedure gifrrows  *********************/
  160. /*                                                                         */
  161. /* Gifrrows reads the given number of rows. There is no return value.      */
  162. /*                                                                         */
  163. /***************************************************************************/
  164. VOID gifrrows (HFILE hImage, BYTE *imbRowBuff, ULONG ulRowLength, ULONG ulNumRows)
  165. {
  166.   register int x, y;
  167.   BYTE     *imbTemp;
  168.  
  169.   for (y=(int)ulNumRows-1; y>=0; y--) {                    /* Row loop     */
  170.     imbTemp = imbRowBuff + y*ulBytesPerLine;
  171.     for (x=0; x<ulRowLength; x++)                          /* Column loop  */
  172.       imbTemp[x] = (BYTE)LWZReadByte (hImage, FALSE, 1024);
  173.   }
  174. }
  175. /***********************  End of procedure gifrrows  ***********************/
  176.  
  177.  
  178.  
  179. /***************************************************************************/
  180. /*                                                                         */
  181. /* I found this last part (the actual GIF decoder) lying around on our     */
  182. /* Unix server. It had the following disclaimer:                           */
  183. /*                                                                         */
  184. /* +------------------------------------------------------------------+    */
  185. /* | Copyright 1989, David Koblas.                                    |    */
  186. /* |   You may copy this file in whole or in part as long as you      |    */
  187. /* |   don't try to make money off it, or pretend that you wrote it.  |    */
  188. /* +------------------------------------------------------------------+    */
  189. /*                                                                         */
  190. /* Which I don't...                                                        */
  191. /*                                                                         */
  192. /***************************************************************************/
  193. int GetCode(HFILE fd, int code_size, int flag)
  194. {
  195.   static unsigned char   buf[280];
  196.   static int             curbit,lastbit,done,last_byte;
  197.   register int           i, j;
  198.   int                    ret;
  199.   unsigned char          count;
  200.  
  201.   if (flag) {
  202.     curbit = 0;
  203.     lastbit = 0;
  204.     done = FALSE;
  205.     return 0;
  206.   }
  207.  
  208.   if ( (curbit+code_size) >= lastbit) {
  209.     if (done) {
  210.       if (curbit>=lastbit)
  211.       exit(1);
  212.     }
  213.     buf[0] = buf[last_byte-2];
  214.     buf[1] = buf[last_byte-1];
  215.     DosRead(fd, &count, 1, &ulBytesRead);
  216.     if (count == 0)
  217.       done = TRUE;
  218.     else
  219.       DosRead(fd, &buf[2], count, &ulBytesRead);
  220.     last_byte = 2 + count;
  221.     curbit = (curbit - lastbit) + 16;
  222.     lastbit = (2+count)<<3 ;
  223.   }
  224.  
  225.   ret = 0;
  226.   for( i = curbit, j = 0; j < code_size; i++, j++ )
  227.     ret |= ((buf[i >> 3] & (1 << (i % 8))) != 0) << j;
  228.  
  229.   curbit += code_size;
  230.  
  231.   return ret;
  232. }
  233.  
  234. int LWZReadByte(HFILE fd, int flag, int input_code_size)
  235. {
  236.   static int      fresh=FALSE;
  237.   register int    i;
  238.   register int    code,incode;
  239.   static int      code_size,set_code_size;
  240.   static int      max_code,max_code_size;
  241.   static int      firstcode,oldcode;
  242.   static int      clear_code,end_code;
  243.   static int      table[2][(1<< MAX_LWZ_BITS)];
  244.   static int      stack[(1<<(MAX_LWZ_BITS))*2],*sp;
  245.  
  246.   if (flag) {
  247.     set_code_size = input_code_size;
  248.     code_size = set_code_size+1;
  249.     clear_code = 1 << set_code_size ;
  250.     end_code = clear_code + 1;
  251.     max_code_size = 2*clear_code;
  252.     max_code = clear_code+2;
  253.  
  254.     GetCode(fd,0,TRUE);
  255.  
  256.     fresh=TRUE;
  257.  
  258.     for (i=0;i<clear_code;i++) {
  259.       table[0][i] = 0;
  260.       table[1][i] = i;
  261.     }
  262.     for (;i<(1<<MAX_LWZ_BITS);i++)
  263.       table[0][i] = table[1][0] = 0;
  264.  
  265.     sp=stack;
  266.  
  267.     return 0;
  268.   } else if (fresh) {
  269.     fresh = FALSE;
  270.     do {
  271.       firstcode=oldcode=
  272.         GetCode(fd, code_size, FALSE);
  273.     } while (firstcode == clear_code);
  274.     return firstcode;
  275.   }
  276.  
  277.   if (sp > stack)
  278.   return *--sp;
  279.  
  280.   while ((code=GetCode(fd,code_size,FALSE))>=0) {
  281.     if (code == clear_code) {
  282.     for (i=0;i<clear_code;i++) {
  283.       table[0][i] = 0;
  284.       table[1][i] = i;
  285.     }
  286.     for (;i<(1<<MAX_LWZ_BITS);i++)
  287.       table[0][i] = table[1][i] = 0;
  288.       code_size = set_code_size+1;
  289.       max_code_size = 2*clear_code;
  290.       max_code = clear_code+2;
  291.       sp=stack;
  292.       firstcode=oldcode=GetCode(fd,code_size,FALSE);
  293.       return firstcode;
  294.     } else if (code == end_code) {
  295.       unsigned char  count;
  296.       unsigned char  junk;
  297.  
  298.       while ((DosRead(fd,&count,1,&ulBytesRead)==0) && (count!=0))
  299.         while (count-->0 && (DosRead(fd,&junk,1,&ulBytesRead)==0));
  300.       if (count!=0)
  301.       exit(1);
  302.     }
  303.  
  304.     incode = code;
  305.  
  306.     if (code >= max_code) {
  307.       *sp++ = firstcode;
  308.       code = oldcode;
  309.     }
  310.  
  311.     while (code >= clear_code) {
  312.       *sp++ = table[1][code];
  313.       if (code == table[0][code])
  314.         exit(1);
  315.       code = table[0][code];
  316.     }
  317.  
  318.     *sp++ = firstcode = table[1][code];
  319.  
  320.     if ((code=max_code)<(1<<MAX_LWZ_BITS)) {
  321.       table[0][code] = oldcode;
  322.       table[1][code] = firstcode;
  323.       max_code++;
  324.       if ((max_code >= max_code_size) &&
  325.         (max_code_size < (1<<MAX_LWZ_BITS))) {
  326.         max_code_size *= 2;
  327.         code_size++;
  328.       }
  329.     }
  330.  
  331.     oldcode = incode;
  332.  
  333.     if (sp > stack)
  334.       return *--sp;
  335.   }
  336.   return code;
  337. } /* LWZReadByte */
  338.