• 最简GIF解析代码gif_jumper,用于stb_image的小改进


    gif jumper

    gif支持多帧动画,但是没有存储总帧数,解析gif直到结束才能知道总帧数。

    所以gif解析代码,要么采用链表,要么不停realloc()分配内存,stb_image的代码就是如此。

    出于本人的强迫症,于是写了一段代码,迅速“跳过”解析过程,返回总帧数,聊胜于无,仅供参考:

    同时也可以作为gif格式的帮助文档,毕竟最好的文档就是代码。

    格式

    • GIF文件头(Header)
    • 逻辑屏幕描述块(Logical Screen Descriptor)
    • 全局彩色表(GlobalColor Table)
    • 图像描述块(Image Descriptor)
    • 局部彩色表(Local Color Table)
    • 图形控制扩展块(Graphic Control Extension)
    • 注释扩展块(Comment Extension)
    • 应用扩展块(Application Extension)
    • 无格式文本扩展块(PlainText Extension)
    • 文件结束块(Trailer)

    源码

    #define JUMP(c, offset) c+=offset
    #define INT8(n, offset) n=*offset
    #define INT8_BIT(n, offset, s, e) n=(unsigned char)((*offset)<<s)>>(s+7-e)
    static int gif_jumper(unsigned char *start, unsigned char *end)
    {
        int num=0;
        int frames=0;
        unsigned char *cur=start;
        
        JUMP(cur, 6); // Header(6bytes)
        JUMP(cur, 4); // Logical Screen Descriptor(7bytes)
        INT8_BIT(num, cur, 0, 0); // Global Color Table Flag
        if(num) {
            INT8_BIT(num, cur, 5, 7); // Size of Global Color Table = 2^(pixel+1)
            JUMP(cur, 3+3*(1 << (num+1)));
        } else {
            JUMP(cur, 3);
        }
    
        while(cur<end) {
            INT8(num, cur);
            switch(num) {
                case 0x2C: // Image Descriptor(9bytes)
                    frames++;
                    JUMP(cur, 1+8);
                    INT8_BIT(num, cur, 0, 0); // Local Color Table Flag
                    if(num) {
                        INT8_BIT(num, cur, 5, 7); // Size of Local Color Table = 2^(pixel+1)
                        JUMP(cur, 1+3*(1 << (num+1)));
                    } else {
                        JUMP(cur, 1);
                    }
                    JUMP(cur, 1); // LZW Minimum Code Size
                    while(cur<end) {
                        INT8(num, cur); // Table-Based Image Data
                        JUMP(cur, 1+num);
                        if (num==0) { 
                            break; // Block Terminator
                        }
                    }
                    break;
                case 0x21: // Extension
                    JUMP(cur, 2); // Extension Introducer
                    while(cur<end) {
                        INT8(num, cur); // Table-Based Image Data
                        JUMP(cur, 1+num);
                        if (num==0) { 
                            break; // Block Terminator
                        }
                    }
                    break;
                case 0x3B: // Trailer
                    JUMP(cur, 1);
                    break;
                default:   
                    return 0;
            }
        };
        return frames;
    }

      

    参考文档:

    GIF文件格式详解

    gif 格式图片详细解析

  • 相关阅读:
    MongoDB学习:(一)MongoDB安装
    事件轮询 Event Loop
    常见的HTML5语义化标签
    前端动画性能优化方案
    前端动画的实现
    《SVN的操作流程及规范》
    css、js文件后的后缀作用是什么?
    实现单行文字溢出显示...,以及多行文字溢出显示...
    从输入URL到页面返回的过程详解
    jQuery实现点击复制效果
  • 原文地址:https://www.cnblogs.com/windfic/p/14372057.html
Copyright © 2020-2023  润新知