详细资料:http://blog.csdn.net/wzy198852/article/details/17266507

MD5:98206F88B84CCC399C840C8EEC902CCF

GIF文件结构定义模块:

 #ifndef _GIF_COMMON_H
#define _GIF_COMMON_H #ifndef BYTE
#define BYTE unsigned char
#endif #ifndef CHAR
#define CHAR char
#endif #ifndef SHORT
#define SHORT short
#endif #ifndef LONG
#define LONG long
#endif typedef struct GIFColor {
BYTE gifRed;
BYTE gifGreen;
BYTE gifBlue;
BYTE gifResv;
}GIFColor; typedef struct GIFHeader {
CHAR gifSignature[]; // GIF署名: "GIF"
CHAR gifVersion[]; // GIF版本号: "87a" or "89a"
BYTE gifResv[]; // 保留字段
}GIFHeader; typedef struct GIFLSDescriptor {
SHORT gifLSWidth; // 逻辑屏幕宽度
SHORT gifLSHeight; // 逻辑屏幕高度 BYTE gifGlobalColorTableFlg : ; // 全局颜色列表标志: 置位表示有全局颜色列表,pixel值有意义
BYTE gifColorResolution : ; // 颜色深度: cr + 1
BYTE gifSortFlg : ; // 分类标志: 置位表示全局颜色列表分类排序
BYTE gifPixel : ; // 全局颜色列表索引数: 2^(pixel+1)
BYTE gifBgColorIdx; // 背景颜色索引,如果无全局颜色列表,该值无意义
BYTE gifAspectRadio; // 像素宽高比
BYTE gifResv[];
}GIFLSDescriptor; typedef struct GIFColorTable {
BYTE gifColorTable[];
}GIFColorTable; typedef struct GIFImageDescriptor {
BYTE gifImageFlg; // 图像标识符开始标志: 0x2c(';')
BYTE gifResv1[]; SHORT gifXOffset; // X方向偏移量
SHORT gifYOffset; // Y方向偏移量
SHORT gifImageWidth; // 图像宽度
SHORT gifImageHeight; // 图像高度 BYTE gifLocalColorTableFlg : ; // 局部颜色列表标志,置位时图像标识符后紧跟一个局部颜色表,\
供紧跟在它之后的一幅图像使用;值否时使用全局颜色列表,忽略pixel值。
BYTE gifInterlaceFlg : ; // 交织标志,置位时图像数据使用交织方式排列,否则使用顺序排列
BYTE gifSortFlg : ; // 分类标志,置位表示局部颜色列表分类排序
BYTE gifResv : ; // 保留位,必须为 0
BYTE gifPixel; // 局部颜色列表索引数: 2^(pixel+1)
BYTE gifResv2[];
}GIFImageDescriptor; typedef struct GIFImageDataSubBlock {
BYTE gifSubBlockSize; // 块大小
BYTE gifResv[];
BYTE *gifCodedData; // 编码数据
}GIFImageDataSubBlock; typedef struct GIFImageData {
BYTE gifLZWCodeTableSize; // LZW初始编码表大小的位数
SHORT gifSubBlockNum; // 数据块数
BYTE gifResv1;
GIFImageDataSubBlock *gifImageDataSubBlocks; // 数据块
BYTE gifImageDataEndFlg; // 数据编码结束: 0
BYTE gifResv2[];
}GIFImageData; typedef struct GIFImageChunk {
/* 图像标识符 */
GIFImageDescriptor gifImageDescriptor;
/* 图像局部颜色列表,gifLocalColorTableFlg=1时有效 */
GIFColorTable gifLocalColorTable;
/* 图像数据 */
GIFImageData gifImageData;
}GIFImageChunk; typedef struct GIFStruct {
/* 1 文件头 */
GIFHeader gifHeader; /* 2 GIF数据流 */
/* 2.1 逻辑屏幕标志符 */
GIFLSDescriptor gifLSDescriptor;
/* 2.2 全局颜色列表,gifGlobalColorTableFlg=1时有效 */
GIFColorTable gifGlobalColorTable;
/* 2.3 图像 */
SHORT gifImageChunkNum; // 图像数
BYTE gifResv[];
GIFImageChunk *gifImageChunks; /* 3 文件终结器 */
}; #endif

