📄 gif.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 + -