一、giflib库和zlib依赖库下载路径
giflib库链接:https://sourceforge.net/projects/giflib/
二、ubuntu上验证GIFLIB
1. 解压:tar -xzvf giflib-5.2.1.tar.gz && cd giflib-5.2.1,解压后的文件目录如下图
2.修改gif2rgb.c并并修改代码
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include "gif_lib.h"
#include "getarg.h"
int transparentColorIndex=NO_TRANSPARENT_COLOR;
int disposalMode=0;
static void DumpScreen2RGB(ColorMapObject *ColorMap,GifRowType *ScreenBuffer, int cow, int col, int ScreenWidth, int ScreenHeight,unsigned char *rgb)
{
int i, j;
GifRowType GifRow;
GifColorType *ColorMapEntry;
for (i = cow; i < ScreenHeight; i++) {
GifRow = ScreenBuffer[i];
for (j = col; j < ScreenWidth; j++) {
ColorMapEntry = &ColorMap->Colors[GifRow[j]];
if ( (disposalMode == DISPOSE_DO_NOT) && (GifRow[j] == transparentColorIndex) ) {
continue;
}
if ( (GifRow[j] != transparentColorIndex) || (transparentColorIndex == NO_TRANSPARENT_COLOR) ) {
rgb[i*ScreenWidth+j*3+0] = ColorMapEntry->Blue;
rgb[i*ScreenWidth+j*3+1] = ColorMapEntry->Green;
rgb[i*ScreenWidth+j*3+2] = ColorMapEntry->Red;
} else {
rgb[i*ScreenWidth+j*3+0] = 0x0;
rgb[i*ScreenWidth+j*3+1] = 0x0;
rgb[i*ScreenWidth+j*3+2] = 0x0;
}
}
}
}
static void write_rgb2file(char *out_FileName,unsigned char *rgb,int size,int count)
{
char filename[64]={0};
sprintf(filename,"%s-%d.rgb",out_FileName,count);
printf("%s\n",filename);
int fd=open(filename,O_RDWR | O_CREAT,0777);
if(fd<0){
printf("can not open the file\n");
return;
}
if( write(fd,rgb,size) != size ){
printf("write rgb to file error\n");
}
close(fd);
}
int GIF2RGB(char *in_FileName,char *out_FileName)
{
int i, j, Size, Row, Col, Width, Height, ExtCode;
GifRecordType RecordType;
GifByteType *Extension;
GifRowType *ScreenBuffer;
GifFileType *GifFile;
int InterlacedOffset[] = { 0, 4, 2, 1 }; /* The way Interlaced image should. */
int InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */
int ImageNum = 0;
ColorMapObject *ColorMap;
int Error;
if ((GifFile = DGifOpenFileName(in_FileName, &Error)) == NULL) {
printf("DGifOpenFileName error %d \n",Error);
return false;
}
if (GifFile->SHeight == 0 || GifFile->SWidth == 0) {
printf("GifFile->SHeight == 0 || GifFile->SWidth == 0 \n");
return false;
}
printf("width:%d height:%d\n",GifFile->SWidth,GifFile->SHeight);
if ((ScreenBuffer = (GifRowType *)malloc(GifFile->SHeight * sizeof(GifRowType))) == NULL){
printf("Failed to allocate memory required, aborted.");
return false;
}
Size = GifFile->SWidth * sizeof(GifPixelType); //一行需要分配的内存
printf("size :%d\n",Size);
if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL){ //第一行
printf("Failed to allocate memory required, aborted.");
return false;
}
for (i = 0; i < GifFile->SWidth; i++){ // 读取背景色
ScreenBuffer[0][i] = GifFile->SBackGroundColor;
}
for (i = 1; i < GifFile->SHeight; i++) { // 给其余每一行分配背景色
if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL){
printf("Failed to allocate memory required, aborted.");
return false;
}
memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
}
unsigned char *rgb=(unsigned char *)malloc( GifFile->SWidth*GifFile->SHeight*3 );
if(rgb==NULL){
DGifCloseFile(GifFile, &Error);
free(ScreenBuffer);
printf("rgb no memory\n");
return false;
}
int count=0;
int frame_delay=0;
// 扫描GIF文件的内容并将图像加载到rgb文件:
do {
if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
printf("DGifGetRecordType error\n");
return false;
}
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
printf("DGifGetImageDesc error\n");
return false;
}
Row = GifFile->Image.Top; //图像相对于屏幕(背景画布)的位置
Col = GifFile->Image.Left;
Width = GifFile->Image.Width;
Height = GifFile->Image.Height;
if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) {
printf("Image %d is not confined to screen dimension, aborted.\n",ImageNum);
return false;
}
if (GifFile->Image.Interlace) {
// 需要对图像执行4次传递:
for (i = 0; i < 4; i++){
for (j = Row + InterlacedOffset[i]; j < Row + Height;j += InterlacedJumps[i]) {
if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],Width) == GIF_ERROR) {
printf("DGifGetLine error\n");
return false;
}
}
}
}else {
for (i = 0; i < Height; i++) {
if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],Width) == GIF_ERROR) {
printf("DGifGetLine error\n");
return false;
}
}
}
//有没有局部颜色表
ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap);
if (ColorMap == NULL) {
printf("Gif Image does not have a colormap\n");
return false;
}
printf("image-%d\n",count);
DumpScreen2RGB(ColorMap,ScreenBuffer,GifFile->Image.Top,GifFile->Image.Left, GifFile->Image.Left + Width, GifFile->Image.Top + Height,rgb);
write_rgb2file(out_FileName,rgb,GifFile->SWidth*GifFile->SHeight*3,count);
count++;
break;
case EXTENSION_RECORD_TYPE: //Skip any extension blocks in file:
if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
printf("DGifGetExtension error\n");
return false;
}
unsigned char *GifExtension= &Extension[1];
if(ExtCode == GRAPHICS_EXT_FUNC_CODE){
frame_delay = 10*(GifExtension[2]<<8 | GifExtension[1]);//拿到延迟时间
}
printf("frame_delay %d\n",frame_delay);
if (GifExtension[0] & 0x01) {
transparentColorIndex = (int) GifExtension[3];
} else {
transparentColorIndex = NO_TRANSPARENT_COLOR;
}
disposalMode = (GifExtension[0] >> 2) & 0x07;
while (Extension != NULL) {
if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
printf("DGifGetExtensionNext error\n");
return false;
}
}
break;
case TERMINATE_RECORD_TYPE:
break;
default: //Should be trapped by DGifGetRecordType.
break;
}
} while (RecordType != TERMINATE_RECORD_TYPE);
for (i = 0; i < GifFile->SHeight; i++){
free(ScreenBuffer[i]);
}
free(ScreenBuffer);
free(rgb);
if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) {
printf("DGifCloseFile error\n");
}
return true;
}
int main(int argc,char *argv[])
{
if(argc == 3){
GIF2RGB(argv[1],argv[2]);
}else{
printf("args error\n");
}
return 0;
}
3.执行make,mkdir test && cp gif2rgb test && cp test.gif test && cd test,测试结果如下
三、移植到不同平台
make CC=arm-linux-gcc 配置对应的交叉编译器即可