文件读取缓存模块:

 #include <stdio.h>
#include <stdlib.h> #ifndef GIF
#define CHAR char
#define BYTE unsigned char
#define SHORT short
#define INT int
#define LONG long
#define GIF #define SUCCESS 0
#define FAILURE 1
#define INVALID -1 #define CHECK_NULL_RET(expr, ret) if(NULL == (expr)) return ret
#define CHECK_RET(expr, ret) if(expr) return ret
#define CHECK_FALSE_RET(expr, ret) if(!(expr)) return ret #endif #define FIRST_BUFF_SIZE 2048
#define SECOND_BUFF_SIZE FIRST_BUFF_SIZE
#define BUFF_SIZE (FIRST_BUFF_SIZE+SECOND_BUFF_SIZE)
#define READ_ONCE_SIZE FIRST_BUFF_SIZE FILE *fin; // 输入文件
BYTE readBuff[BUFF_SIZE]; // 缓存区,分为第一缓存和第二缓存,对应FIRST_BUFF和SECOND_BUFF
INT startIdx; // 有效数据起始索引(包含当前),默认值为INVALID(-1)
INT endIdx; // 有效数据结束索引(包含当前),默认值为INVALID(-1)
INT readIdx; // 下一次读取起始索引(包含当前),默认值为INVALID(-1) #define GET_VALID_SIZE() (endIdx - readIdx + 1) INT RBFillBuff()
{
INT realReadBytes;
INT unusedLen;
CHECK_NULL_RET(fin, FAILURE); if(readIdx <= endIdx) // 有未读数据
{
memmove(readBuff, &readBuff[readIdx], endIdx-readIdx+);
startIdx = readIdx = ;
endIdx = endIdx - readIdx;
}
else // 无未读数据
{
startIdx = endIdx = -;
readIdx = ;
}
CHECK_FALSE_RET(endIdx < FIRST_BUFF_SIZE, SUCCESS); realReadBytes = fread(&readBuff[endIdx+], , READ_ONCE_SIZE, fin);
CHECK_FALSE_RET(realReadBytes > , FAILURE); startIdx = readIdx = ;
endIdx = endIdx + realReadBytes; return SUCCESS;
} VOID RBFreeFile()
{
if(fin != NULL)
{
fclose(fin);
fin = NULL;
}
} /* 缓存模块初始化 */
INT RBModuleInit(CHAR *filePath)
{
startIdx = endIdx = -;
readIdx = ; CHECK_NULL_RET(filePath, FAILURE); fin = fopen(filePath, "rb");
CHECK_NULL_RET(fin, FAILURE);
RBFillBuff();
} INT RBGetBytes(BYTE *buff, int len)
{
INT ret;
CHECK_NULL_RET(buff, FAILURE);
CHECK_FALSE_RET(len > && len < FIRST_BUFF_SIZE, FAILURE);
if(len > GET_VALID_SIZE())
{
if(FAILURE == RBFillBuff())
{
return FAILURE;
}
}
CHECK_FALSE_RET(len <= GET_VALID_SIZE(), FAILURE);
memcpy(buff, &readBuff[readIdx], len);
readIdx += len; return SUCCESS;
} INT RBGetByte(BYTE *value)
{
return RBGetBytes(value, );
}
 #include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct Elem {
