Linux giflib库移植

一、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,测试结果如下

1928cbcda308a7b811d1245df0ca962f.png 三、移植到不同平台

        make CC=arm-linux-gcc 配置对应的交叉编译器即可

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值