• 全部
  • 问答

关于GIF颜色表及解码的问题

CommanSource 2005-02-17 11:43:59

#include <conio.h>
#include <stdlib.h>
#include <alloc.h>
#include <stdio.h>
#include <graphics.h>
#include <dos.h>
#include <fcntl.h>
#include <string.h>
#include <process.h>
#include <bios.h>
#include "gif89.c"
unsigned int lowidth,lohigth;
char page_new=0,page_old=0;

void selectpage(register char page)
{ union REGS r;
r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page;
int86(0x10,&r,&r);
}

unsigned char set_SVGA_mode(int vmode)
{
union REGS r;
r.x.ax=0x4f02;
r.x.bx=vmode;
int86(0x10,&r,&r);
return(r.h.ah);
}

unsigned int get_SVGA_mode()
{ union REGS r;
r.x.ax=0x4f03;
int86(0x10,&r,&r);
return(r.x.bx);
}

void PutPoint(int x, int y, char Color)
{
long position;
position=y*640l+x;
page_new=position/65536l;
if(page_new!=page_old)
selectpage(page_new);
pokeb(0xa000,position%65536l,Color);
}

void Out_Line(char *ptr, int x, int y,int width)
{
int i;
for(i=0; i<width; i++)
{
PutPoint(x++,y,ptr[i]);
}
}

void disp(unsigned char *image,unsigned char *pattern,unsigned int width,unsigned int higth)
{
int i,j,k,max,may;
char* buffer;
char* mage;
/* write to display card*/
buffer = (char*)malloc(width);
mage = (unsigned char*)malloc(width*higth);
for(i=0; i<higth*width; i++)
{
mage[i] = pattern[image[i]];
}
k=(width%4)?(4-width%4):0;
max=(640+width)/2-width;
may=(480-higth)/2+higth;

for(j=0;j<higth;j++)
{
fread(buffer,width,1,mage);
Out_Line(buffer,max,may-j,width);
fseek(mage,k,1);
}
}


void main(int argc,char *argv[])
{
unsigned char pat[256][3];
int bit_count,savemode;
unsigned int j;
long i;
unsigned int frames;
FRAME* fm;
char* all;
unsigned int grwidth,grhigth;
unsigned int delayTime;
GLOBAL_INFO* gi;
char* File = "C:\\ibm1.gif";
unsigned int seg = 0;
if(CGif89a(File,seg)==1)
{
printf("open error!");
exit(1);
}
savemode=get_SVGA_mode();
set_SVGA_mode(0x101);
gi = getGlobalInfo();
lowidth = gi->scrWidth;
lohigth = gi->scrHeight;
frames = gi->frames;
if(frames=1)
{
fm==NULL;
fm = getNextFrame();
if(fm == NULL)
{
printf("NO more frame!");
return;
}
grwidth= fm->imageWidth;
grhigth= fm->imageHeight;
if(fm->lFlag==1)
{
disp(fm->dataBuf,fm->pColorTable,grwidth,grhigth);
}
else
{
disp(fm->dataBuf,gi->gColorTable,grwidth,grhigth);
}
getchar();
}
else
{
while(1)
{
j=0;
for(;j<frames;j++)
{
memset(MK_FP(0xa000,0),0,lowidth*lohigth);
fm==NULL;
fm = getNextFrame();
if(fm == NULL)
{
printf("NO more frame!");
return;
}
grwidth= fm->imageWidth;
grhigth= fm->imageHeight;
if(fm->lFlag==1)
{
disp(fm->dataBuf,fm->pColorTable,grwidth,grhigth);
}
else
{
disp(fm->dataBuf,gi->gColorTable,grwidth,grhigth);
}

sleep(fm->ctrlExt.delayTime*100);
}
}
}
getchar();
free(gi);
free(fm);
fclose(File);
bioskey(0);
set_SVGA_mode(savemode);
}
小弟最近需要写一个能在TC中显示GIF动画的程序,是用GIF89A做为解码来做的
但是一直不能正确显示GIF图片(不管是一帧还是多帧),怀疑是颜色表索引的问题
而且图象也不能正确显示,估计是解码的问题。还有如何显示透明色也不太明白。希望各位高手能帮帮
小弟,不甚感激,谢谢
...全文
250 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
applebomb 2005-02-27
我也很想帮你,但是我这里只有一个写入GIF的,可以运行的,你看看它的代码
读取是写的逆操作,应该对你有帮助

