예제 #1
0
/*
 * Reads the GIF screen and the global color table.
 */
void GIFReadScreen(struct GIFScreen *screen, FILE *stream)
{
    unsigned char buffer[7];

    GIF_TRACE(("Reading Header\n"));
    GIF_FREAD(buffer, 6, stream);
    if (memcmp(buffer, "GIF", 3) != 0)
        GIFError("Not a GIF file");
    if ((memcmp(buffer + 3, "87a", 3) != 0) &&
            (memcmp(buffer + 3, "89a", 3) != 0))
        GIFWarning("Invalid GIF version number, not \"87a\" or \"89a\"");

    GIF_TRACE(("Reading Logical Screen Descriptor\n"));
    GIF_FREAD(buffer, 7, stream);
    screen->Width            = GIF_GETW(buffer + 0);
    screen->Height           = GIF_GETW(buffer + 2);
    screen->GlobalColorFlag  = (buffer[4] & 0x80) ? 1 : 0;
    screen->ColorResolution  = ((buffer[4] & 0x70) >> 3) + 1;
    screen->SortFlag         = (buffer[4] & 0x08) ? 1 : 0;
    screen->GlobalNumColors  = 2 << (buffer[4] & 0x07);
    screen->Background       = buffer[5];
    screen->PixelAspectRatio = buffer[6];

    if (screen->GlobalColorFlag)
    {
        GIF_TRACE(("Reading Global Color Table\n"));
        GIF_FREAD(screen->GlobalColorTable, 3 * screen->GlobalNumColors,
            stream);
    }

    GIF_TRACE(("Validating Logical Screen Descriptor\n"));
    if (screen->Width == 0 || screen->Height == 0)
        GIFError("Invalid image dimensions");
    if (screen->Background > 0)
    {
        if ((screen->GlobalColorFlag &&
             (screen->Background >= screen->GlobalNumColors)) ||
            !screen->GlobalColorFlag)
        {
#if 0       /* too noisy */
            GIFWarning("Invalid background color index");
#endif
            screen->Background = 0;
        }
    }
}
예제 #2
0
static int GIFReadDataBlock(unsigned char *buffer, FILE *stream)
{
    int count;

    GIF_FGETC(count, stream);
    DataBlockSize = count;
    if (count > 0)
    {
        GIF_FREAD(buffer, (unsigned int)count, stream);
    }
    return count;
}
예제 #3
0
/*
 * Reads the next GIF image and local color table.
 */
