gif文件解析
详细资料:http://blog.csdn.net/wzy198852/article/details/17266507
MD5:98206F88B84CCC399C840C8EEC902CCF
GIF文件结构定义模块:
1 #ifndef _GIF_COMMON_H 2 #define _GIF_COMMON_H 3 4 #ifndef BYTE 5 #define BYTE unsigned char 6 #endif 7 8 #ifndef CHAR 9 #define CHAR char 10 #endif 11 12 #ifndef SHORT 13 #define SHORT short 14 #endif 15 16 #ifndef LONG 17 #define LONG long 18 #endif 19 20 typedef struct GIFColor { 21 BYTE gifRed; 22 BYTE gifGreen; 23 BYTE gifBlue; 24 BYTE gifResv; 25 }GIFColor; 26 27 typedef struct GIFHeader { 28 CHAR gifSignature[3]; // GIF署名: "GIF" 29 CHAR gifVersion[2]; // GIF版本号: "87a" or "89a" 30 BYTE gifResv[3]; // 保留字段 31 }GIFHeader; 32 33 typedef struct GIFLSDescriptor { 34 SHORT gifLSWidth; // 逻辑屏幕宽度 35 SHORT gifLSHeight; // 逻辑屏幕高度 36 37 BYTE gifGlobalColorTableFlg : 1; // 全局颜色列表标志: 置位表示有全局颜色列表,pixel值有意义 38 BYTE gifColorResolution : 3; // 颜色深度: cr + 1 39 BYTE gifSortFlg : 1; // 分类标志: 置位表示全局颜色列表分类排序 40 BYTE gifPixel : 3; // 全局颜色列表索引数: 2^(pixel+1) 41 BYTE gifBgColorIdx; // 背景颜色索引,如果无全局颜色列表,该值无意义 42 BYTE gifAspectRadio; // 像素宽高比 43 BYTE gifResv[2]; 44 }GIFLSDescriptor; 45 46 typedef struct GIFColorTable { 47 BYTE gifColorTable[256]; 48 }GIFColorTable; 49 50 typedef struct GIFImageDescriptor { 51 BYTE gifImageFlg; // 图像标识符开始标志: 0x2c(';') 52 BYTE gifResv1[3]; 53 54 SHORT gifXOffset; // X方向偏移量 55 SHORT gifYOffset; // Y方向偏移量 56 SHORT gifImageWidth; // 图像宽度 57 SHORT gifImageHeight; // 图像高度 58 59 BYTE gifLocalColorTableFlg : 1; // 局部颜色列表标志,置位时图像标识符后紧跟一个局部颜色表,\ 60 供紧跟在它之后的一幅图像使用;值否时使用全局颜色列表,忽略pixel值。 61 BYTE gifInterlaceFlg : 1; // 交织标志,置位时图像数据使用交织方式排列,否则使用顺序排列 62 BYTE gifSortFlg : 1; // 分类标志,置位表示局部颜色列表分类排序 63 BYTE gifResv : 2; // 保留位,必须为 0 64 BYTE gifPixel; // 局部颜色列表索引数: 2^(pixel+1) 65 BYTE gifResv2[3]; 66 }GIFImageDescriptor; 67 68 typedef struct GIFImageDataSubBlock { 69 BYTE gifSubBlockSize; // 块大小 70 BYTE gifResv[3]; 71 BYTE *gifCodedData; // 编码数据 72 }GIFImageDataSubBlock; 73 74 typedef struct GIFImageData { 75 BYTE gifLZWCodeTableSize; // LZW初始编码表大小的位数 76 SHORT gifSubBlockNum; // 数据块数 77 BYTE gifResv1; 78 GIFImageDataSubBlock *gifImageDataSubBlocks; // 数据块 79 BYTE gifImageDataEndFlg; // 数据编码结束: 0 80 BYTE gifResv2[3]; 81 }GIFImageData; 82 83 typedef struct GIFImageChunk { 84 /* 图像标识符 */ 85 GIFImageDescriptor gifImageDescriptor; 86 /* 图像局部颜色列表,gifLocalColorTableFlg=1时有效 */ 87 GIFColorTable gifLocalColorTable; 88 /* 图像数据 */ 89 GIFImageData gifImageData; 90 }GIFImageChunk; 91 92 typedef struct GIFStruct { 93 /* 1 文件头 */ 94 GIFHeader gifHeader; 95 96 /* 2 GIF数据流 */ 97 /* 2.1 逻辑屏幕标志符 */ 98 GIFLSDescriptor gifLSDescriptor; 99 /* 2.2 全局颜色列表,gifGlobalColorTableFlg=1时有效 */ 100 GIFColorTable gifGlobalColorTable; 101 /* 2.3 图像 */ 102 SHORT gifImageChunkNum; // 图像数 103 BYTE gifResv[2]; 104 GIFImageChunk *gifImageChunks; 105 106 107 108 /* 3 文件终结器 */ 109 }; 110 111 #endif
文件读取缓存模块:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #ifndef GIF 5 #define CHAR char 6 #define BYTE unsigned char 7 #define SHORT short 8 #define INT int 9 #define LONG long 10 #define GIF 11 12 #define SUCCESS 0 13 #define FAILURE 1 14 #define INVALID -1 15 16 #define CHECK_NULL_RET(expr, ret) if(NULL == (expr)) return ret 17 #define CHECK_RET(expr, ret) if(expr) return ret 18 #define CHECK_FALSE_RET(expr, ret) if(!(expr)) return ret 19 20 #endif 21 22 #define FIRST_BUFF_SIZE 2048 23 #define SECOND_BUFF_SIZE FIRST_BUFF_SIZE 24 #define BUFF_SIZE (FIRST_BUFF_SIZE+SECOND_BUFF_SIZE) 25 #define READ_ONCE_SIZE FIRST_BUFF_SIZE 26 27 FILE *fin; // 输入文件 28 BYTE readBuff[BUFF_SIZE]; // 缓存区,分为第一缓存和第二缓存,对应FIRST_BUFF和SECOND_BUFF 29 INT startIdx; // 有效数据起始索引(包含当前),默认值为INVALID(-1) 30 INT endIdx; // 有效数据结束索引(包含当前),默认值为INVALID(-1) 31 INT readIdx; // 下一次读取起始索引(包含当前),默认值为INVALID(-1) 32 33 #define GET_VALID_SIZE() (endIdx - readIdx + 1) 34 35 INT RBFillBuff() 36 { 37 INT realReadBytes; 38 INT unusedLen; 39 CHECK_NULL_RET(fin, FAILURE); 40 41 if(readIdx <= endIdx) // 有未读数据 42 { 43 memmove(readBuff, &readBuff[readIdx], endIdx-readIdx+1); 44 startIdx = readIdx = 0; 45 endIdx = endIdx - readIdx; 46 } 47 else // 无未读数据 48 { 49 startIdx = endIdx = -1; 50 readIdx = 0; 51 } 52 CHECK_FALSE_RET(endIdx < FIRST_BUFF_SIZE, SUCCESS); 53 54 realReadBytes = fread(&readBuff[endIdx+1], 1, READ_ONCE_SIZE, fin); 55 CHECK_FALSE_RET(realReadBytes > 0, FAILURE); 56 57 startIdx = readIdx = 0; 58 endIdx = endIdx + realReadBytes; 59 60 return SUCCESS; 61 } 62 63 VOID RBFreeFile() 64 { 65 if(fin != NULL) 66 { 67 fclose(fin); 68 fin = NULL; 69 } 70 } 71 72 /* 缓存模块初始化 */ 73 INT RBModuleInit(CHAR *filePath) 74 { 75 startIdx = endIdx = -1; 76 readIdx = 0; 77 78 CHECK_NULL_RET(filePath, FAILURE); 79 80 fin = fopen(filePath, "rb"); 81 CHECK_NULL_RET(fin, FAILURE); 82 RBFillBuff(); 83 } 84 85 INT RBGetBytes(BYTE *buff, int len) 86 { 87 INT ret; 88 CHECK_NULL_RET(buff, FAILURE); 89 CHECK_FALSE_RET(len > 0 && len < FIRST_BUFF_SIZE, FAILURE); 90 if(len > GET_VALID_SIZE()) 91 { 92 if(FAILURE == RBFillBuff()) 93 { 94 return FAILURE; 95 } 96 } 97 CHECK_FALSE_RET(len <= GET_VALID_SIZE(), FAILURE); 98 memcpy(buff, &readBuff[readIdx], len); 99 readIdx += len; 100 101 return SUCCESS; 102 } 103 104 105 INT RBGetByte(BYTE *value) 106 { 107 return RBGetBytes(value, 1); 108 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 typedef struct Elem { 6 unsigned char value; 7 int preIdx; 8 }Elem; 9 10 int tabSize; 11 Elem lzwTab[256]; 12 13 #define LZWSIZE 2 14 15 int LzwInit(int size) 16 { 17 int loop = 0; 18 for(loop = 0; loop < size; loop++) 19 { 20 lzwTab[loop].value = loop; 21 lzwTab[loop].preIdx = -1; 22 } 23 tabSize = size; 24 return 1; 25 } 26 27 int AddElement(unsigned char currChar, int lastIdx) 28 { 29 lzwTab[tabSize].value = currChar; 30 lzwTab[tabSize].preIdx = lastIdx; 31 tabSize++; 32 return 1; 33 } 34 35 int SearchStrInTable(unsigned char currChar, int lastIdx) 36 { 37 int loop = 0; 38 for(loop = 0; loop < tabSize; loop++) 39 { 40 if((lzwTab[loop].value == currChar) && (lzwTab[loop].preIdx == lastIdx)) 41 { 42 return loop; 43 } 44 } 45 return -1; 46 } 47 48 int LzwEncode(const unsigned char *inStream, int inLen, int *outStream, int *outLen) 49 { 50 51 unsigned char currChar = 0; 52 int lastIdx = -1; 53 int currIdx = -1; 54 55 int readIdx = 0; 56 int writeIdx = 0; 57 58 LzwInit(LZWSIZE); // 初始化编码表 59 60 for(readIdx = 0; readIdx < inLen; readIdx++) // 遍历输入流 61 { 62 currChar = inStream[readIdx]; // 当前字符,与lastIdx组成当前字符串 63 currIdx = SearchStrInTable(currChar, lastIdx); // 查找当前字符串索引 64 if(currIdx == -1) // 未找到 65 { 66 outStream[writeIdx++] = lastIdx; // 输出前缀索引到编码流 67 AddElement(currChar, lastIdx); // 添加当前字符串到编码表 68 lastIdx = SearchStrInTable(currChar, -1); // 以当前字符的索引作为lastIdx,为下一轮做准备 69 } 70 else 71 { 72 lastIdx = currIdx; 73 } 74 } 75 outStream[writeIdx++] = lastIdx; 76 *outLen = writeIdx; 77 78 return 1; 79 } 80 81 int SearchCodeInTable(int currCode, unsigned char *strBuff) 82 { 83 if(currCode >= tabSize) 84 { 85 return 0; 86 } 87 else 88 { 89 int writeIdx = 0; 90 while(currCode >= 0) 91 { 92 strBuff[writeIdx++] = lzwTab[currCode].value; 93 currCode = lzwTab[currCode].preIdx; 94 } 95 96 unsigned char *strHead = strBuff; 97 unsigned char *strTail = strBuff + writeIdx - 1; 98 unsigned char strTemp; 99 while(strHead < strTail) 100 { 101 strTemp = *strHead; 102 *strHead = *strTail; 103 *strTail = strTemp; 104 105 strHead++; 106 strTail--; 107 } 108 return writeIdx; 109 } 110 } 111 112 int WriteString(unsigned char *outStream, unsigned char *strBuff, int strLen, int *outLen) 113 { 114 memcpy(outStream + (*outLen), strBuff, strLen); 115 *outLen += strLen; 116 return 1; 117 } 118 119 int LzwDecode(const int *inStream, int inLen, unsigned char *outStream, int *outLen) 120 { 121 int currCode; 122 int lastCode = -1; 123 int readIdx = 0; 124 int strLen = 0; 125 unsigned char *strBuff = new unsigned char[256]; 126 *outLen = 0; 127 128 LzwInit(LZWSIZE); // 初始化编码表 129 130 for(readIdx = 0; readIdx < inLen; readIdx++) 131 { 132 currCode = inStream[readIdx]; 133 strLen = SearchCodeInTable(currCode, strBuff); 134 if(strLen == 0) // 没找到 135 { 136 strBuff[strLen++] = strBuff[0]; 137 WriteString(outStream, strBuff, strLen, outLen); 138 if(lastCode != -1) 139 { 140 AddElement(strBuff[0], lastCode); 141 } 142 lastCode = currCode; 143 } 144 else // 找到 145 { 146 WriteString(outStream, strBuff, strLen, outLen); 147 AddElement(strBuff[0], lastCode); 148 lastCode = currCode; 149 } 150 } 151 return 1; 152 } 153 154 int test() 155 { 156 unsigned char srcData[] = {1,0,0,1,1,1,0,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1}; 157 int encodeData[32]; 158 unsigned char decodeData[32]; 159 int srcDataLen = 23; 160 int encodeDataLen; 161 int decodeDataLen; 162 163 printf("Start encode...\n"); 164 LzwEncode(srcData, srcDataLen, encodeData, &encodeDataLen); 165 printf("End encode, encodeDataLen=%d.\n", encodeDataLen); 166 printf("encodeData:"); 167 for(int i=0; i<encodeDataLen; i++) 168 { 169 printf("%d ", encodeData[i]); 170 } 171 172 printf("\nStart decode...\n"); 173 LzwDecode(encodeData, encodeDataLen, decodeData, &decodeDataLen); 174 printf("End decode, decodeDataLen=%d.\n", decodeDataLen); 175 printf("decodeData:"); 176 for(int i=0; i<decodeDataLen; i++) 177 { 178 printf("%d ", decodeData[i]); 179 } 180 printf("\n"); 181 return 1; 182 } 183 184 int main() 185 { 186 test(); 187 188 system("pause"); 189 return 0; 190 }