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. Selenium4自动化测试6--控件获取数据--下拉框级联选择、checkbox选择、时间选择器

    4-下拉框级联选择 import time from selenium.webdriver.support.select import Select #pip install selenium fro ...

  2. pageoffice6 版本实现word 文件添加水印

    在很多场景下,Word文档正式发文之前,或者说形成最终文档之前,常常需要往Word文件中添加水印,并且会根据文件类型或内容的不同,需要添加的水印也不一样. 添加水印是Word软件里的一个简单功能,直接 ...

  3. jenkens

    [root@mcw01 ~]$ ls .jenkins/ config.xml jenkins.install.UpgradeWizard.state nodeMonitors.xml secret. ...

  4. docker flannel网络

    部署etcd github部署访问链接:https://github.com/etcd-io/etcd/releases/ ETCD_VER=v3.5.1 # choose either URL GO ...

  5. 用Vue全家桶纯手工搓了一个开源版「抖音」

    前言 2018年刚入行前端时,公司使用的还是Angular.Angular什么都好,就是写代码时的体验老糟心了,改一个地方,按下保存之后,要等好几秒刷新后才能看到效果,Webstorm无比好用的自动保 ...

  6. css圆圈慢慢放大

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  7. LeetCode 40. Combination Sum II 组合总和 II (C++/Java)

    题目: Given a collection of candidate numbers (candidates) and a target number (target), find all uniq ...

  8. sql去重常用的基本方法

    1.存在两条完全相同的纪录 select distinct * from table(表名) where (条件)   2.存在部分字段相同的纪录(有主键id即唯一键) 如果是这种情况的话用disti ...

  9. Go 语言中的异常处理简单实践 panic、recover【GO 基础】

    〇.Go 中的异常处理简介 Golang 没有结构化异常,使用 panic 抛出错误,recover 捕获错误. panic.recover 参数类型为 interface{},因此可抛出任何类型对象 ...

  10. mysql 判断字符串结尾

    mysql 判断字符串结尾 CREATE TABLE `tbl_str` ( `id` INT DEFAULT NULL, `Str` VARCHAR(30) DEFAULT NULL) INSERT ...