本来以为,ETC1作为Android 设备的OpenGL标准,开源且最常用的的一种压缩纹理格式,总会有人去翻译一下khronos的文档,读一下代码,给大家作个普及的,不料就是搜不到。没办法,尽管英文不好,还是硬啃了下文档,把 ETC1压缩纹理的实现原理弄清楚了。
https://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt

至于什么是压缩纹理,如何使用,可以参考:
http://blog.csdn.net/wanglang3081/article/details/8869589

ETC1的文件头

文件头大小为16:

#define ETC_PKM_HEADER_SIZE 16

将ETC1纹理存成pkm文件时,加上这个文件头,便于读取时获知大小、格式,上传压缩纹理时把这个头去掉。

文件头内容为:特征符——编码宽——编码高——实际宽——实际高

static const char kMagic[] = { 'P', 'K', 'M', ' ', '1', '0' };static const etc1_uint32 ETC1_PKM_FORMAT_OFFSET = 6;
static const etc1_uint32 ETC1_PKM_ENCODED_WIDTH_OFFSET = 8;
static const etc1_uint32 ETC1_PKM_ENCODED_HEIGHT_OFFSET = 10;
static const etc1_uint32 ETC1_PKM_WIDTH_OFFSET = 12;
static const etc1_uint32 ETC1_PKM_HEIGHT_OFFSET = 14;

尽管ETC1是固定的压缩比,但考虑到像素不对齐的情况,实际宽和实际高还是有必要存储的。

编码构成

Jpeg压缩标准是把图像划分为一系列8X8的像素块,然后每个像素块压缩成变长编码的。ETC1则是4X4的像素块压缩成固定的64位编码(8字节),由于固定,才有利于GPU内部实现并行解压缩。

#define ETC1_ENCODED_BLOCK_SIZE 8
#define ETC1_DECODED_BLOCK_SIZE 48 // RGB 三分量 * 4 * 4

因此,不考虑像素非4对齐的情况,它的压缩比是固定的48/8=6,至于常用的把ARGB分别存储为两张ETC1纹理的做法,压缩比是64/16=4。
像素不对齐的情况如何处理,就自己想想吧,反正不是大问题。

4X4的像素点与64位编码对应关系如下:
1、将 4X4 的像素点划分为两个subblock,横分或者竖分【1个位表示:flipbit】。
2、两部分的像素RGB求均值,总共用24个位表示两个RGB均值,分两种方案【1个位表示:diffbit】
(1)两个subblock的RGB均值都用4位表示。刚好4*3*2=24位。
(2)两个subblock的RGB值相差在 [-4,3]区间(5位表示的情况下,对应常规的8位表示是[-32,24]),第一个subblock的RGB值用5位表示,第二个用3位差值表示。
3、解码时,像素值由RGB均值加上差值而得,差值表为8X4大小。每一个subblock使用的是其中一行【行号需要3个位,两个subblock,加起来6个位】,每个像素点对应所取差值行中一个数【编号需要2个位,这样就16X2=32个位】。PS:RGB三个分量是用同一个差值。

64位的编码分成两部分,高位和低位。
低位存储每个像素点的差值行序号,按大端存储方式,分两部分,前一部分存储高位,后一部分存储低位。
高位存储RGB均值,subblock所用的差值表行号,再加上 flipbit 和 diffbit
详细内容直接上文档上的图:

横分/竖分示例图,图中每个字母代码一个像素:

编码过程

ETC1的编码流程如下:
1、将图像划分为一系列 4X4 的子块。
2、对每个子块,尝试所有的编码可能性,取解码后和原block像素差值和最小的一种编码。
(1)是否flip,这个决定subblock如何划分
(2)每个subblock用哪一行差值表
(3)每个像素取哪一列的差值
注:决定好flip之后,颜色均值和是否能用diff方式已经确定,这个不用遍历。
3、合并所有子块编码。

不难看出,编码过程需要遍历所有可能性,其复杂度远大于解码,每一个 RGB 像素变成了一个精度较低的RGB均值和一个2位差值号,因此产生压缩。这种预测式表述自然本身就存在偏差,压缩损失亦来自于此。

