gifmodify.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:6k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/gifmodify.c 1.2 1999/08/03 16:08:19 amb Exp $
  3.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.5.
  4.   A function for filtering GIF data streams in order to "disable" the mostly
  5.   annoying animations.
  6.   ******************/ /******************
  7.   Written by Ingo Kloecker
  8.   Modified by Andrew M. Bishop
  9.   Copyright 1999 Ingo Kloecker
  10.   This file may be distributed under the GNU Public License, version 2, or
  11.   any higher version.  See section COPYING of the GNU Public license
  12.   for conditions under which this file may be redistributed.
  13.   ***************************************/
  14. #include <string.h>
  15. #include "wwwoffle.h"
  16. #include "document.h"
  17. #include "errors.h"
  18. /*
  19.   OutputGIFWithModifications - function to disable the animation of GIF89a files
  20.   Short description:
  21.   In order to "disable" the animation the function searches for Graphic
  22.   Control Extension and sets the delay time for the following image to
  23.   655.35 seconds (which is the maximal possible setting as for example
  24.   the Netscape Navigator misinterprets a value of 0 as no delay instead of 
  25.   infinite delay).
  26.   The GIF89a Specification of CompuServe Inc. says the following about the
  27.   delay time:
  28.     "Delay Time - If not 0, this field specifies the number of
  29.                   hundredths (1/100) of a second to wait before
  30.      continuing with the processing of the Data Stream."
  31.   and
  32.     "In the absence of a specified Delay Time, the decoder should wait
  33.      for user input indefinitely."
  34.   
  35.   Here you can find more information about the structure of GIF files:
  36.   http://members.aol.com/royalef/gifabout.htm
  37. */
  38. void OutputGIFWithModifications(int client,int spool,URL *Url)
  39. {
  40.  int bytes_to_skip=0;
  41.  unsigned char blocktype='t';
  42.  int pHeader=0;
  43.  char GIFHeader[7];
  44.  int colors;
  45.  int colorbits;
  46.  int filterGIF = 1;
  47.  char gifstream[READ_BUFFER_SIZE];
  48.  int n;
  49.  while((n=read_data(spool,gifstream,READ_BUFFER_SIZE))>0)
  50.    {
  51.     int offset=0;
  52.     while ((filterGIF == 1) && (bytes_to_skip+offset < n)) {
  53.      offset += bytes_to_skip;
  54.      bytes_to_skip = 0;
  55.      if (blocktype==0) {
  56.       /* Identify next block */
  57.       blocktype = gifstream[offset];
  58.       switch (blocktype) {
  59.       case ',': /* Image Descriptor */
  60.        /* PrintMessage(Debug,"Image Descriptor Block"); */
  61. bytes_to_skip=9; /* skip unnecessary information */
  62. break;
  63.       case '!': /* Extension Block */
  64.        /* PrintMessage(Debug,"Extension Block"); */
  65. bytes_to_skip=1; /* skip to Extension Block Identifier */
  66. break;
  67.       case ';': /* GIF Terminator */
  68.        /* PrintMessage(Debug,"Terminator Block"); */
  69. filterGIF = 0; /* end filtering of GIF file */
  70. break;
  71.       default : /* Unknown Block */
  72.        /* PrintMessage(Debug,"Unknown Block Type %d in GIF file.", blocktype); */
  73. filterGIF = -1;
  74.       }
  75.     }
  76.     else {
  77.       switch (blocktype) {
  78.       case 't': /* Checking GIF-Header */
  79. if (pHeader<5) { /* If Header hasn't been completely read */
  80.   GIFHeader[pHeader]=gifstream[offset];
  81.   pHeader++;
  82.   bytes_to_skip=1;
  83. }
  84. else {
  85.   GIFHeader[pHeader]=gifstream[offset];     
  86.   GIFHeader[6]='';
  87.   if (!strncmp(GIFHeader,"GIF89a",6)) {
  88.            /* PrintMessage(Debug,"File is a GIF89a."); */
  89.     filterGIF = 1;
  90.     bytes_to_skip=1+4; /* skip unnecessary information */
  91.     blocktype='G';
  92.   }
  93.   else
  94.     filterGIF = 0;
  95. }
  96. break;
  97.       case 'G': /* Inside Logical Screen Descriptor */
  98. /* If Global Color Map exists */
  99. if (gifstream[offset] & 0x80) {
  100.   colorbits = gifstream[offset] & 0x07;
  101.   colors=2;
  102.   for (; colorbits>0; colorbits--)
  103.     colors*=2;
  104. }
  105. else
  106.   colors=0;
  107.         /* PrintMessage(Debug,"Global Color Map has %d colors.",colors); */
  108. /* skip last 3 bytes of Logical Screen Descr. and optional GCM */
  109. bytes_to_skip=3+3*colors;
  110. blocktype=0;
  111. break;
  112.       case ',': /* Image Descriptor */
  113. /* If Local Color Map exists */
  114. if (gifstream[offset] & 0x80) {
  115.   colorbits = gifstream[offset] & 0x07;
  116.   colors=2;
  117.   for (; colorbits>0; colorbits--)
  118.     colors*=2;
  119. }
  120. else {
  121.   colors=0;
  122. }
  123.         /* PrintMessage(Debug,"Image has %d colors.",colors); */
  124. /* skip last byte of Image Descr., optional LCM and first byte of Raster Data Stream (LZW Minimum Code Size) */
  125. bytes_to_skip=1+3*colors+1;
  126. blocktype='D'; /* set blocktype to Data Block */
  127. break;
  128.       case 'D': /* Data Block */
  129. bytes_to_skip=1+gifstream[offset];
  130. if (bytes_to_skip < 1)
  131.   bytes_to_skip += 256; 
  132.         /* PrintMessage(Debug,"Inside Data Block (blocksize=%d).",bytes_to_skip-1); */
  133. if (bytes_to_skip == 1) /* If end of Block reached */
  134.   blocktype=0; /* reset blocktype */
  135. break;
  136.       case '!': /* Extension Block */
  137. /* Falls Graphics Control Extension Block */
  138. if (gifstream[offset]=='371') {
  139.          /* PrintMessage(Debug,"Graphics Control Extension Block."); */
  140.   bytes_to_skip=3; /* goto delay time entry */
  141.   blocktype='1';
  142. }
  143. else { /* skip this block */
  144.          /* PrintMessage(Debug,"Other Extension Block."); */
  145.   bytes_to_skip=1;
  146.   blocktype='D';
  147. }
  148. break;
  149.       case '1': /* first byte of delay time */
  150. /* set delay time to maximum (0xFFFF = 655.35s) */
  151.        /* PrintMessage(Debug,"1st byte of delay time was %d",gifstream[offset]); */
  152. gifstream[offset]=255;
  153. bytes_to_skip=1; /* goto second byte of delay time entry */
  154. blocktype='2';
  155. break;
  156.       case '2': /* second byte of delay time */
  157.        /* PrintMessage(Debug,"2nd byte of delay time was %d",gifstream[offset]); */
  158. gifstream[offset]=255;
  159. bytes_to_skip=3; /* skip rest of GCE block */
  160. blocktype=0;
  161. break;
  162.       }
  163.     }
  164.   }
  165.   if (filterGIF == 1) {
  166.     bytes_to_skip -= n-offset;
  167.   }
  168.   write_data(client,gifstream,n);
  169.  }
  170. }