⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imggif.cc

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 CC
字号:
/**
 * imggif.c - interface for libgif input routines
 *
 * Copyright (c) 1998
 *      Transvirtual Technologies, Inc.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution 
 * of this file. 
 */

#include "defs.h"
#include "toolkit.h"

#include "qimage.h"

#if defined(HAVE_GIF_LIB_H) && (defined(HAVE_LIBGIF) || defined(HAVE_LIBUNGIF))
#define INCLUDE_GIF 1
#endif

#if defined(INCLUDE_GIF)
BEGIN_C_DECLS

#include "gif_lib.h"

END_C_DECLS
#endif


#if defined(INCLUDE_GIF)
static int iOffset[] = { 0, 4, 2, 1 };
static int iJumps[] = { 8, 8, 4, 2 };
#endif

int colordepth;
char *s;
/**************************************************************************************
 * internal functions
 */

#if defined(INCLUDE_GIF)
static void
writeRow ( Image* img, GifPixelType* rowBuf, GifColorType* cm, int row )
{
  int             idx, col;
  jint            rgb;
  unsigned long   pix;
  unsigned char   *imgData;
  imgData = img->qImg->scanLine(row);
  //fprintf(stderr,"img w=%d h=%d imgData %p\n",img->qImg->width(),img->qImg->height(),imgData);
//  memset(imgData,(char *)rowBuf,img->width);
  for ( col=0; col < img->width; col++ ) {
	idx = rowBuf[col];
	if ( img->qImg_AlphaMask/*img->xMask*/ && (idx == img->trans) ) {
	  pix = 0;
	  //fprintf(stderr,"alpha %d %d\n",col,row);
          img->qImg_AlphaMask->setPixel((int)col,(int)row,(uint)0);
	  //XPutPixel( img->xMask, col, row, 0);
	}
	else {
	  rgb = (cm[idx].Red << 16) | (cm[idx].Green << 8) | (cm[idx].Blue);
//	  pix = pixelValue( X, rgb);
	}
	//fprintf(stderr,"setting pixel %d %d %d\n",col,row,rgb);
	img->qImg->setPixel((int)col,(int)row,idx);	
//	XPutPixel( img->xImg, col, row, pix);
  }
}


#define CHECK(gifOp) \
  if ( gifOp == GIF_ERROR ) { \
    if ( img )    Java_java_awt_Toolkit_imgFreeImage( 0, 0, img); \
    if ( rowBuf ) AWT_FREE( rowBuf); \
    return 0; \
  }


static Image*
readGif ( GifFileType *gf )
{
  Image*          firstImg = 0;
  Image*	  img = 0;
  int             i, extCode, width, height, row, cmapSize;
  int             trans = -1, nFrames = 0, delay = 0;
  GifRecordType   rec;
  GifByteType     *ext;
  ColorMapObject  *cmap;
  GifColorType    *clrs;
  GifPixelType    *rowBuf = (GifPixelType*) AWT_MALLOC( gf->SWidth * sizeof( GifPixelType) );

  do {
	CHECK( DGifGetRecordType( gf, &rec));

	switch ( rec ) {
	case IMAGE_DESC_RECORD_TYPE:
	  CHECK( DGifGetImageDesc( gf));

	  width    = gf->Image.Width;
	  height   = gf->Image.Height;

      cmap     = (gf->Image.ColorMap) ? gf->Image.ColorMap : gf->SColorMap;
	  clrs     = cmap->Colors;
      cmapSize = cmap->ColorCount;

	  /*
	   * create our image objects and keep track of frames 
	   */
	  if ( !firstImg ) {     /* this is the first (maybe only) frame */
		firstImg = img = createImage( width, height);
		img->qImg = new QImage(width,height,colordepth);
		if(img->qImg->load(s)==FALSE) fprintf(stderr,"load image %s failed\n",s);
	  }
	  else {                 /* this is a subsequent gif-movie frame, link it in */
		img->next = createImage( width, height);
		img->next->qImg = new QImage(width,height,colordepth);
		if(img->next->qImg->load(s)==FALSE) fprintf(stderr,"load image %s failed\n",s);
		bool ok = FALSE;
		ok = reconvertImage(img);
		if (ok == FALSE) img->qpm->resize(0,0);
		img = img->next;
	  }

	  /*
	   * The trans index might have been cached by a preceeding extension record. Now
	   * that we have the Image object, it's time to store it in img and to create the
	   * mask
	   */
	  if ( trans != -1 ) {
		img->trans = trans;
		createXMaskImage( X, img);
		img->qImg->setAlphaBuffer(TRUE);
		img->qImg_AlphaMask = new QImage();
		if(img->qImg && img->qImg->hasAlphaBuffer());
		*(img->qImg_AlphaMask) = img->qImg->createAlphaMask();
		trans = -1;
	  }

	  /*
	   * Some browsers seem to assume minimal values, and some animations
	   * seem to rely on this. But there's no safe guess, so we
	   * skip it completely
	   */
/*
	  if ( delay == 0 )
		delay = 1000;
	  else if ( delay < 100 )
		delay = 100;
*/

	  img->latency = delay;
	  img->left = gf->Image.Left;
	  img->top = gf->Image.Top;
	  img->frame = nFrames;

	  nFrames++;
	  createXImage( X, img);
	  img->qImg = new QImage();
	  if(img->qImg->load(s) == FALSE) fprintf(stderr,"load %s failed",s);
	  /*
	   * start reading in the image data
	   */
	  if ( gf->Image.Interlace ) {
		/* Need to perform 4 passes on the images: */
		for ( i = 0; i < 4; i++ ) {
		  for (row = iOffset[i]; row < height; row += iJumps[i]) {
			memset( rowBuf, gf->SBackGroundColor, width);
			memset(img->qImg->scanLine(row),gf->SBackGroundColor,width);
			CHECK( DGifGetLine( gf, rowBuf, width));
			writeRow( img, rowBuf, clrs, row);
		  }
		}
	  }
	  else {
		for ( row = 0; row < height; row++) {
		  memset( rowBuf, gf->SBackGroundColor, width);
		  CHECK( DGifGetLine(gf, rowBuf, width));
		  memset (img->qImg->scanLine(row),gf->SBackGroundColor,width);
		  writeRow( img, rowBuf, clrs, row);
		}
	  }
	  break;

	case EXTENSION_RECORD_TYPE:
	  CHECK( DGifGetExtension( gf, &extCode, &ext));

	  if ( extCode == 0xf9 ) {   /* graphics extension */
		/*
		 * extension record with transparency spec are preceeding description records
		 * (which create new Images), so just cache the transp index, here
		 */
		if ( ext[1] & 1 ) {      /* transparent index following */
		  trans = ext[4];
		}
		delay = ((ext[3] << 8) | ext[2]) * 10; /* delay in 1/100 secs */
	  }
	  else if ( extCode == 0xff ) {  /* application extension block */
	  }

	  while ( ext != NULL ) {
		CHECK( DGifGetExtensionNext( gf, &ext));
	  }
	  break;

	case TERMINATE_RECORD_TYPE:
	  break;

	default:                /* Should be traps by DGifGetRecordType. */
	  break;
	}
  } while ( rec != TERMINATE_RECORD_TYPE );

  if ( firstImg && (img != firstImg) ){
	img->next = firstImg;   /* link it together (as a ring) */
  }
  //fprintf(stderr,"total frame = %d\n",nFrames);
  return firstImg;
}

