示例#1
0
void GifDecode(FILE *fp, UBYTE *pix, GifImageHdr gifimage)
{ UBYTE *chPos, firstCodeOut = 0, charBuff[256];
  ULONG CLEAR, EOI, bits = 0, code = 0, codeFeched, buffCount = 0;
  int need = 0;

  interlaced = gifimage.i;
  imgwidth = gifimage.width;
  imgheight = gifimage.height;
  imgsize = imgwidth * imgheight;
  picture = pix;
  pass = picI = 0;
  if ( debugFlag > 1 )
     fprintf(stderr, "(interlaced,imgwidth,imgheight,imgsize)=(%d,%d,%d,%d)\n",
		interlaced, imgwidth, imgheight, imgsize);

  rootCodeSize = Xgetc(fp);
  CLEAR = 1 << rootCodeSize;
  EOI = CLEAR + 1;

  GifClearTable();

  if ( (buffCount = Xgetc(fp)) == 0 ) {
    sprintf(charBuff, "End of image # %d before it began!\n", count);
    TheEnd1(charBuff);
  }

  while(buffCount > 0) {
    if ( fread(charBuff, 1, buffCount, fp) != buffCount ) { 
      sprintf(charBuff, "Premature end of file; Image # %d\n", count);
      TheEnd1(charBuff);
    }
    for(chPos = charBuff; buffCount-- > 0; chPos++) {
      need += (int) *chPos << bits;
      bits += 8;
      while (bits >= codeSize) {
	code = need & mask;
	need >>= codeSize;
	bits -= codeSize;
	if(code > expected)
	   TheEnd1("Neither LZW nor RunLength (new code != expected)\n");
	if (code == EOI) {
	  if (debugFlag > 1) fprintf(stderr, "Image # %d ends; buffCount=%d\n",
			count, buffCount);
	  goto skipRest;
	}

	if(code == CLEAR) {
	GifClearTable();
	continue;
	}
	if(old == MAXVAL) {  /* i.e. first code after clear table */
	  pix = GifSendData(pix, 1, &last[code]);
	  firstCodeOut = last[code];
	  old = code;
	  continue;
	}
	codeFeched = code;
	if(code == expected) {
	  *topGifBuff++ = firstCodeOut;
	  code = old;
	}
	while(code > CLEAR) {
	  *topGifBuff++ = last[code];
	  code = first[code];
	}

	*topGifBuff++ = firstCodeOut = last[code];
	first[expected] = old;
	last[expected] = firstCodeOut;
	if(expected < MAXVAL) expected++;
	if(((expected & mask) == 0) && (expected < MAXVAL)) {
	  codeSize++;
	  mask += expected;
	}
	old = codeFeched;
	pix = GifSendData(pix, topGifBuff - gifBuff, gifBuff);
	topGifBuff = gifBuff;

      }   /* end of extracting codes */
    }   /* end of reading a block of data */
    if ( (buffCount = Xgetc(fp)) == 0 ) {
      sprintf(charBuff, "End of image # %d without EOI\n", count);
      TheEnd1(charBuff);
    }
  }

skipRest: 
  if (debugFlag) fprintf(stderr, "Ending GifDecode, written: %d=%d\n",
	  interlaced && (pix-picture == 0) ? imgsize : pix - picture, imgsize);
  return ;
}
示例#2
0
/*
 * Read a Gif file.
 */