unsigned char value;
int preIdx;
}Elem; int tabSize;
Elem lzwTab[]; #define LZWSIZE 2 int LzwInit(int size)
{
int loop = ;
for(loop = ; loop < size; loop++)
{
lzwTab[loop].value = loop;
lzwTab[loop].preIdx = -;
}
tabSize = size;
return ;
} int AddElement(unsigned char currChar, int lastIdx)
{
lzwTab[tabSize].value = currChar;
lzwTab[tabSize].preIdx = lastIdx;
tabSize++;
return ;
} int SearchStrInTable(unsigned char currChar, int lastIdx)
{
int loop = ;
for(loop = ; loop < tabSize; loop++)
{
if((lzwTab[loop].value == currChar) && (lzwTab[loop].preIdx == lastIdx))
{
return loop;
}
}
return -;
} int LzwEncode(const unsigned char *inStream, int inLen, int *outStream, int *outLen)
{ unsigned char currChar = ;
int lastIdx = -;
int currIdx = -; int readIdx = ;
int writeIdx = ; LzwInit(LZWSIZE); // 初始化编码表 for(readIdx = ; readIdx < inLen; readIdx++) // 遍历输入流
{
currChar = inStream[readIdx]; // 当前字符,与lastIdx组成当前字符串
currIdx = SearchStrInTable(currChar, lastIdx); // 查找当前字符串索引
if(currIdx == -) // 未找到
{
outStream[writeIdx++] = lastIdx; // 输出前缀索引到编码流
AddElement(currChar, lastIdx); // 添加当前字符串到编码表
lastIdx = SearchStrInTable(currChar, -); // 以当前字符的索引作为lastIdx,为下一轮做准备
}
else
{
lastIdx = currIdx;
}
}
outStream[writeIdx++] = lastIdx;
*outLen = writeIdx; return ;
} int SearchCodeInTable(int currCode, unsigned char *strBuff)
{
if(currCode >= tabSize)
{
return ;
}
else
{
int writeIdx = ;
while(currCode >= )
{
strBuff[writeIdx++] = lzwTab[currCode].value;
currCode = lzwTab[currCode].preIdx;
} unsigned char *strHead = strBuff;
unsigned char *strTail = strBuff + writeIdx - ;
unsigned char strTemp;
while(strHead < strTail)
{
strTemp = *strHead;
*strHead = *strTail;
*strTail = strTemp; strHead++;
strTail--;
}
return writeIdx;
}
} int WriteString(unsigned char *outStream, unsigned char *strBuff, int strLen, int *outLen)
{
memcpy(outStream + (*outLen), strBuff, strLen);
*outLen += strLen;
return ;
} int LzwDecode(const int *inStream, int inLen, unsigned char *outStream, int *outLen)
{
int currCode;
int lastCode = -;
int readIdx = ;
int strLen = ;
unsigned char *strBuff = new unsigned char[];
*outLen = ; LzwInit(LZWSIZE); // 初始化编码表 for(readIdx = ; readIdx < inLen; readIdx++)
{
currCode = inStream[readIdx];
strLen = SearchCodeInTable(currCode, strBuff);
if(strLen == ) // 没找到
{
strBuff[strLen++] = strBuff[];
WriteString(outStream, strBuff, strLen, outLen);
if(lastCode != -)
{
AddElement(strBuff[], lastCode);
}
lastCode = currCode;
}
else // 找到
{
WriteString(outStream, strBuff, strLen, outLen);
AddElement(strBuff[], lastCode);
lastCode = currCode;
}
}
return ;
} int test()
{
unsigned char srcData[] = {,,,,,,,,,,,,,,,,,,,,,,};
int encodeData[];
unsigned char decodeData[];
int srcDataLen = ;
int encodeDataLen;
int decodeDataLen; printf("Start encode...\n");
LzwEncode(srcData, srcDataLen, encodeData, &encodeDataLen);
printf("End encode, encodeDataLen=%d.\n", encodeDataLen);
printf("encodeData:");
for(int i=; i<encodeDataLen; i++)
{
printf("%d ", encodeData[i]);
} printf("\nStart decode...\n");
LzwDecode(encodeData, encodeDataLen, decodeData, &decodeDataLen);
printf("End decode, decodeDataLen=%d.\n", decodeDataLen);
printf("decodeData:");
for(int i=; i<decodeDataLen; i++)
{
printf("%d ", decodeData[i]);
}
printf("\n");
return ;
} int main()
{
test(); system("pause");
return ;
}

