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 格式图片详细解析

最简GIF解析代码gif_jumper,用于stb_image的小改进的更多相关文章

  1. [webpack]--webpack 如何解析代码模块路径

    前言 webpack是如何解析代码模块路径 webpack 中有一个很关键的模块 enhanced-resolve 就是处理依赖模块路径的解析的,这个模块可以说是 Node.js 那一套模块路径解析的 ...

  2. Delphi汉字简繁体转换代码(分为D7和D2010版本)

    //delphi 7 Delphi汉字简繁体转换代码unit ChineseCharactersConvert; interface uses   Classes, Windows; type   T ...

  3. UWP 在 WebView 中执行 JavaScript 代码(用于模拟用户输入等) - walterlv

    原文:UWP 在 WebView 中执行 JavaScript 代码(用于模拟用户输入等) - walterlv UWP 在 WebView 中执行 JavaScript 代码(用于模拟用户输入等) ...

  4. Beaver解析代码反向生成语法文件

    背景 Beaver是一款LALR的语法生成工具,现在有一个反编译项目的需求,需要将Beaver语法文件编译后的代码反向生成语法文件的需求,不去评论需求多么傻逼,直接干 设计 flowchart 语法文 ...

  5. QueryDet: Cascaded Sparse Query for Accelerating High-Resolution Small Object Detection(QueryDet:用于加速高分辨率小目标检测的级联稀疏查询)

    QueryDet: Cascaded Sparse Query for Accelerating High-Resolution Small Object Detection(QueryDet:用于加 ...

  6. js 日期计算星座 根据生日的月份和日期,一行代码计算星座的js小函数(转)

    本博客根据 开源中国作者清风徐不来 的文章 根据生日的月份和日期,一行代码计算星座的js小函数(转) 原文出自CSDN 无心的专栏 的文章,知识产权归原文作者所有! 点击查看原文:js 日期计算星座

  7. stl文件格式解析代码--java版

    代码是参考three.js中的stlLoader.js写的. 需要注意的地方,java中byte取值-128~127 package test_stl.test_entry; import java. ...

  8. PE格式文件的解析代码

    #include "Global.h" ; //标志,用于表示是否为pe32+文件 ; //标志,用于表示读入的模式,若为0代表是内存读入,不为0,代表是文件打开,此时mode是文 ...

  9. h264文件分析(纯c解析代码)

    参考链接:1. 解析H264的SPS信息 https://blog.csdn.net/lizhijian21/article/details/80982403               2. h.2 ...

  10. 你一定看得懂的 DDD+CQRS+EDA+ES 核心思想与极简可运行代码示例

    前言 随着分布式架构微服务的兴起,DDD(领域驱动设计).CQRS(命令查询职责分离).EDA(事件驱动架构).ES(事件溯源)等概念也一并成为时下的火热概念,我也在早些时候阅读了一些大佬的分析文,学 ...

随机推荐

  1. MegaCli64查看磁盘损坏,错误个数统计情况

    如下,两个命令,是磁盘濒临崩坏,比如存在扇区损坏之类的事情发生.咨询的浪潮热线,报sn.他们的临界值是500,我们监控脚本是200告警.Predictive Failure Count 这个的数字比M ...

  2. Istio(十二):Istio问题排查

    目录 一.模块概览 二.Envoy基础 2.1 Envoy 基础 三.Envoy示例 四.调试备忘录 4.1 配置 4.2 运行时 4.3 检查 Envoy 日志 4.4 配置 istiod 日志 一 ...

  3. [Unity] 实现AssetBundle资源加载管理器

    实现Unity AssetBundle资源加载管理器 AssetBundle是实现资源热更新的重要功能,但Unity为其提供的API却十分基(jian)础(lou).像是自动加载依赖包.重复加载缓存. ...

  4. Android OpenMAX(二)OMX Component实现基础

    Android OpenMAX IL提供的API位于 frameworks/native/headers/media_plugin/media/openmax ,目录下存放有预定义的类型.组件句柄定义 ...

  5. SignalR 客户端源生成器 客户端强类型方法

    SignalR 客户端源生成器根据您定义的接口生成强类型的发送和接收代码.您可以在客户端上重用来自强类型 SignalR 集线器的相同接口来代替松散类型的 .On("methodName&q ...

  6. swift_slowAlloc Crash 分析

    一.Crash详情 Crash类型 exception EXC_BREAKPOINT (SIGTRAP) reason EXC_BREAKPOINT EXC_ARM_BREAKPOINT fault_ ...

  7. react props-type

    对于组件来说,props是外部传入的,无法保证组件使用者传入什么格式的数据,简单来说就是组件调用者可能不知道组件封装着需要什么样的数据,如果传入的数据不对,可能会导致程序异常,所以必须要对于props ...

  8. rsync备份任务练习

    06-备份任务实战 今天的任务主要以实际备份任务入手,完成综合练习,完成对rsync的综合运用. 先看需求 再讲解 再次动手实践 客户端需求 客户端需求: 1.客户端每天凌晨1点在服务器本地打包备份( ...

  9. Vue学习:12.生命周期实例

    两个小例子,巩固一下生命周期钩子函数. 实例1:初始化渲染 实现功能: 在 Vue 实例数据为空的情况下,用户在一进入页面就向服务器发送请求获取数据,并在数据返回后进行动态渲染. 思路: 创建一个 V ...

  10. java.util.Date和java.sql.Date有什么区别?

    java.util.Date包含日期和时间,而java.sql.Date只包含日期信息,而没有具体的时间信息.如果你想把时间信息存储在数据库       里,可以考虑使用Timestamp或者Date ...