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

📄 gif_pic.c

📁 GIF图片解压成RGB格式的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
			}

			if(TableIndex < LZW_MAXCODES && PrefixCode != NOCODE )
			{
				//PrefixTable[TableIndex] = PrefixCode;
				PrefixTable[2*TableIndex+0] = PrefixCode & 0xff;
				PrefixTable[2*TableIndex+1] = PrefixCode>>8;
				SuffixTable[TableIndex++] = SuffixCode;
				if( TableIndex >= MaxCodeSize && RunBits < LZW_MAXBITS )
				{
					MaxCodeSize <<= 1;
					RunBits++;
				}
			}

			PrefixCode = LastCode;
		}
	}
	NepFree(StackTable);
	return RetVal;
}
/***************************************************
 功能: 将一个字节只存一点的单色图象数据,准换成一个字节存放8点;或者将一个字节只村1点的16色
       图象数据,转换成4个Bit Planes的数据排列形式,每次转换只处理一行数据量
       存储单元,在读取该文件内的识别信息和图象数据
 输入: Img ==> 存放Image数据结构的存储单元指针
       LineBuf ==> 图象文件的文件指针
	   LineCount ==> 代表图象的行树
	   LineBytes ==> 一行的字节数
 输出:
 返回:
***************************************************/
static void GetGifLine(Image *Img, BYTE* LineBuf, WORD LineCount, WORD LineBytes)
{
	BYTE* ImgBuf;
	BYTE  Data;

	WORD  Count;
	WORD  Bytes;
	WORD  ShiftBits;
	WORD  Times;

	if( LineCount < Img->PageSize )
		Count = 0;
	else
	{
		Count = LineCount / Img->PageSize;
		LineCount %= Img->PageSize;
	}

	ImgBuf = &Img->Data[Count][LineBytes * LineCount];
	if( Img->Type == 1 )
	{
		Count = 0;
		for( Bytes = 0 ; Bytes < LineBytes ; Bytes++ )
		{
			Data = 0;
			for( Times = 8 , ShiftBits = 7 ; Times > 0 ; Times--,ShiftBits-- )
			{
				Data |= LineBuf[Count] << ShiftBits;
				Count++;
			}

			ImgBuf[Bytes] = Data;
			Data = 0;
		}
	}
	else
	{
		if( Img->Type == 2 )
		{
			BYTE MaskBlt;

			WORD Width;
			WORD BitPlane;

			Width = Img->width;
			Bytes = 0;
			for( BitPlane = 0 ; BitPlane < 4 ; BitPlane++ )
			{
				Count = 0;
				MaskBlt = 1 << BitPlane;
				while(Count < Width)
				{
					ShiftBits = 7;
					Times = 8;
					Data = 0;
					while(Times--)
					{
						Data |= (LineBuf[Count] >> BitPlane & 1) << ShiftBits;
						Count++;
						ShiftBits++;
					}
					ImgBuf[Bytes] = Data;
					Bytes++;
				}
			}
		}
		else
		{
			for( Bytes = 0; Bytes < LineBytes ; Bytes++ )
			{
				ImgBuf[Bytes] = LineBuf[Bytes];
			}
		}
	}
}
/***************************************************
 功能: 依据所传入的图象指针,清楚图象数据结构与图象画面所占用的存储单元,以便释放该存储单元空间
       提供给其他图象使用。
 输入: Img ==> 存放Image数据结构的存储单元指针
 输出:
 返回:
***************************************************/
void GifImageFree(Image *Img )
{
	WORD PageTotal;

	/* 计算图象分页数 */
	PageTotal = Img->height / Img->PageSize + (Img->height % Img->PageSize ? 1:0 );

	/* 释放所申请的存储单元 */
	while( PageTotal--)
		NepFree( Img->Data[PageTotal]);
	NepFree( Img->Data );
	if( Img->Color != NULL )
		NepFree( Img->Color );

	NepFree( Img );
}