void animate_gif(FILE *fout,char *fname,int firstImage,int Xoff,int Yoff,
		 int delay_time,int loop_val) /* time in 100th of seconds */
{
  FILE *fp;
  UBYTE *pix;
  int i;
  if ( (fp = fopen(fname, REABIN)) == 0) {
    fprintf(stderr, "Can't open %s for reading.\n", fname);
    TheEnd();
  }
     global.trans.type = TRANS_NONE;
     global.trans.valid = 0;
     global.time = delay_time;

     global.disposal = DEFAULT_DISPOSAL;
    global.left = Xoff;
    global.top = Yoff;

    loop=loop_val;
     /*   loop = TRUE; */
           /* loopcount = 0; */
   
   
  /*global.left = global.top = 0;*/
   
   
   GifScreenHeader(fp, fout, firstImage);

   /* read until , separator */
  do {
    switch ( i = Xgetc(fp)) {
      case ',':
      case '\0':
	break;
      case '!':
	Xgetc(fp); /* the extension code */
	for ( i = Xgetc(fp); i > 0; i-- ) Xgetc(fp);
	while ( ( i = Xgetc(fp) ) > 0 ) {
	  for ( i = i ; i > 0; i-- ) Xgetc(fp);
	}
	break;
      default:
	fclose(fp);
	if ( feof(fp) || i == ';' )
	TheEnd1("GifReadHeader: Unexpected End of File\n");
	TheEnd1("GifReadHeader: Unknown block type\n");
     }
   } while(i != ',');

  if(firstImage) {
    globscrn.m = gifscrn.m;
    globscrn.pixbits = gifscrn.pixbits;
    globscrn.bc = gifscrn.bc;
    if ( globscrn.m ) {
      for (i = gifMask[1+globscrn.pixbits]; i >= 0; i--) {
	gifGmap[i].cmap.red   = gifCmap[i].cmap.red;
	gifGmap[i].cmap.green = gifCmap[i].cmap.green;
	gifGmap[i].cmap.blue  = gifCmap[i].cmap.blue;
      }
    }
    if(loop) GifLoop(fout, loopcount);
  }

  ReadImageHeader(fp);

 /*** ACTION for IMAGE */

  if ( ( gifimage.m != 0 && globmap !=0 ) || minimize !=0 ) {
    UBYTE translator[256], *p, *po;
    int left, right=0, top, bot=0, i, j, k, l, hi, wi;
    long dsquare, dsquare1;
    hi = gifimage.height;
    wi = gifimage.width;
    if (( pix = (UBYTE *)malloc(wi * hi * sizeof(UBYTE)) ) == NULL )
	 TheEnd1("No memory for image\n");
    if (debugFlag) fprintf(stderr, "  decoding picture no %d\n", count);
    GifDecode(fp, pix, gifimage);
    gifimage.i = 0;
    k = gifMask[1+globscrn.pixbits]; 
    l = gifMask[1+gifscrn.pixbits]; 
    for (j = 0; j <= l; j++) {
      dsquare = 256*256*3;
      for (i = 0; i <= k; i++) {
	dsquare1 = sq(gifGmap[i].cmap.red, gifCmap[j].cmap.red) +
		   sq(gifGmap[i].cmap.green, gifCmap[j].cmap.green) +
		   sq(gifGmap[i].cmap.blue,  gifCmap[j].cmap.blue);
	if ( dsquare1 < dsquare ) {
	  dsquare = dsquare1;
	  translator[j]=i;
	  if ( dsquare == 0 ) break;
	}
      }
    }
    gifimage.m = 0;
    gifscrn.pixbits = globscrn.pixbits;
    if (debugFlag) fprintf(stderr, "  translating picture no %d\n", count);
    for (i = wi * hi -1; i>=0; i--)
      pix[i]=translator[pix[i]];
    if ( minimize != 0 && pixold != NULL  && hi == gifimageold.height
	&& wi == gifimageold.width && gifimage.top == gifimageold.top
	&& gifimage.left == gifimageold.left ) {
      gifimageold = gifimage;
/* First test from left to right, top to bottom */
      p = pix; po = pixold;
      for (i = 0; i < hi; i++ ) {
	for (j = 0; j < wi; j++ ) {
	  if ( *p++ != *po++ ) {
	    left = j; top=i;
	    goto done;
	  }
	}
      }
      if (FALSE) { 
done: /* i.e. a preliminary left and top found */ ;
      }
      else goto alike; /* writes full image, should we drop it ? */
/* Then test from right to left, bottom to top */
      k=hi*wi-1; 
      p = &pix[k]; po = &pixold[k];
      for (i = hi-1; i >= top; i-- ) {
	for (j = wi -1; j >= 0; j-- ) {
	  if ( *p-- != *po-- ) {
	    right = j; bot=i;
	    goto botfound;
	  }
	}
      }
botfound:
/* The form of the differing area (not rectangle) may be slanted */
      if ( right < left ) {
	i = right; right = left; left = i;
      }
/* Now test between top and bottom at the left hand side */
      for (i = top+1; i <= bot; i++ ) {
	k= i * wi;
	p = &pix[k]; po = &pixold[k];
	for (j = 0; j < left; j++ ) {
	  if ( *p++ != *po++ ) {
	    left = j;
	    break;
	  }
	}
      }
/* Finally test between bottom and top at the right hand side */
      for (i = bot-1; i >= top; i-- ) {
	k= (i+1) * wi-1;
	p = &pix[k]; po = &pixold[k];
	for (j = wi-1; j > right; j-- ) {
	  if ( *p-- != *po-- ) {
	    right = j;
	    break;
	  }
	}
      }
      gifimage.left += left;
      gifimage.top += top;
      gifimage.width = right-left+1;
      gifimage.height = bot-top+1;
      WriteImageHeader(fout);
/* The rectangle containing diffs is transferred to the mem area of pixold */
      po = pixold;
      for (i = top; i <= bot; i++ ) {
	p = &pix[i * wi+left];
	for (j = left; j <= right; j++ ) {
	  *po++ = *p++;
	}
      }
      GifEncode(fout, pixold, gifscrn.pixbits+1, gifimage.height * gifimage.width);
      if (debugFlag)
	fprintf(stderr, "  encoded: width= %d, height = %d, left = %d, top = %d\n",
	   gifimage.width, gifimage.height, gifimage.left, gifimage.top);
    }
    else {
alike:
      WriteImageHeader(fout);
      gifimageold = gifimage;
      GifEncode(fout, pix, gifscrn.pixbits+1, gifimage.height * gifimage.width);
      if (debugFlag) fprintf(stderr, "  picture re-encoded\n");
    }
    free(pixold);
    pixold = pix;
    fputc(0, fout);    /* block count of zero */
  }
  else {
    WriteImageHeader(fout);
    i = Xgetc(fp); fputc(i, fout); /* the LZW code size */
    while ( ( gifBlockSize = Xgetc(fp) ) > 0 ) {
      fputc(gifBlockSize, fout);
      while ( gifBlockSize-- > 0 ) fputc(Xgetc(fp),fout);
    }
    if ( gifBlockSize == 0 ) fputc(gifBlockSize, fout);
    else TheEnd1("GifPassing: Unexpected End of File\n");
  }

  fclose(fp);
}