static void GIFReadNextImage(struct GIFImage *image, FILE *stream)
{
    struct GIFScreen *screen;
    unsigned char    buffer[9];

    GIF_TRACE(("Reading Local Image Descriptor\n"));
    GIF_FREAD(buffer, 9, stream);
    if (image == NULL)
    {
        GIFSkipDataBlocks(stream);
        return;
    }

    image->LeftPos        = GIF_GETW(buffer + 0);
    image->TopPos         = GIF_GETW(buffer + 2);
    image->Width          = GIF_GETW(buffer + 4);
    image->Height         = GIF_GETW(buffer + 6);
    image->LocalColorFlag = (buffer[8] & 0x80) ? 1 : 0;
    image->InterlaceFlag  = (buffer[8] & 0x40) ? 1 : 0;
    image->SortFlag       = (buffer[8] & 0x20) ? 1 : 0;
    image->LocalNumColors = image->LocalColorFlag ? (2 << (buffer[8] & 0x07)) : 0;

    if (image->LocalColorFlag)
    {
        GIF_TRACE(("Reading Local Color Table\n"));
        GIF_FREAD(image->LocalColorTable, 3 * image->LocalNumColors, stream);
    }

    GIF_TRACE(("Validating Logical Screen Descriptor\n"));
    screen = image->Screen;

    if (image->Width == 0 || image->Height == 0 ||
            image->LeftPos + image->Width > screen->Width ||
            image->TopPos + image->Height > screen->Height)
        GIFError("Invalid image dimensions");

    GIFReadImageData(image, stream);
}
예제 #4
0
//函数调用了一个定位文件和读文件的函数
//调用前将pgif->fp定位到lzw开始,初始化pgif的调色板等显示参数
void GIFShowImage(GIF *pgif)
{
	LZW lzw;					//保存lzw解压缩参数
	u8 temp;
	GIFImageDescriptor imagedes;	//gif图像描述
	GraphicControlExtension gce;	//图像扩展
	u8 blockflag;
	
	GIF_FREAD((UINT8*)&imagedes, sizeof(GIFImageDescriptor), pgif->fp);//帧图像描述块

	pgif->Interlace = imagedes.ColorFlag.InterlaceFlag;
	pgif->width = imagedes.Width;
	pgif->height = imagedes.Height;
	pgif->curx = 0;
	pgif->cury = 0;

	//lzw解码
	GIF_FREAD(&temp, sizeof(u8),pgif->fp);	//lzw编码长度
	LzwInit(LzwTable, temp, &lzw,pgif->fp);			//初始化管理结构体
	LzwStart(&lzw,pgif);		//解码输出
	GIF_FSEEK(pgif->fp, 1, FSEEK_CUR);		//跳过块结束标记


}
예제 #5
0
static void GIFSkipDataBlocks(FILE *stream)
{
    int           count;
    unsigned char buffer[GIF_UCHAR_MAX + 1];

    for ( ; ; )
    {
        GIF_FGETC(count, stream)
        if (count > 0)
        {
            GIF_FREAD(buffer, (unsigned int)count, stream);
        }
        else
            return;
    }
}
예제 #6
0
//打开一个gif图像,需用GIFShowImage输出
//成功返回0
u8 GIFOpen(GIF *pgif,struct FileInfo *fp)
{
	GIFLSDescriptor ls;				//gif逻辑屏幕描述
	u8 blockflag;					//块标记 数据块:; ......
	GraphicControlExtension gce;		//图形扩展
	
	pgif->fp = fp;
	GIF_FSEEK(pgif->fp, sizeof(GIFHeader), FSEEK_SET);	//跳过文件头
	GIF_FREAD((UINT8*)&ls, sizeof(GIFLSDescriptor), pgif->fp);//逻辑屏幕描述 40byte
	if (ls.ColorFlag.GlobalColorTableFlag)			//如果有全局调色板
	{
//		pgif->globleClrTable = new GIFRGBITEM[1 << (ls.ColorFlag.Pixel + 1)];
			GIF_FREAD((UINT8*)(pgif->globleClrTable), sizeof(GIFRGBITEM)*(1 << (ls.ColorFlag.Pixel + 1)), pgif->fp);
	}
	else
		pgif->globleClrTable = NULL;

	pgif->scWidth = ls.Width;
	pgif->scHeight = ls.Height;
	
	pgif->bkColorIndex = ls.BackColor;
	pgif->DelayTime = 0;	//初始化为静态图
	pgif->TransparentColorFlag = 0;	//默认无透明色


	pgif->skimage = pgif->fp->File_CurOffset;
	//读取各种控制块
	while (1)
	{
		GIF_FREAD(&blockflag, 1, pgif->fp);
		if (blockflag == ',')	//帧图像数据(2C)
		{
	//保存该位置指针
			return 0;
		}
		else if (blockflag == 0x21)	//扩展块
		{
			GIF_FREAD(&blockflag, 1, pgif->fp);
			if (blockflag == 0xF9)		//图形控制扩展块
			{
					GIF_FREAD((UINT8*)&gce, sizeof(GraphicControlExtension), pgif->fp);
				pgif->DelayTime = gce.DelayTime;			//本帧图像延时
				pgif->TransparentColorFlag = gce.Flag.TransparentColorFlag;//透明标志
				pgif->DisposalMethod = gce.Flag.DisposalMethod;	//处理方法
				pgif->TransparentColorIndex = gce.TransparentColorIndex;	//透明色引索

				GIF_FSEEK(pgif->fp, 1, FSEEK_CUR);	//块结束标记
			}
			else if (blockflag == 0xFF)//应用程序扩展
			{
				GIF_FSEEK(pgif->fp, sizeof(ApplicationExtension), FSEEK_CUR);
				//跳过应用数据
				while (1)
				{
					GIF_FREAD(&blockflag,  1, pgif->fp);	//应用程序数据大小
					if (blockflag == 0)break;
					else
						GIF_FSEEK(pgif->fp, blockflag, FSEEK_CUR);
				}
			}
			else if (blockflag == 0xFE)	//跳过注释扩展块
			{
				while (1)
				{
					GIF_FREAD(&blockflag, 1, pgif->fp);
					if (blockflag == 0)break;
					else
					GIF_FSEEK(pgif->fp, blockflag, FSEEK_CUR);
				}

			}
			else if (blockflag == 0x01)	//跳过图形文本扩展
			{
				GIF_FSEEK(pgif->fp, sizeof(PlainTextExtension), FSEEK_CUR);
				while (1)
				{
					GIF_FREAD(&blockflag,  1, pgif->fp);
					if (blockflag == 0)break;
					else
						GIF_FSEEK(pgif->fp, blockflag, FSEEK_CUR);
				}
			}
			else
			{
				return 2;
			}
		}
		else if (blockflag == ';')				//文件结束
		{
			return 3;	//文件结束
		}
		else
		{
			return 1;
		}
	}
}