/***************************************************
 功能: 将一个字节只存一点的单色图象数据,准换成一个字节存放8点;或者将一个字节只村1点的16色
       图象数据,转换成4个Bit Planes的数据排列形式,每次转换只处理一行数据量
       存储单元,在读取该文件内的识别信息和图象数据
 输入: Img ==> 存放Image数据结构的存储单元指针
       LineBuf ==> 图象文件的文件指针
	   LineCount ==> 代表图象的行树
	   LineBytes ==> 一行的字节数
 输出:
 返回:
***************************************************/
Image* ImageAlloc(WORD Type,WORD Width,WORD Height, WORD Color)
{
	Image* Img;

	/* 申请图象数据结构所需的存储单元 */
	if( (Img = (Image*)NepMalloc(sizeof(Image))) != NULL )
	{
		DWORD DataTotal;
		WORD  PageTotal;
		WORD  PageBytes;
		WORD  LineBytes;
		WORD  Count;

		/* 计算图象所需数据值 */
		Img->Type = Type;
		Img->width = Width;
		Img->height = Height;

		if( Type == 1 || Type == 2 )
			LineBytes = (Width/8 + (Width%8?1:0)) * (Type == 2?4:1);
		else
			LineBytes = Width;

		DataTotal = (DWORD)LineBytes * Height;
		if( DataTotal > (DWORD)UINT_MAX - 16 )
			Img->PageSize = (UINT_MAX - 16)/LineBytes;
		else
			Img->PageSize = Height;

		PageTotal = Height / Img->PageSize + ( Height % Img->PageSize ? 1: 0);

		Img->Data = (BYTE**)NepMalloc(PageTotal * sizeof(BYTE*) );
		if( Img->Data != NULL )
		{
			PageBytes = Img->PageSize * LineBytes;
			for( Count = 0 ; Count < PageTotal ; Count++ )
			{
				if(Count == PageTotal-1 && (Img->height % Img->PageSize))
					PageBytes = (Img->height % Img->PageSize) * LineBytes;
				if( (Img->Data[Count] = (BYTE*)NepMalloc(PageBytes)) == NULL )
				{
					while( Count--)
						NepFree(Img->Data[Count]);
					NepFree( Img->Data );
					NepFree( Img );
					Img = NULL;
					break;
				}
			}
		}
		else
		{
			NepFree( Img );
			Img = NULL;
		}
		/* 申请调色板数据所需要的存储单元 */
		if( Img != NULL )
		{
			if( Color )
			{
				if( Type == 1 )
					Count = 6;
				else if( Type == 2 )
					Count = 48;
				else
					Count = 768;

				if( (Img->Color = (BYTE*)NepMalloc(Count)) == NULL )
				{
					while(PageTotal--)
						NepFree( Img->Data[PageTotal]);

					NepFree(Img->Data);
					NepFree( Img );
					Img = NULL;
				}
			}
			else
				Img->Color = NULL;
		}
	}

	return Img;
}

/***************************************************
 功能: 将Img数据转成DIB格式
***************************************************/
const BYTE	SHIFT2BMP[8] = {7,6,5,4,3,2,1,0};
const BYTE	SHIFT16BMP[8]= {4,0};

void GifDataToDIB(WORD* Ptr, Image* Img)
{
	WORD	W, H;
	BYTE	*ColorIndex;
	BYTE	*ScrPtr;
	WORD	*DestPtr;
	WORD	Color[256];
	WORD	ColorReg;
	BYTE	R,G,B;
	WORD	LineBytes;
	WORD	i, j;
	WORD	LineIndex;
	WORD	DataOffset;
	WORD	PageNum, PageNo;
	DWORD	DIBSize;

	W = Img->width;
	H = Img->height;
	PageNum = (H + Img->PageSize - 1)/Img->PageSize;
	*Ptr++ = W;
	*Ptr++ = H;
	*Ptr++ = 0x0010;

	DIBSize = (DWORD)W * H;
	if(DIBSize > gLCDBUFSIZE*2)
	{
		return;
	}

	//整理调色版
	ColorIndex = Img->Color;
	for( i = 0 ; i < Img->ColorBytes ; i++ )
	{
		R = Img->Color[3*i + 0];
		G = Img->Color[3*i + 1];
		B = Img->Color[3*i + 2];
		ColorReg = (((R<<8)&0xf800) + ((G<<3)&0x07e0)+ ((B>>3)&0x001f));
		Color[i] = (ColorReg>>8) + (ColorReg<<8);
	}

	if( Img->Type == 1 || Img->Type == 2 )
	{
		LineBytes = (Img->width / 8 + (Img->width %8 ? 1:0)) * (Img->Type==2?4:1);
	}
	else
		LineBytes = Img->width;

// 	if( Img->Type == 1)
// 	{
// 		LineBytes = (Img->width + 7) / 8;
// 	}
// 	else if( Img->Type == 2)
// 	{
// 		LineBytes = (Img->width + 1) / 2;
// 	}
// 	else
// 	{
// 		LineBytes = Img->width;
// 	}

	DataOffset = 0x0000;
	PageNo = 0x0000;
	ScrPtr = Img->Data[PageNo++];
	DestPtr = Ptr;
	LineIndex = 0;
	while(H--)
	{
		i = W;
		j = 0;
		switch(Img->Type)
		{
		case 1:
			while(i--)
			{
				ColorReg = (ScrPtr[DataOffset]>>SHIFT2BMP[j++])&0x01;
				ColorReg = Color[ColorReg];
				*DestPtr++ = ColorReg;
				if (j>=8)
				{
					j = 0;
					DataOffset++;
				}
			}

			if(j!=0)
				DataOffset++;

			break;

		case 2:
			while(i--)
			{
				ColorReg = (ScrPtr[DataOffset]>>SHIFT16BMP[j++])&0x0f;
				ColorReg = Color[ColorReg];
				*DestPtr++ = ColorReg;
				if (j>=2)
				{
					j = 0;
					DataOffset++;
				}
			}

			if(j!=0)
				DataOffset++;

			break;

		case 3:
			while(i--)
			{
				ColorReg = ScrPtr[DataOffset++];
				*DestPtr++ = Color[ColorReg];
			}
			break;
		}

		LineIndex++;
		if(LineIndex>=Img->PageSize)
		{
			LineIndex = 0;
			if(PageNo < PageNum)
			{
				DataOffset = 0x0000;
				ScrPtr = Img->Data[PageNo++];
			}
			else
				return;
		}
	}
}