/**************************************************************************************
 * memory buffer IO
 */

typedef struct {
  unsigned char *buf;
  unsigned char *p;
  long          remain;
} BufferSource;

static int
readGifBuffer ( GifFileType *gf, GifByteType* buf, int length )
{
  BufferSource *psource = (BufferSource*)gf->UserData;

  if ( psource && (psource->remain >= length) ) {
	memcpy( buf, psource->p, length);
	psource->p += length;
	psource->remain -= length;

	return length;
  }
  else {
	return 0;
  }
}

/*
 * intercept all file io and map it to AWT_xx file io maros
 * (in order to obtain thread safety)
 */
typedef struct {
  int fd;
} FileSource;

static int
readGifFileSource( GifFileType *gf, GifByteType* buf, int length )
{
  FileSource *psource = (FileSource*)gf->UserData;
  int n =  AWT_READ( psource->fd, buf, length);

  return (n < 0) ? 0 : n;
}

#endif /* INCLUDE_GIF */

/**************************************************************************************
 * these are the "exported" production interface functions
 */

Image*
readGifFile ( int infile, char *fn )
{
  Image          *img = 0;

#if defined(INCLUDE_GIF)

  /*
   * we don't use DGifOpenFile because file io might be intercepted
   * (because of threading)
   */
  FileSource     fileSrc;
  GifFileType    *gf;
  s=fn;
  QImage *tmp2 = new QImage(fn);
  colordepth = tmp2->depth();
  //fprintf(stderr,"colordepth %d %d %d\n",colordepth,tmp2->width(),tmp2->height());
  delete tmp2;
  fileSrc.fd = infile;

  if ( !(gf = DGifOpen( &fileSrc, readGifFileSource)) )
	{
	fprintf(stderr,"can't open gif file!!\n");
	return 0;
	}
  img = readGif( gf);

  DGifCloseFile( gf);
#endif

  return img;
}


Image*
readGifData ( unsigned char* buf, long len )
{
  Image          *img = 0;
#if defined(INCLUDE_GIF)
  BufferSource   bufSrc;
  GifFileType    *gf;
  QByteArray a;
  a.setRawData((char *)buf,sizeof(buf));
  QImage *tmp2 = new QImage(a);
  colordepth = tmp2->depth();
  delete tmp2;
  bufSrc.buf = bufSrc.p = buf;
  bufSrc.remain = len;

  if ( !(gf = DGifOpen( &bufSrc, readGifBuffer)) )
	return 0;

  img = readGif( gf);

  DGifCloseFile( gf);
  
#endif /* INCLUDE_GIF */

  return img;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -