⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gif.h

📁 这个版本修正了已知的Bug,同时添加了部分函数
💻 H
字号:
#define pack_fseek(f,off) fseek(f,off,SEEK_CUR)

struct
{
	short base;
	char  new_c;
	short length;
} str[4096];

struct
{
 FILE *f;
 short empty_string, curr_bit_size, bit_overflow;
 short bit_pos, data_pos;
 int data_len, entire, code;
 int cc, string_length, i, bit_size;
 unsigned char string[4096];
 BITMAP *bmp;
 short image_x, image_y, image_w, image_h, x, y;
 short interlace, gif_len, gif_wid, gif_error;
 unsigned char Col_Index[256];
}Gif_info,*GIF_INF;



void clear_table(void)
{
	GIF_INF->empty_string = GIF_INF->cc + 2;
	GIF_INF->curr_bit_size = GIF_INF->bit_size + 1;
	GIF_INF->bit_overflow = 0;
}


 void get_code(void)
{
if(GIF_INF->bit_pos + GIF_INF->curr_bit_size > 8) {
	if(GIF_INF->data_pos >= GIF_INF->data_len) { GIF_INF->data_len = fgetc(GIF_INF->f); GIF_INF->data_pos = 0; }
	GIF_INF->entire = (fgetc(GIF_INF->f) << 8) + GIF_INF->entire;
	GIF_INF->data_pos ++;
}
if(GIF_INF->bit_pos + GIF_INF->curr_bit_size > 16) {
	if(GIF_INF->data_pos >= GIF_INF->data_len) { GIF_INF->data_len = fgetc(GIF_INF->f); GIF_INF->data_pos = 0; }
	GIF_INF->entire = (fgetc(GIF_INF->f) << 16) + GIF_INF->entire;
	GIF_INF->data_pos ++;
}
GIF_INF->code = (GIF_INF->entire >> GIF_INF->bit_pos) & ((1 << GIF_INF->curr_bit_size) - 1);
if(GIF_INF->bit_pos + GIF_INF->curr_bit_size > 8)
	GIF_INF->entire >>= 8;
if(GIF_INF->bit_pos + GIF_INF->curr_bit_size > 16)
	GIF_INF->entire >>= 8;
GIF_INF->bit_pos = (GIF_INF->bit_pos + GIF_INF->curr_bit_size) % 8;
if(GIF_INF->bit_pos == 0) {
	if(GIF_INF->data_pos >= GIF_INF->data_len) { GIF_INF->data_len = fgetc(GIF_INF->f); GIF_INF->data_pos = 0; }
	GIF_INF->entire = fgetc(GIF_INF->f);
	GIF_INF->data_pos ++;
}
}


 void get_string(int num)
{
	if(num < GIF_INF->cc)
	{
		GIF_INF->string_length = 1;
		GIF_INF->string[0] = str[num].new_c;
	}
	else
	{
		GIF_INF->i = str[num].length;
		GIF_INF->string_length = GIF_INF->i;
		while(GIF_INF->i > 0)
		{
			GIF_INF->i --;
			GIF_INF->string[GIF_INF->i] = str[num].new_c;
			num = str[num].base;
		}
	}
}

void output_string(char bool)
{       int lptr;
	for(GIF_INF->i = 0; GIF_INF->i < GIF_INF->string_length; GIF_INF->i ++)
	{    lptr=GIF_INF->x+GIF_INF->y*GIF_INF->bmp->w;
         if (lptr>=0&&lptr<GIF_INF->gif_len*GIF_INF->gif_wid)
         if(bool)
         GIF_INF->bmp->dat[lptr]=GIF_INF->Col_Index[GIF_INF->string[GIF_INF->i]];
         else
         GIF_INF->bmp->dat[lptr]=GIF_INF->string[GIF_INF->i];
            else GIF_INF->gif_error=1;
	GIF_INF->x ++;
	if(GIF_INF->x >= GIF_INF->image_x + GIF_INF->image_w)
	{
	GIF_INF->x = GIF_INF->image_x;
	GIF_INF->y += GIF_INF->interlace;
	if(GIF_INF->interlace)
		{
		if(GIF_INF->y >= GIF_INF->image_y + GIF_INF->image_h)
		{
		if(GIF_INF->interlace == 8 && (GIF_INF->y - GIF_INF->image_y) % 8 == 0) {
		GIF_INF->interlace = 8;
		GIF_INF->y = GIF_INF->image_y + 4;
		}
		else if(GIF_INF->interlace == 8  && (GIF_INF->y - GIF_INF->image_y) % 8 == 4) {
		GIF_INF->interlace = 4;
		GIF_INF->y = GIF_INF->image_y + 2;
		}
		else if(GIF_INF->interlace == 4) {
		GIF_INF->interlace = 2;
		GIF_INF->y = GIF_INF->image_y + 1;
		}
		}
	}
	}
	}
}

 int   pack_mgetw(FILE *f)
{ unsigned short w[2],i;
  for (i=0;i<2;i++) w[i]=fgetc(f); 
  return (unsigned)w[0]*256+w[1];
}

 int   pack_igetw(FILE *f)
{ int b1,b2;
  b1=fgetc(f); b2=fgetc(f);
  return ( (b2<<8) | b1 );
}