ETC1压缩纹理格式详解相关推荐

  1. 三维重建:PNG格式详解-与LibPNG使用

    PNG图像包含了骨骼信息,左边的图像比右边的大几十K,包含了骨骼信息:        PNG格式详解:https://blog.mythsman.com/post/5d2d62b4a2005d7404 ...

  2. linux下tar命令解压缩,tar解压缩命令 Linux下的tar压缩解压缩命令详解

    <tar解压缩命令 Linux下的tar压缩解压缩命令详解>由会员分享,可在线阅读,更多相关<tar解压缩命令 Linux下的tar压缩解压缩命令详解(14页珍藏版)>请在人人 ...

  3. Gerber 格式详解

    Gerber 格式详解 gerber中文 gerber,gerber 文件:590m.com/f/25127180-487459253-79168e(访问密码:551685) 以下内容无关: ---- ...

  4. BMP格式详解<转>

    BMP格式详解 BMP文件格式详解(BMP file format) BMP文件格式,又称为Bitmap(位图)或是DIB(Device-Independent Device,设备无关位图),是Win ...

  5. bmp图片的格式详解

    BMP文件格式详解(BMP file format) BMP文件格式,又称为Bitmap(位图)或是DIB(Device-Independent Device,设备无关位图),是Windows系统中广 ...

  6. 图片 bmp 格式详解

    1 概述 BMP(Bitmap-File)图片文件格式,又称为 Bitmap (位图)或是 DIB(Device-Independent Device,设备无关位图),是 Windows 系统中广泛使 ...

  7. Ffmpeg快速命令使用 Ffmpeg选项详解 Ffmepg格式详解 常见视频文件格式详解

    http://www.ffmpeg.com.cn/index.php/%E9%A6%96%E9%A1%B5 Ffmpeg快速命令使用 From Ffmpeg工程组 Jump to: navigatio ...

  8. ffmpeg-jpeg图片格式详解

    jpg/jpeg是24位的图像文件格式,也是一种高效率的压缩格式 JPEG格式可以分为 1.标准JPEG:只有图片完全被加载和读取完毕之后,才能看到图片的全貌 2.渐进式JPEG:(标准的改进)首先呈 ...

  9. BMP位图格式详解二--转载

    转自:http://www.cnblogs.com/xiehy/archive/2011/06/07/2074405.html BMP文件格式,又称为Bitmap(位图)或是DIB(Device-In ...

最新文章

  1. 【camera】全景驾驶感知网络YOLOP部署与实现(交通目标检测、可驾驶区域分割、车道线检测)
  2. day12-mysql 增删改查
  3. Const *ptr ptr
  4. 员工提出离职,称害怕猝死,HR却说:先猝死了再说!
  5. linux上使用git把代码push到gitee上
  6. 利用DBMS_FILE_TRANSFER传输数据库文件
  7. Android开发之Handler机制记录
  8. weblogic安全漫谈
  9. P1429-平面最近点对(加强版)【分治】
  10. spring学习(51):对象的初始化和销毁
  11. Python的虚拟环境配置(pyenv+virtualenv)
  12. table超出边框出现滚动条_精美横轴智能滚动条设计
  13. 详细解读Python 递归函数!
  14. Oracle11g安装完成后给用户解锁
  15. windows环境下安装zookeeper教程详解(单机版)
  16. python编程案例教程-Python程序开发案例教程
  17. JCam2 v1.6.0 USB摄像头工具全新发布及使用详解
  18. IE浏览器无法连接网络的解决办法
  19. 云桌面到底是干什么的?
  20. 2018新年计划-雄起

热门文章

  1. Mysql,日志文件
  2. uni-app安装到建立项目开发环境
  3. flask之搭建web服务
  4. Java设计模式之责任链模式(简单易懂)
  5. STM32CubeMX配置注意事项
  6. 企业选择大数据应用程序,需要考虑哪些因素?
  7. IT男在深圳--求生存篇
  8. RS232 422 485定义、接口、接线图
  9. unbound学习笔记
  10. opencv-blob