gif文件解析的更多相关文章

  1. CocosStudio文件解析工具CsdAnalysis

    起因 因为工作需要,所以需要使用CocosStudio来制作界面动画什么的.做完了发现需要找里边对象的时候会有很长一串代码,感觉不是很爽.之前写OC代码的时候可以吧程序中的对象指针跟编辑器中的对象相对 ...

  2. 通过正则表达式实现简单xml文件解析

    这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...

  3. 八、Android学习第七天——XML文件解析方法(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...

  4. phpcms V9 首页模板文件解析

    在了解了<phpcms V9 URL访问解析>之后,我们已经知道首页最终执行的是content模块下index控制器的init方法. 下面, 我们逐步分析过程如下: 第一.首页默认执行的是 ...

  5. (转)AVI文件格式解析+AVI文件解析工具

    AVI文件解析工具下载地址:http://download.csdn.net/detail/zjq634359531/7556659 AVI(Audio Video Interleaved的缩写)是一 ...

  6. itextSharp 附pdf文件解析

    一.PdfObject: pdf对象 ,有9种,对象是按照对象内涵来分的,如果按照对象的使用规则来说,对象又分为间接对象和直接对象.间接对象是PDF中最常用的对象,如前面对象集合里面的,所有对象都是间 ...

  7. 《热血传奇2》wix、wil文件解析Java实现

    在百度上搜索java+wil只有iteye上一篇有丁点儿内容,不过他说的是错的!或者说是不完整的,我个人认为我对于热血传奇客户端解析还是有一定研究的,请移步: <JMir——Java版热血传奇2 ...

  8. paper 37 : WINCE的BIB文件解析

    WINCE的BIB文件解析 BIB的全称为Binary Image Builder,在Wince编译过程中的最后MakeImage阶段会用到BIB文件,BIB文件的作用是指示构建系统如何构建二进制映像 ...

  9. 如何让你的Apache支持include文件解析和支持shtml的相关配置

    源地址:http://www.itokit.com/2011/0430/65992.html Apache支持include文件解析shtml首先要应该修改Apache配置文件httpd.conf . ...

  10. android基础知识13:AndroidManifest.xml文件解析

    注:本文转载于:http://blog.csdn.net/xianming01/article/details/7526987 AndroidManifest.xml文件解析. 1.重要性 Andro ...

随机推荐

  1. ajax的缺点

    平时我们大多注意的都是ajax给我们所带来的好处诸如用户体验的提升.对ajax所带来的缺陷有所忽视. 下面所阐述的ajax的缺陷都是它先天所产生的. 1.ajax干掉了back按钮,即对浏览器后退机制 ...

  2. linux 集群及lvs

    集群及LVS 集群: 一组通过高速网络互联的计算机组,并以单一系统的模式加以管理 价格很多服务器集中起来,提供同一种服务,在客户端看起来就像只有一个服务器 可以在付出较低成本的情况下获得在性能,可靠性 ...

  3. 如何将ubuntu控制台输出到串口?

    如何将ubuntu控制台输出到串口? Linux使用ubuntu14.04发行版本 操作步骤: 1.修改/etc/default/grub ## Modify this line by leekwen ...

  4. directdraw显示yuv420(YV12)

    height=width=widthBytes=0;  m_screen.SetWindowPos(&CWnd::wndBottom,0,0,720,576, SWP_NOMOVE | SWP ...

  5. Css中路径data:image/png;base64的用法详解

    今天查看一些网站的css中发现了 background-image:url(data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAAB ...

  6. linux下驱动模块化编译,动态加载以及卸载

    步骤:: 1.编写first_driver_hello.c文件,将其放在/linux2.6.32/drivers/char路径下: 2.在/linux2.6.32/drivers/cha/Kconfi ...

  7. hihocoder Challenge 29 D. 不上升序列

    这场爆零比赛题目还是要补的 这道题据说是出烂掉的原题,我找了下 CF13.C/ CF371 div1 C,一模一样 我服这群原题大佬 为 当时,使 不严格递增的最小步数,那么 Otherwise 显然 ...

  8. 异常-----java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.core.KeyFactory

    SSH 类库问题 java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer2009- ...

  9. ASP.NET 初识Cookie

    1.ASP.NET中使用Cookie 0.说明 Cookie存在客户端电脑上,Session存在服务器上,所以保存登录信息等敏感信息时不能使用Cookie,用户个性化设置可以使用Cookie 1.新建 ...

  10. Python编程核心内容之一——Function(函数)

    Python版本:3.6.2  操作系统:Windows  作者:SmallWZQ 截至上篇随笔<Python数据结构之四--set(集合)>,Python基础知识也介绍好了.接下来准备干 ...