/***************************************************
 功能: 将Img数据转成DIB格式,进行缩放为原来的(1/Type)
***************************************************/
void ZoomDIB(WORD* DestPtr, WORD* ScrPtr, RECT gRect)
{
	WORD	i, j;
	WORD	Type, Type_W, Type_H;
	WORD	Rect_W, Rect_H;
	WORD	DibW, DibH, DibType;
	WORD	Dib_W, Dib_H;
	DWORD	DibSize;
	WORD	*Dest_Ptr, *Scr_Ptr;

	Rect_W = gRect.right - gRect.left + 1;
	Rect_H = gRect.bottom - gRect.top + 1;
	DibW = *ScrPtr++;
	DibH = *ScrPtr++;
	DibType = *ScrPtr++;
	DibSize = (DWORD)DibW*DibH;

	if(Rect_W>=DibW && Rect_H>=DibH)
	{
		Type=0;
	}
	else
	{
		Type_W = (Rect_W + DibW - 1)/DibW;
		Type_H = (Rect_H + DibH - 1)/DibH;
		if(Type_W >= Type_H)
		{
			Type = Type_W; 
		}
		else
		{
			Type = Type_H; 
		}
	}

	if(Type==0)
	{
		memcpy(DestPtr, ScrPtr, DibSize*sizeof(WORD));
		return;
	}
	else
	{
		Dib_W = (DibW + Type - 1)/Type;
		Dib_H = (DibH + Type - 1)/Type;

		*DestPtr++ = Dib_W;
		*DestPtr++ = Dib_H;
		*DestPtr++ = DibType;
		i = DibW*Type;
		while(Dib_H--)
		{
			Dest_Ptr = DestPtr;
			Scr_Ptr = ScrPtr;

			j = Dib_W;
			while(j--)
			{
				*Dest_Ptr++ = *Scr_Ptr;
				Scr_Ptr += Type;
			}

			DestPtr += Dib_W;
			ScrPtr += i;
		}
	}
}

/***************************************************
***************************************************/
BOOL InitGetGifData(PFILE File)
{
	WORD i;
	Image	*Img = NULL;

	hPicview = NepMalloc(sizeof(PICVIEW_OBJ));
	if(hPicview==NULL)
		return FALSE;

//	hPicview->nWinPosWidth  = 100;
//	hPicview->nWinPosHeight = 100;
//	hPicview->PicFile       = TestHandle;
//	hPicview->pPictureBuf   = NULL;
//	hPicview->nFileOffset   = 0;

	//初始化图片的显示位置
//	hPicview->nDispPosX = 0;
//	hPicview->nDispPosY = 0;
//	hPicview->nDispWidth= 0;
//	hPicview->nDispHeight= 0;

	//初始化放大倍数
//	hPicview->fZoomSat = 0;

	//gif全局变量
	hPicview->nPicIdx       = 0x00;
	hPicview->nMaxPic       = 0x00;
	hPicview->pExternPattle = (BYTE*)NepMalloc(768);
	for( i = 0 ; i < 64 ; i++ )
		hPicview->pImg[i] = NULL;

	Img = ImageGifFileRead(File);
	if(Img==NULL)
	{
		GifMemFree();
		return FALSE;
	}
	else
		return TRUE;
}

/***************************************************
***************************************************/
void GifMemFree(void)
{
	WORD i;

	if(hPicview!=NULL)
	{
		for(i=0; i<hPicview->nMaxPic; i++)
		{
			if(hPicview->pImg[i]!=NULL)
				GifImageFree(hPicview->pImg[i]);
		}
		NepFree(hPicview->pExternPattle);
		NepFree(hPicview);
		hPicview = NULL;
	}
}

/***************************************************
功能: 根据所传入图象文件的名称,先申请所需要的Image数据结构
存储单元,在读取该文件内的识别信息和图象数据
输入: FileName ==> GIF图象文件名
输出:
返回:
成功时,返回申请给Image数据结构的存贮单元指针
失败时,则返回NULL值
***************************************************/
void GetGifInfo(WORD* pWidth, WORD* pHeight, PFILE File)
{
	BYTE	ByteBuf[16];

	if( NepFsRead(File,ByteBuf,13) != 13)
	{
		*pWidth  = 0;
		*pHeight = 0;
		return;
	}

	/* 读取表头信息 */
	if( strncmp(ByteBuf,"GIF",3) != 0 )
	{
		*pWidth  = 0;
		*pHeight = 0;
		return;
	}
	else
	{
		*pWidth = ((WORD)ByteBuf[7]<<8) + (ByteBuf[6]&0x00ff);
		*pHeight = ((WORD)ByteBuf[9]<<8) + (ByteBuf[8]&0x00ff);
	}
}
/**************************************************/

⌨️ 快捷键说明

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