/*--GIF动画生成.
程序中type的值为2则按16色的格式生成动画;type的值为3则按256色
mode的值为0按顺序方式压缩数据,mode的值为1则按交叉方式压缩
数据,生其的动画文件可直接在浏览器中播放.
TC20 small模式下编译通过--*/
#include<stdio.h>
#include<graphics.h>

#define MAXCODES 4096
#define TABLESIZES 4999

int left,top,width,right,bottom,type,mode;
unsigned char blockbuf[256],colorbits;
int clearcode,eofcode,encode;
int encodetable[TABLESIZES];
int initbits,runbits,shiftbits;
int maxcodesize,bytecount;
unsigned long tempcodes;
int linestart[]={0,4,2,1};
int rowcount[]={8,8,4,2};

void getcolortable(int colortable[16][3])/* 设置16色颜色表 */
{int i,j;
int color[16]={0,1,2,3,4,5,22,7,56,57,58,59,60,61,62,63};
for(i=0;i<16;i++)
{j=color[i];
if(i==6)j=20;
outportb(0x3c7,((unsigned char)j));
colortable[i][0]=inportb(0x3c9);
colortable[i][1]=inportb(0x3c9);
colortable[i][2]=inportb(0x3c9);
}
}

void globalheader(FILE * fp)
{int i,colornum,colortable[16][3];
unsigned char pal[768];
struct globalhead{
unsigned char signature[6];
unsigned int width;
unsigned int height;
unsigned char flag;
unsigned char color;
unsigned char ratio;
}gif;
memcpy(gif.signature,"GIF89a",6);/* Gif 数字签名 GIF89a */
gif.width=right-left;
gif.height=bottom-top;

if(type==2)
colorbits=4;
else colorbits=8;/* 色深 */
gif.flag=(colorbits-1<<4)|(colorbits-1);
if(type!=1)gif.flag|=0x80;

gif.color=0;gif.ratio=0;
fwrite(&gif,1,13,fp);/* GIF 文件头:13BYTE */

if(gif.flag&0x80){
for(i=0;i<768;i++)pal[i]=0;
getcolortable(colortable);
for(i=0;i<16;i++)
{pal[3*i]=colortable[i][0]<<2;
pal[3*i+1]=colortable[i][1]<<2;
pal[3*i+2]=colortable[i][2]<<2;
}
colornum=3*(1<<colorbits);
fwrite(&pal,1,colornum,fp);
}
}

void localheader(FILE * fp)
{struct localhead{
unsigned char label;
unsigned int left;
unsigned int top;
unsigned int width;
unsigned int height;
unsigned char flag;
}image;
image.label=0x2c;image.left=0;image.top=0;
image.width=right-left;image.height=bottom-top;
image.flag=colorbits-1;
if(mode)image.flag|=0x40;
fwrite(&image,1,10,fp);
}

void cleartable()
{int count;
encode=eofcode+1;runbits=initbits+1;maxcodesize=1<<runbits;
for(count=0;count<TABLESIZES;count++)encodetable[count]=0;
}

void savecode(FILE * fp)
{blockbuf[0]=bytecount;bytecount++;
fwrite(blockbuf,1,bytecount,fp);
bytecount=0;
}

void fillblockbuf(FILE * fp,int code)
{tempcodes|=(unsigned long)code<<shiftbits;shiftbits+=runbits;
while(shiftbits>=8)
{blockbuf[++bytecount]=tempcodes&0x00ff;
if(bytecount==255)savecode(fp);tempcodes>>=8;shiftbits-=8;
}
}

