#ifndef _GIF_PICTURE_
#define _GIF_PICTURE_

//http://www.hackhome.com/InfoView/Article_121692.html
//    GIF(Graphics Interchange Format)是CompuServe公司开发的图像文件存储格式，
//1987年开发的GIF文件格式版本号是GIF87a，1989年进行了扩充，扩充后的版本号定义
//为GIF89a。

//    GFI图像文件以数据块(block)为单位来存储图像的相关信息。一个GIF文件由表示
//图形/图像的数据块、数据子块以及显示图形/图像的控制信息块组成，称为GIF数据流
//(Data Stream)。数据流中的所有控制信息块和数据块都必须在文件头(Header)和文件
//结束块(Trailer)之间。

//    GIF文件格式采用了LZW(Lempel-Ziv Walch)压缩算法来存储图像数据，定义了允许
//用户为图像设置背景的透明(transparency)属性。此外，GIF文件格式可在一个文件中
//存放多幅彩色图形/图像。如果在GIF文件中存放有多幅图，它们可以像演幻灯片那样显
//示或者像动画那样演示。

//    GIF格式中的调色板有通用调色板和局部调色板之分，因为GIF格式允许一个文件中存储多个
//图像，因此有这两种调色板，其中通用调色板适于文件中的所有图像，而局部调色板只适用于某
//一个图像。格式中的数据区域一般分为四个部分，图像数据识别区域，局部调色板数据，采用压
//缩算法得到的图象数据区域和结束标志区域。

//GIF文件头
struct GIF_HEADER 
{
	BYTE  bySignature[3]; //署名，
	BYTE  byVersion[3];	 //版本号，"87a"表1987年5月版本，"89a"表1989年7月版本
};

//逻辑屏幕标识符
struct GIF_SCREEN 
{
	WORD  wScreenWidth; //逻辑屏幕宽度
	WORD  wScreenHeight; //逻辑屏幕高度
	struct  flag
	{
		BYTE size:3; //全局颜色列表大小，等于2的size+1次方.
		BYTE s:1; //分类标志(Sort Flag)，如果置位表示全局颜色列表分类排列.
		BYTE cr:3; //颜色深度(Color ResoluTion)，cr+1确定图象的颜色深度.
		BYTE g:1; //全局颜色列表标志(Global Color Table Flag)。
	}Flag;
	BYTE  byBackColorIndex; //背景色索引
	BYTE  byAspectRatio; //像素宽高比 Aspect Ratio = (W / H + 15) / 64
};

//GIF文件的调色板
struct GIF_RGBQUAD
{
	BYTE rgbRed;
	BYTE rgbGreen;
	BYTE rgbBlue;
};


//图形控制扩展块
struct GIF_CONTROL_EX 
{
	BYTE byFlags1;  //扩展块，恒定于0x21
	BYTE byFlags2;  //图形控制扩展块，恒定于0xF9
	BYTE bySize;    //不包括块终结器，固定值4
	struct  flag
	{
		BYTE t:1; //透明色标志,置位表示使用透明颜色
		BYTE i:1; //用户输入标志
					//指出是否期待用户有输入之后才继续进行下去，置位表示期待，值否
					//表示不期待。用户输入可以是按回车键、鼠标点击等，可以和延迟
					//时间一起使用，在设置的延迟时间内用户有输入则马上继续进行，或
					//者没有输入直到延迟时间到达而继续。

		BYTE method:3; //处置方法
							//0 - 不使用处置方法
							//1 - 不处置图形，把图形从当前位置移去
							//2 - 回复到背景色
							//3 - 回复到先前状态
							//4-7 - 自定义
		BYTE reserved:3; //保留
	}Flag;
	WORD wDelayTime; //单位1/100秒，如果值不为1，表示
							//暂停规定的时间后再继续往下处理数据流
	BYTE byTransparentIndex; //透明色索引值

	BYTE byTerminator; //标识块终结，固定值0
};

