# title: 图片压缩算法
date: 2022-04-07 12:00
count: true
tags: 图形学笔记
category: 图形学笔记

# 图片压缩算法

# DXTC

DXTC(或 BC)为微软为 DX 而推出的基于 block 的贴图压缩格式,其主要采用调色板的原理来进行压缩。

BC1:

基于 4x4block 来进行,不含有 alpha 通道,每个 block 内记录两个 16bits 的颜色做为基准颜色,然后解压时再使用两个基准色调制出另外两个颜色做为块内 4 个压缩颜色。其计算方式为:

basecolor2 = 2/3 *basecolor0 + 1/3 * basecolor1

basecolro3 = 1/3 *basecolor0 + 2/3 * basecolor1

对于每个块内的 texel,存储 2bits 的索引,用来指向到 4 个基准颜色中的一个。所以对于 BC1 的压缩状态为 64bits:

BC3:

在 BC1 的基础上支持 alpha 通道。首先,颜色的存储方式与 BC1 相同,需要 64bits;对于 alpha 部分,使用与颜色部分相同的策略来处理。在 block 存储两个基准的 alpha 值,然后在其基础上插值得到其它 6 个共计 8 个 alpha 值,来做为 alpha 的调色板;然后对于每个 texel 存储一个 3bits 的索引,用来指向到这 8 个 alpha 中的一个。所以其对应的存储状态为:

同时,两个 alpha 值中的不同的标记情况也对应着不同的插值操作:

若 alpha0 > alpha1

alphai = (7 - i) / 7 *alpha0 + i/7 * alpha1;(2<=i<=7);

若 alpha0 < alpha1

alphai = (5 - i) / 5 *alpha0 + i/5 * alpha1;(2<=i<=5);

alpha6 = 0;

alpha7=255;

# ETC

ETC 压缩算法采用将图像中的 chromatic 和 luminance 分开存储的方式,而在解码时使用 luminance 对 chromatic 进行调制进而重现原始图像信息。

Untitled

ETC 也主要有两种方法:ETC1 和改进后的 ETC2。

# PVRTC

PVRTC 的不是基于 block 的方式生成的,但是却也可以理解为以 block 方式组织的。其生成压缩后包含两张 (w/4,h/4) 大小的缩略图(w,h 为原始图片的宽和高,可以理解为第 4 级的 mipmap,但生成过程会比较 mipmap 的复杂),其中的每个 pixel 映射并对应到原始图像中的一个 64x64 的 block 上;然后使用 1 张与原始图像大小相同的 modulate 图,对应的每个 pixel 占 2 个 bits,也即可对应四种调制方式,通过几种不同的调制方式还原出近似的原始像素值。

压缩后的一个 4x4 的 block 中的 bits 的组成内容为:

Untitled

通过调节上述两张缩略图的大小,可以相应的改变对应的压缩比,比如由(w/4,h/4)修改为(w/8,h/4),而其它的映射方式不变,即可将压缩比增大一倍。

# ASTC

ASTC 中 ARM 研发的一种较新的贴图压缩格式,相对于上述几种方法具有较多的优势,其应该会慢慢成为之后移动设备上贴图压缩的主要标准和主流。其主要具有如下的特性:

  1. 较高的灵活性;
  2. 可变的压缩率;
  3. 支持 2d/3d 贴图;
  4. 适用于移动平台;
  5. 支持 LDR/HDR 贴图内容;

ASTC 同样是基于 block 的压缩方式,但块的大小却较支持多种尺寸,比如从基本的 4x4 到 12x12,而且块的宽高也不限于 pot,比如 6x5;每个块内的内容用 128bits 来进行存储,因而不同的块就对应着不同的压缩率。

对于每个块,同样存储两个插值端点,称为 endpoints,但是这里的 endpoints 不一定是基于颜色的(RGBA),也可以基于 layer,比如对于 R,G,B,A 甚或其中的组合如 RG 等,这样的话就可以用来对 normal map 或 alpha map 进行更好的压缩;

对于块中的每个 texel,存储其对应于 endpoints 的插件 weight,但是存储的 weight 数量可以比 texel 少,特别是对于规格较大的块(比如 12x12),这种情况下会首先对于每个 texel 通过线性插值得到其对就应的 weight,然后再进行颜色的计算;

对于块内颜色分布较为复杂的情况,分析块内颜色的分布,然后做 partition,对于每个 partition 进行分别的处理(与 ETC2 中将颜色分布对应到具体的预知分布模式中的处理方法不同),分别存储其对应的 endpoints;这样一来对于块内的某个 texel 进行取值时就先定位其对应的 partition,然后再计算在其在对应的小子块内的颜色。

块内信息的存储采用了 BISE 的方式来进行压缩,尽可能的节省对应的存储空间。比如对于一组 5 个表示范围已知的整型数值,采用 BISE 存储后可节省两个 bits,这样就使用每个块内较大量的数据存储于 128bits 内成为可能;

对于单 layer 的一个 block 内的 bits 组织大概如下所示:

更多的细节可以看这里

4.1 Bounded Integer sequence encoding

主要是针对范围限定的整数序列进行压缩存储进而节省空间。比如对于三个数 4,78,55,其直接用 binary 的表示为 0000100,1001110,0110111,直接存储二进制序列的话需要 7bits * 3 = 21bits(在已知最大范围为 78 的情况下,不需要存储满 8bits)。但是能不能在 21bits 的基础上再减少呢?BISE 就是实现这样的目的的。

假设序列的范围为 N,对应的 bit 位数为 n:

这里的背后其实是基于这样的一个事实,比如在基于 3 的压缩中,如果 N<=32n-2,那么在 N 的最高两位 bit 上,其并不会出现 22 种情况的所有组合(因其大小是受限的),到少 11 这样的组合就是没有的,否则其对应的值必定大于 N。所以 BISE 压缩就是将受限的整数序列中的前两位数据中的无效 bits 进行合理使用。比如,在上述 4,78,55 的序列中,78 <= 5 * 2^4 = 80,所以可以使用基于 5 的 BISE,将三个数的二进制序列构造为{000 0100, 100 1100, 011 0111},高三位的组合为{000,100,011},因这三个 3 位 bits 序列中的最大值是 5,所以每三个 bits 最多有 5 种情况,那么这个高三位组合的序列共可能有 5^3=125 种组合情况,这样的话就可以使用 7bits 的空间来存储所有的这些组合,如此一来就可以将原来 33=9bits 的存储空间存储在 7bits 中,进而达到压缩的目的。