void LZWimage(FILE * fp) /* 写入LZW数据 */
{unsigned char suffixtable[TABLESIZES],bytebuf[640],now;
int i,prefixtable[TABLESIZES],prefixcode,suffixcode,index,off;
unsigned int width,height,row,dot,online;
width=right-left;height=bottom-top;initbits=colorbits;

if(initbits>8)exit(1);/* 不支持高于256色 */

fputc(initbits,fp);
clearcode=1<<initbits;
eofcode=clearcode+1;
bytecount=shiftbits=0;
tempcodes=0;
cleartable();/* 清空索引表 */

fillblockbuf(fp,clearcode);
for(row=0,online=0,now=0;row<height;row++)/* 处理所有行 */
{
for(i=0;i<width;i++)
bytebuf[i]=getpixel(left+i,top+online);
if(mode){online+=rowcount[now];
if(online>=height){now++;online=linestart[now];}
}
else online++;
if(row==0){prefixcode=bytebuf[0];dot=1;}
else dot=0;

while(dot<width)/* 压缩一行信息 */
{suffixcode=bytebuf[dot++];
index=prefixcode^(suffixcode<<4);
if(index==0)off=1;else off=TABLESIZES-index;
while(1)
{if(encodetable[index]==0)
{fillblockbuf(fp,prefixcode);
if(encode==MAXCODES)
{fillblockbuf(fp,clearcode);cleartable();}
else
{if(encode==maxcodesize)
{maxcodesize<<=1;runbits++;
}
prefixtable[index]=prefixcode;
suffixtable[index]=suffixcode;encodetable[index]=encode++;
}
prefixcode=suffixcode;break;
}
if(prefixtable[index]==prefixcode&&suffixtable[index]==suffixcode)
{prefixcode=encodetable[index];break;}
else
{index-=off;if(index<0)index+=TABLESIZES;}
}
}
}
fillblockbuf(fp,prefixcode);fillblockbuf(fp,eofcode);
if(shiftbits>0||bytecount>0)
{blockbuf[++bytecount]=tempcodes&0x00ff;savecode(fp);}
fputc(0,fp);
}

void applyblock(FILE * fp)
{
struct
{unsigned char extension;
unsigned char label;
unsigned char size;
char identifier[8];
char code[3];
char data[4];
unsigned char teminator;
}application;

application.extension=0x21;
application.label=0xff;application.size=11;
memcpy(application.identifier,"NETSCAPE",8);
memcpy(application.code,"2.0",3);application.data[0]=3;
application.data[1]=1;application.data[2]=0xe8;application.data[3]=3;
application.teminator=0;
fwrite(&application,1,19,fp);
}

void controlblock(FILE * fp,int delaytime)
{struct{unsigned char extension;
unsigned char label;
unsigned char size;
unsigned char field;
unsigned int delaytime;
unsigned char colorindex;
unsigned char terminator;
}control;
control.extension=0x21;control.label=0xf9;
control.size=4;control.field=0;
control.delaytime=delaytime;control.colorindex=0;
control.terminator=0;fwrite(&control,1,8,fp);
}


void formgif()/* 使用GIF函数,输出GIF图象 */
{int i,charsize=4;
char * text="GIF Animator!";
FILE * fp;
settextstyle(TRIPLEX_FONT,HORIZ_DIR,charsize);
left=220;top=200;right=420;bottom=280;type=3;mode=0;
if((fp=fopen("animator.gif","wb"))==NULL)
{printf("Can not create Gif file!\n");exit(1);}

globalheader(fp); /* 写入全局头 */
applyblock(fp); /* 写入应用程序声明头 */

for(i=1;i<22;i++)
{setcolor(GREEN);outtextxy(right-20*i,top+20,text);

controlblock(fp,20); /* 写入控制块 */
localheader(fp); /* 写入局部头 */
LZWimage(fp); /* 写入LZW数据 */

delay(200);setcolor(BLACK);outtextxy(right-20*i,top+20,text);
}
fputc(';',fp);fclose(fp);
}
main()
{int gd,gm,gerror;
detectgraph(&gd,&gm);initgraph(&gd,&gm,"");
cleardevice();formgif();closegraph();
}
回复
CommanSource 2005-02-21
唉,没人能帮忙吗?
回复
CommanSource 2005-02-18
对不起,这个代码有很多问题,例如多帧的时候没有返回第一帧等,但现在最重要的问题还是色表和解压,因只有一帧的时候也无法使用!
回复
xuelong_zl 2005-02-18
没学过,up先
回复
CommanSource 2005-02-18
对的,你仔细看我的程序就知道是从下到上进行扫描的,哇,都快崩溃了
回复
CommanSource 2005-02-18
恩,谢谢,提醒,请问BMP和GIF图片的存储顺序不一样吗?这个程序是由一个显示BMP图片改过来的,可以正确显示,郁闷!
回复
Dong 2005-02-18
好像你的读取有问题
图片的存储是:
从下到上
从左到右
不是直接读取的

比如:
1 2 3
4 5 6
7 8 9

存储后的数据是789456123
回复
CommanSource 2005-02-18
就是色表的问题,应该将RGB提取出来,转成256色的色标,但是怎么弄呢?
我手上只有RGBTO16BIT的方法,郁闷
回复
相关推荐
发帖
C语言
创建于2007-09-28

6.3w+

社区成员

C语言相关问题讨论
申请成为版主
帖子事件
创建了帖子
2005-02-17 11:43
社区公告
暂无公告