BITMAP *load_gif(char *filename,char bloot)
{
	short width, height, depth;
	short old;PALETTE pal;
        GIF_INF=&Gif_info;
       if((GIF_INF->f = fopen(filename, "rb"))==NULL)
          {
           sprintf(grp_err,"Can't Open File %s",filename);
	    return FALSE;
          }
	GIF_INF->i  = pack_mgetw(GIF_INF->f) << 8;
	GIF_INF->i += fgetc(GIF_INF->f);
	if(GIF_INF->i != 0x474946) /* is it really a GIF? */
	{
         sprintf(grp_err,"The File isn't GIF format %s",filename);
		fclose(GIF_INF->f);
          return FALSE;
	}
	pack_fseek(GIF_INF->f, 3); /* skip version */

	width = pack_igetw(GIF_INF->f);
	height = pack_igetw(GIF_INF->f);

        GIF_INF->bmp=create_bitmap(width,height);

        GIF_INF->gif_error=0; GIF_INF->gif_len=width; GIF_INF->gif_wid=height;

        if(GIF_INF->bmp->dat==NULL) {
                fclose(GIF_INF->f);
                grp_exit();
                sprintf(grp_err,"Creating Surface error");
                return FALSE;
        }
	GIF_INF->i = fgetc(GIF_INF->f);
	if(GIF_INF->i & 128) /* no global colour table? */
		depth = (GIF_INF->i & 7) + 1;
	else
		depth = 0;
	pack_fseek(GIF_INF->f, 2);	/* skip background colour and aspect ratio */

	if(pal&& depth) /* only read palette if pal and depth are not 0 */
	{
		for(GIF_INF->i = 0; GIF_INF->i < (1 << depth); GIF_INF->i ++)
		{
			pal[GIF_INF->i].r = fgetc(GIF_INF->f) / 4;
			pal[GIF_INF->i].g = fgetc(GIF_INF->f) / 4;
			pal[GIF_INF->i].b = fgetc(GIF_INF->f) / 4;
                   if(bloot)
                   GIF_INF->Col_Index[GIF_INF->i]=get_color(pal[GIF_INF->i].r,
                                    pal[GIF_INF->i].g,pal[GIF_INF->i].b);
		}
	}
	else
		if(depth)
			pack_fseek(GIF_INF->f, (1 << depth) * 3);

do
{
	GIF_INF->i = fgetc(GIF_INF->f);
	switch(GIF_INF->i)
	{
	case 0x2C: /* Image Descriptor */
 		GIF_INF->image_x = pack_igetw(GIF_INF->f);
		GIF_INF->image_y = pack_igetw(GIF_INF->f); /* individual image dimensions */
		GIF_INF->image_w = pack_igetw(GIF_INF->f);
		GIF_INF->image_h = pack_igetw(GIF_INF->f);
		GIF_INF->i = fgetc(GIF_INF->f);
		if(GIF_INF->i & 64)
	          GIF_INF->interlace = 8;
		else
			GIF_INF->interlace= 1;
			if(GIF_INF->i & 128)
		{
			depth = (GIF_INF->i & 7) + 1;
			if(pal)
			{
			for(GIF_INF->i = 0; GIF_INF->i < (1 << depth); GIF_INF->i ++)
			{
			pal[GIF_INF->i].r = fgetc(GIF_INF->f) / 4;
			pal[GIF_INF->i].g = fgetc(GIF_INF->f) / 4;
			pal[GIF_INF->i].b = fgetc(GIF_INF->f) / 4;
                  if(bloot)
                  GIF_INF->Col_Index[GIF_INF->i]=get_color(pal[GIF_INF->i].r,
                                       pal[GIF_INF->i].g,pal[GIF_INF->i].b);
			}
		}
	//	else
//		pack_fseek(GIF_INF->f, (1 << depth) * 3);
	}
		/* lzw stream starts now */
	GIF_INF->bit_size = fgetc(GIF_INF->f);
	GIF_INF->cc = 1 << GIF_INF->bit_size;
	/* initialise GIF_INF->string table */
        for(GIF_INF->i = 0; GIF_INF->i < GIF_INF->cc; GIF_INF->i ++)
		{
		str[GIF_INF->i].base = -1;
		str[GIF_INF->i].new_c = GIF_INF->i;
		str[GIF_INF->i].length = 1;
		}
        	/* initialise the variables */
	GIF_INF->bit_pos = 0;
	GIF_INF->data_len= fgetc(GIF_INF->f); GIF_INF->data_pos = 0;
	GIF_INF->entire = fgetc(GIF_INF->f); GIF_INF->data_pos ++;
	GIF_INF->string_length = 0; GIF_INF->x = GIF_INF->image_x;
        GIF_INF->y = GIF_INF->image_y;
        	/* starting GIF_INF->code */
	clear_table();
	get_code();
	if(GIF_INF->code == GIF_INF->cc)
	get_code();
	get_string(GIF_INF->code);
	output_string(bloot);
	old = GIF_INF->code;
        	while(TRUE)
		{
		get_code();
        	if(GIF_INF->code == GIF_INF->cc)
		{
		/* starting GIF_INF->code */
		clear_table();
		get_code();
		get_string(GIF_INF->code);
		output_string(bloot);
		old = GIF_INF->code;
		}
		else if(GIF_INF->code == GIF_INF->cc + 1)
			{
			break;
		}
		else if(GIF_INF->code < GIF_INF->empty_string)
		{
		get_string(GIF_INF->code);
		output_string(bloot);
        	if(GIF_INF->bit_overflow == 0) {
	        str[GIF_INF->empty_string].base = old;
		str[GIF_INF->empty_string].new_c = GIF_INF->string[0];
		str[GIF_INF->empty_string].length = str[old].length + 1;
		GIF_INF->empty_string ++;
		if(GIF_INF->empty_string == (1 << GIF_INF->curr_bit_size))
		GIF_INF->curr_bit_size ++;
		if(GIF_INF->curr_bit_size == 13) {
		GIF_INF->curr_bit_size = 12;
		GIF_INF->bit_overflow = 1;
		}
		}
                old = GIF_INF->code;
		}
		else
		{
		get_string(old);
		GIF_INF->string[str[old].length] = GIF_INF->string[0];
		GIF_INF->string_length ++;
                if(GIF_INF->bit_overflow == 0) {
		str[GIF_INF->empty_string].base = old;
		str[GIF_INF->empty_string].new_c = GIF_INF->string[0];
		str[GIF_INF->empty_string].length = str[old].length + 1;
		GIF_INF->empty_string ++;
		if(GIF_INF->empty_string== (1 << GIF_INF->curr_bit_size))
		GIF_INF->curr_bit_size ++;
		if(GIF_INF->curr_bit_size == 13) {
		GIF_INF->curr_bit_size = 12;
		GIF_INF->bit_overflow = 1;
		}
		}
                output_string(bloot);
		old = GIF_INF->code;
		}
	        }
		break;
		case 0x21: /* Extension Introducer */
		GIF_INF->i = fgetc(GIF_INF->f);
		if(GIF_INF->i == 0xF9) /* Graphic Control Extension */
		{
			pack_fseek(GIF_INF->f, 1); /* skip size (it's 4) */
			GIF_INF->i = fgetc(GIF_INF->f);
			if(GIF_INF->i & 1) /* is transparency enabled? */
			{
				pack_fseek(GIF_INF->f, 2);
				fgetc(GIF_INF->f); /* transparent colour */
			}
			else
				pack_fseek(GIF_INF->f, 3);
		}
		GIF_INF->i = fgetc(GIF_INF->f);
		while(GIF_INF->i) /* skip Data Sub-blocks */
		{
			pack_fseek(GIF_INF->f, GIF_INF->i);
			GIF_INF->i = fgetc(GIF_INF->f);
		}
		break;
                      case   -1:
		case 0x3B: /* Trailer - end of data */
			fclose(GIF_INF->f);
                        return GIF_INF->bmp;

		}
	} while(!GIF_INF->gif_error);
	return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -