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

📄 gif.c

📁 在ecos 下mingui 的移植开发
💻 C
字号:
#include <assert.h>#include <stdio.h>#include <stdlib.h>#ifndef __ECOS# include <memory.h>#endif#include <string.h>#include "gif.h"const int v_incr[4]={8,8,4,2};const int v_start[4]={0,4,2,1};int unpack_gif(gif_info_t* ginfo){    int bpp;    int palette_size;    assert(ginfo->gif_surface==NULL);	assert(ginfo->gif_buffer!=NULL);    ginfo->gif_cur_buffer=ginfo->gif_buffer;        memcpy(&(ginfo->gif_global),             ginfo->gif_cur_buffer,             sizeof(gif_global_t));    ginfo->gif_x=0;    ginfo->gif_y=0;    ginfo->gif_surface=malloc(ginfo->gif_global.width*ginfo->gif_global.height*3);    ginfo->gif_cur_buffer+=GIF_GLOBAL_SIZE;    bpp=(ginfo->gif_global.flag&0x07)+1;    palette_size=(1<<bpp)*3;    memcpy(&(ginfo->gif_global_palette),             ginfo->gif_cur_buffer,             palette_size);    if (strncmp(ginfo->gif_global.magic_word,"GIF",3)!=0) {        return -1;    }    ginfo->gif_cur_buffer+=palette_size;    while(1) {        char block_type=*(ginfo->gif_cur_buffer);        ginfo->gif_cur_buffer++;        switch(block_type) {        case ',':             // unpack local image block            return unpack_local_image(ginfo);            break;        case '!':            {            // char sub_block_type=*(ginfo->gif_cur_buffer++);			unsigned char sub_block_size=*(ginfo->gif_cur_buffer++);            ginfo->gif_cur_buffer+=sub_block_size; // skip subblock            ginfo->gif_cur_buffer++;  // skip '0x00'            }            break;        default:            // unknown block , return false .            return -1;         }    }    return 0;}int unpack_local_image(gif_info_t* ginfo){    memcpy(&(ginfo->gif_local),             ginfo->gif_cur_buffer,             sizeof(gif_local_t));    ginfo->gif_cur_buffer+=GIF_LOCAL_SIZE;    ginfo->b_interlaced=ginfo->gif_local.flag&0x40;    ginfo->b_local_palette=ginfo->gif_local.flag&0x08;    if (ginfo->b_local_palette!=0) {        // load local palette ...        int bpp;        int palette_size;        bpp=(ginfo->gif_local.flag&0x07)+1;        palette_size=(1<<bpp)*3;        memcpy(&(ginfo->gif_local_palette),                 ginfo->gif_cur_buffer,                 palette_size);        ginfo->gif_cur_buffer+=palette_size;    }    return unpack_image_data(ginfo);}int unpack_image_data(gif_info_t* ginfo){    ginfo->first_ch=*(ginfo->gif_cur_buffer);        assert(ginfo->first_ch==1||           ginfo->first_ch==2||           ginfo->first_ch==4||           ginfo->first_ch==8);        ginfo->gif_cur_buffer++;    ginfo->gif_x=0;    ginfo->gif_y=0;    ginfo->CLEAR=1<<ginfo->first_ch;    ginfo->EOI=ginfo->CLEAR+1;    ginfo->request_bits=ginfo->first_ch+1;    while((ginfo->code=get_code(ginfo))!=ginfo->EOI) {        if (ginfo->code==ginfo->CLEAR) {            clear_code_table(ginfo,ginfo->CLEAR);        }        else  {            if (ginfo->code_table[ginfo->code].prefix==-2) {                insert_code_table(ginfo,ginfo->prefix,ginfo->prefix);            }            else {                if (ginfo->prefix!=-1) {                    insert_code_table(ginfo,ginfo->code,ginfo->prefix);                }            }            // output code ...            output_code(ginfo,ginfo->code);             ginfo->prefix=ginfo->code;        }    }    return 0;}void clear_code_table(gif_info_t* ginfo,int clear){    int i;    ginfo->free_code=clear+2;    ginfo->prefix=-1;    for(i=0;i<clear;i++) {        ginfo->code_table[i].first=i;   // first char         ginfo->code_table[i].last=i;    // last char         ginfo->code_table[i].prefix=-1; // prefix index     }    for(i=clear;i<4096;i++) {        ginfo->code_table[i].prefix=-2;    }    ginfo->request_bits=ginfo->first_ch+1;    ginfo->code_limit=1<<ginfo->request_bits;}void insert_code_table(gif_info_t* ginfo,int code,int prefix){    ginfo->code_table[ginfo->free_code].prefix=ginfo->prefix;    ginfo->code_table[ginfo->free_code].last=ginfo->code_table[code].first;    ginfo->code_table[ginfo->free_code].first=ginfo->code_table[prefix].first;    ginfo->free_code++;    if (ginfo->free_code==ginfo->code_limit) {        if (ginfo->request_bits<12) {            ginfo->request_bits++;            ginfo->code_limit=1<<ginfo->request_bits;        }    }}void output_code(gif_info_t* ginfo,int code){    int i=0;    while(code!=-1) {        ginfo->code_string[i++]=ginfo->code_table[code].last;        code=ginfo->code_table[code].prefix;    }    for(i--;i>=0;i--) {        output_pixel(ginfo,ginfo->code_string[i]);    }}void output_pixel(gif_info_t* ginfo,unsigned char pixel) {    unsigned char r,g,b;    if (ginfo->b_local_palette!=0) {        r=ginfo->gif_local_palette.palette[pixel*3];        g=ginfo->gif_local_palette.palette[pixel*3+1];        b=ginfo->gif_local_palette.palette[pixel*3+2];    }    else {        r=ginfo->gif_global_palette.palette[pixel*3];        g=ginfo->gif_global_palette.palette[pixel*3+1];        b=ginfo->gif_global_palette.palette[pixel*3+2];    }    draw_pixel(ginfo,r,g,b);    ginfo->gif_x++;    if (ginfo->gif_x>=ginfo->gif_local.width) {        ginfo->gif_x=0;        if (ginfo->b_interlaced==0) {            ginfo->gif_y++;        }        else {            ginfo->gif_y+=v_incr[ginfo->pass];            if (ginfo->gif_y>=ginfo->gif_local.height) {                ginfo->pass++;                ginfo->gif_y=v_start[ginfo->pass];            }        }    }}/* * get request_bits from buffer */int get_code(gif_info_t* ginfo){    int request_bits=ginfo->request_bits;    int  value=0;    int  mask;    int  position=0,use_bits=0;    while(request_bits>0) {        if (ginfo->remain_bits==0) {            if (ginfo->remain_bytes==0) {                ginfo->remain_bytes=*ginfo->gif_cur_buffer++;            }            ginfo->remain_bytes--;            ginfo->remain_bits=8;            ginfo->data=*ginfo->gif_cur_buffer++;        }        if (request_bits>=ginfo->remain_bits) {            use_bits=ginfo->remain_bits;        }        else {            use_bits=request_bits;        }        ginfo->remain_bits-=use_bits;        mask=0xff>>(8-use_bits);        mask&=ginfo->data;        // store remain useful bits to low bits of data        ginfo->data>>=use_bits;        mask<<=position;        // new position that bits should be placed next time         position+=use_bits;        // insert these bits to the value        value|=mask;        request_bits-=use_bits;    }    return value;}void draw_pixel(gif_info_t* ginfo,int r,int g,int b){    int x,y;    int offset;    unsigned char* mem;    x=ginfo->gif_x;    y=ginfo->gif_y;    offset=ginfo->gif_local.width*y+x;    mem=(unsigned char*)(ginfo->gif_surface);    mem+=offset*3;    if (r>=0) {        *mem=(char)r;    }    mem++;    if (g>=0) {        *mem=(char)g;    }    mem++;    if (b>=0) {        *mem=(char)b;    }    mem++;}void destroy_gif(gif_info_t* ginfo) {    if (ginfo->gif_surface!=NULL) {        free(ginfo->gif_surface);    }}

⌨️ 快捷键说明

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