详细资料: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. Git创建本地分支并推送到远程github仓库

  2. 利用Caffe训练模型(solver、deploy、train_val)+python使用已训练模型

    本文部分内容来源于CDA深度学习实战课堂,由唐宇迪老师授课 如果你企图用CPU来训练模型,那么你就疯了- 训练模型中,最耗时的因素是图像大小size,一般227*227用CPU来训练的话,训练1万次可 ...

  3. 第5章 PCIe总线的事务层

    事务层是PCIe总线层次结构的最高层,该层次将接收PCIe设备核心层的数据请求,并将其转换为PCIe总线事务,PCIe总线使用的这些总线事务在TLP头中定义.PCIe总线继承了PCI/PCI-X总线的 ...

  4. R+NLP︱text2vec包——四类文本挖掘相似性指标 RWMD、cosine、Jaccard 、Euclidean (三,相似距离)

    要学的东西太多,无笔记不能学~~ 欢迎关注公众号,一起分享学习笔记,记录每一颗"贝壳"~ --------------------------- 在之前的开篇提到了text2vec ...

  5. 【转载】使用SDL播放YUV图像数据(转)

    SDL提供了针对YUV格式数据的直接写屏操作.废话不多说,直接上代码吧/** * file showyuv.c * author: rare * date: 2009/12/06 * email: d ...

  6. ffmpeg在am335x上的移植

    交叉编译工具:arm-linux-gcc 一.先下载一下文件 1. yasm-1.2.0.tar.gz 2. x264-snapshot-20140424-2245.tar.bz2 3. xvidco ...

  7. 错误代码: 1045 Access denied for user 'skyusers'@'%' (using password: YES)

    1. 错误描述 GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "."; 1 queries exe ...

  8. WebService之CXF注解之三(Service接口实现类)

    ITeacherServiceImpl.java: /** * @Title:ITeacherServiceImpl.java * @Package:com.you.service.impl * @D ...

  9. Java中集合List,Map和Set的区别

    Java中集合List,Map和Set的区别 1.List和Set的父接口是Collection,而Map不是 2.List中的元素是有序的,可以重复的 3.Map是Key-Value映射关系,且Ke ...

  10. 1118: 属于 static 类型 Object 的值的隐式强制指令的目标可能是非相关类型 Number。

    1.错误描述 此行的多个标记: -1118: 属于 static 类型 Object 的值的隐式强制指令的目标可能是非相关类型 Number. -left 2.错误原因 /** * 刷新按钮函数 */ ...