//图像描述块
struct GIF_DESCRIPTOR 
{
	BYTE  byFlags;      //图象标识符开始标志，恒定于0x2C
	WORD  wImageLeft;   //图象相对于逻辑屏幕左上角的x坐标，常为0；
	WORD  wImageTop;    //图象相对于逻辑屏幕左上角的y坐标，常为0
	WORD  wImageWidth;  //图象的宽度
	WORD  wImageHeight; //图象的高度
	struct flag
	{
		BYTE size:3; //局部颜色列表大小，size+1就为颜色列表的位数
		BYTE r:2; //保留，必须初始化为0.
		BYTE s:1; //分类标志，如果置位表示紧跟着的局部颜色列表分类排列.
		BYTE i:1; //交织标志，置位时图象数据使用连续方式排列，否则使用顺序排列。
		          //交织时每隔八行组行一组
		BYTE g:1; //局部颜色列表标志。
	}Flag;
};


/*

  GIF图象数据使用了LZW压缩算法，大大减小了图象数据的大小。图象数据在压缩前有两种
  排列格式：连续的和交织的(由图象标识符的交织标志控制)。连续方式按从左到右、从上
  到下的顺序排列图象的光栅数据；交织图象按下面的方法处理光栅数据：

  创建四个通道(pass)保存数据，每个通道提取不同行的数据：
  第一通道(Pass 1)提取从第0行开始每隔8行的数据；
  第二通道(Pass 2)提取从第4行开始每隔8行的数据；
  第三通道(Pass 3)提取从第2行开始每隔4行的数据；
  第四通道(Pass 4)提取从第1行开始每隔2行的数据；
*/


//注释扩展块
struct GIF_COMMENT_EX
{
	BYTE byFlags1;  //扩展块，恒定于0x21
	BYTE byFlags2;  //图形控制扩展块，恒定于0xFE

	// + 多个 Comment Data
	// + Terminator - 标识块终结，固定值0

};

//图形文本扩展块
struct GIF_TEXT_EX 
{
	BYTE byFlags1;  //扩展块，恒定于0x21
	BYTE byFlags2;  //图形文本控制扩展块，恒定于0x01
	BYTE bySize;    //块大小，固定值12
	WORD wTextLeft; //文本框离逻辑屏幕的左边界距离
	WORD wTextTop;  //文本框离逻辑屏幕的上边界距离
	WORD wTextWidth;//文本框宽度
	WORD wTextHeight;//文本框高度

	BYTE byCellWidth;//单个单元格宽度
	BYTE byCellHeight;//单个单元格宽度
	BYTE byForegroundIndex;//前景色在全局颜色列表中的索引
	BYTE byBlackgroundIndex;//背景色在全局颜色列表中的索引

	// + 多个 Text Data
	// + Terminator - 标识块终结，固定值0

};

//应用程序扩展块
struct GIF_APPLICATION_EX
{
	BYTE byFlags1;  //扩展块，恒定于0x21
	BYTE byFlags2;  //应用程序扩展块，固定值0xFF
	BYTE bySize;    //块大小，固定值11
	BYTE byIdentify[8];//应用程序标识符
	BYTE byAuthenticationCode[3];//应用程序鉴别码

	// + 多个  Data
	// + Terminator - 标识块终结，固定值0

};

#include <Memory.h>

struct GIF_XMSHEADER
{
	WORD  wFlags;
	BYTE  byMethod;
	BYTE  byTransparent;
	WORD  wTransparentIndex;
	WORD  wTime;

	DWORD dwLoc;
};

#define XMSMEMORY_GIFHEADER_COUNT 1024
#define XMSMEMORY_GIFHEADER_LENGTH \
	(1L * sizeof(GIF_XMSHEADER) * \
	XMSMEMORY_GIFHEADER_COUNT + \
	256L * (1 + sizeof(GIF_RGBQUAD)))

#define XMSMEMORY_GIFHEADER_FLAG  0xA55Au

int DisplayGifFile(int nLeft, int nTop, const char* pStrFile,
	int nPage, BOOL bDisplay);

int DisplayGifFile(int nLeft, int nTop,
	CXmsMemory* pXmsMemory, DWORD dwXmsIndex,
	int nPage, BOOL bDisplay, BOOL bInit);

long DisplayGIFDescriptor(int nLeft, int nTop,
	CXmsMemory* pXmsMemory, DWORD lgFilePoint,
	GIF_RGBQUAD* pGlobalQuad,
	BOOL bTransparent, int nBackColor,
	BYTE* buffer, BYTE* pbyOut, BOOL bDisplay);

#endif
