目录简介术语TGA格式TGA头部(Header)图像/颜色表数据(Image/Color Map Data)颜色表数据(Color Map Data)图像数据(Image Data)开发者区域(Develop Area)扩展区域(EXTENSION AREA)TGA文件脚注(TGA FILE FOOTER)图像类型(Image Type)1: 颜色表图像类型2: 真彩图像3: 黑白图像(无颜色表)9: RLE压缩的颜色表图像10: RLE压缩的真彩图像11: RLE压缩的黑白图像RLE编码packet格式关于跨行参考
简介
TGA(or TARGA)是由Truevision公司开发的一种描述bitmap(位图)图像文件格式,能表示黑白、索引颜色、RGB颜色等bitmap,是目前应用最广泛的图像格式. 文件扩展名.tga,兼顾bitmap的图像质量、JPEG的小体积特点,支持不失真的压缩算法(RLE).
TGA格式文件目前有2个版本v1.0和v2.0: v1.0称为origin Truevision TGA; v2.0称为new TGA File或extension TGA File.
new TGA File解决了以下需求(也是新增内容, 如果没用到, 可不必关心):
The inclusion of a scaled-down “postage stamp” copy of the image 缩减版postage stamp图像副本
Date and Time of image file creation 图像文件创建的日期和时间
Author Name 作者名
Author Comments 作者备注
Job Name 作业名
Job Accumulated Time 作业累计时间
Gamma Value 伽马值
Correct Color LUT
Pixel Aspect Ratio 像素纵横比
Scan Line Offset Table 扫描线偏移表
Key Color 关键色
Software Package Name and Version Number 软件包名和版本号
Developer Definable Areas 开发商定义区域
Attribute (Alpha) channel Type 属性(α)通道类型
The ability for simple expansion 简单扩展能力
本文主要解析TGA v2.0格式(详见参考链接).
术语
Pseudo-Color(伪彩色): 将整个像素值用作可编程颜色表的单个索引, 该颜色表包含实际要显示的红、绿、蓝颜色强度. 使用这种图像的Truevision产品(硬件)有: VDA, VDA/D, TARGA M8, ATVista, NuVista和HR视频板.
True-Color(真彩): 每个像素的红、绿、蓝字段直接决定每种原色强度, 而非通过索引指向颜色表. 对应Truevision产品有: ICB, TARGA 16, TARGA 24, TARGA 32, ATVista和NuVista视频板.
Direct-Color(直接彩色): 每个像素分为红、绿、蓝字段, 但这些字段是单独的索引, 用来访问独立的可编程颜色查找表. 颜色表的查找结果决定了每个原色的强度. 直接彩色系统类似于伪彩色系统, 除了颜色表中的红、绿、蓝可单独改变(改单个索引或查找到的颜色值即可); 而伪彩色系统中的红、绿、蓝, 是绑定到一起存放在颜色表中的. 对应Truevision产品有: ATVista和NuVista视频板.
仅用作伪彩色设备: VDA, VDA/D, TARGA M8, HR;
仅用作真彩设备: ICB, TARGA 16, 24, 32.
Long = 32bit
Short = 16bit
Byte = 8bit
ASCII = C风格字符串, 多个字节, 以NUL byte结尾.
Bit Numbering(位序):
Byte Ordering(字节序): TGA采用Intel字节序(非Motorola字节序), 即低位字节优先. (tips: 解析跨字节整型数据时会用到, 如short, long类型)
TGA格式
TGA格式各主要组成部分及其分布, 如下图所示:
其中, 白底色模块为固定长度, 蓝底色部分表示可变长度(variable).
TGA头部(Header)
18byte头部,包含5个域:
域编号(field no.)
长度
域名
描述
1
1byte
Id length
Image id段长度,取值0~255. 0表示无id段
2
1byte
Color map type
是否包含颜色表(color map) 0: 不使用颜色表; 1: 使用颜色表
3
1byte
Image type
图像类型. 应用场景详见后文Image Types章节. 0~127为Truevision公司用于一般应用, 128~255供开发者使用. 0: 没有图像数据; 1: 未压缩的颜色表图像; 2: 未压缩的TRUE-COLOR图像; 3: 未压缩的黑白图像; 9: RLE压缩的颜色表图像; 10: RLE压缩的TRUE-COLOR图像; 11: 压缩的黑白图像.
4
5byte
Color map specification
描述颜色表规范. 如果Header.Color map type = 0, 则没有颜色表存在, 这5byte应全为0.
2byte
First Entry Index
颜色表起点, 即颜色表第一项的索引
2byte
Color map Length
颜色表长度, 即颜色表共有多少项
1byte
Color map Entry Size
颜色表项大小, 即每个项占用bit数. 典型值15, 16, 24, 32. 实际存储空间必须是整数字节, 即使是15(bit), 占用2byte存储空间, 可用16bit解析, 然后忽略第16bit
5
10byte
Image specification
描述图像维度和格式
2byte
X origin of Image
图像起点(左下角)x坐标. 基于屏幕原点在左下角
2byte
Y origin of Image
图像起点(左下角)y坐标. 基于屏幕原点在左下角
2byte
Image Width
图像宽度(单位: pixel)
2byte
Image Height
图像高度(单位: pixel)
1byte
Pixel Depth
像素深度, 即每个像素的bit数, 包含属性或α通道. 常用值8, 16, 24, 32
1byte
Image Descriptor
图像描述器. bit3~0: 关联到每个像素的属性位数, 对于Targa 16, 应为0或1; 对于Targa 24, 应为0; 对于Targa 32, 应为8. 与Field 24有关. bit5~4: 指示传输像素数据到屏幕的的顺序. bit4从左到右顺序, bit5为从上到下顺序. bit7~6: 须为0, 兼容未来版本.
图像/颜色表数据(Image/Color Map Data)
域编号(field no.)
长度
域名
描述
6
可变. 取决于Header.Id length(field 1)值
Image Id
可选域. Header.Id length = 0表明无该段
7
可变. 取决于Header.Color map type(field 2)及Color map Length(field 4.2), Color map Entry Size(4.3)
Color Map Data
实际颜色表信息. field 2 = 0, 表明无color map存在; field 2 = 1, 则长度为(field 4.2 * field 4.3)bits. 每个颜色表项(entry)用整数字节存储, 不会出现小数字节. 颜色表项的RGB颜色, 存放在多字节项的连续位段中.
8
可变.
Image Data
图像数据信息. 包含Width × Height pixels, Width和Height在Field 5.6, 5.5中定义. 每个像素都存储为整数字节.
颜色表数据(Color Map Data)
根据颜色表规范(Color Map Specification, field 4),知规定颜色表数据(field 7, Color Map Data)的规格信息:
Field No.
Name
Description
4.1
First Entry Index
颜色表的第一项的索引,我更愿称之为 第一个有效项的索引
4.2
Color map Length
颜色表中项的数量,注意是有效项的数量
4.3
Color map Entry Size
颜色表中每一项的大小(bits)
tips: 颜色表中, 每个元素称为一个颜色表项(Color Map Entry), 简称项(Entry).
问题1: 根据TGA格式文件各组成部分的排列,颜色表所在域Image Map Data紧跟Image ID, 前面的域都能确定大小, 为何还需要First Entry Index?
由于官方文档描述不清, 个人理解: 颜色表区域中存放着若干项, 但不一定都用到. 比如有1000项, 但只用了其中72个(从342开始),其他都无效. 此时, 可设置First Entry Index = 342, Color map Length = 72.
i.e. Field 7 Color Map Data中存放了所有项,而Field 4 Color Map Specification描述的是其中的有效项.
问题2:如何知道颜色表中,项的起始位置、数量?
项的起始(包括无效项),即颜色表的起始位置(Color Map Offset),由文件头Header大小 + Image ID大小(= ID Length)决定:
\[Color\ Map\ offset = Size\ of\ Header + ID\ Length
\]
问题3: 颜色表规范描述了有效的颜色表第一项的索引、项数、每项大小, 但存放什么内容呢?
存放RGB颜色值, 但每个R、G、B分量占用空间\(Size\ of (R/G/B)\)不一定是1byte或整数byte, 而是
\[Size\ of (R/G/B)= min(\frac{field\ 4.3}{3}, 8)bits
\]
例如,
Color map Entry Size = 8 => Size of (R/G/B) = min(8/3,8) = 2bit(other bits reserved);
Color map Entry Size = 16 => Size of (R/G/B) = min(16/3, 8) = 5bit;
Color map Entry Size = 24 => Size of (R/G/B) = min(24/3, 8) = 8bit;
Color map Entry Size = 32 => Size of (R/G/B) = min(32/3, 8) = 8bit.
图像数据(Image Data)
根据图像规范(field 5, Image specification), 知图像数据(field 8, Image Data)信息:
Image Width => 图像宽度(pixel)
Image Height => 图像高度(pixel)
Pixel Depth => 每个像素的位数, 通常是8、16、24、32(其他值也能用).
问题: Pixel存放什么?
根据不同的Image Type(详见后文), Pixel存放内容有不同的解读.
对于颜色表图像(COLOR-MAPPED), Image type(field 3)=1或9, Pixel存放的就是颜色表项的索引(基于前面的First Entry Index计算).
对于真彩图像(TRUE-COLOR), Image type(field 3)=2或10, Pixel存放的就是R、G、B值(由Image Descriptor决定属性位数, 即α通道).
对于黑白图像(BLACK and WHITE), Image type(field 3)=3或11, Pixel存放的就是灰度值(8bit即可).
Pixel通常会有下面几种类型:
from: TGA File Format Summary
可知,如果以从头到尾读取文件数据的角度看,Pixel存放颜色通道数据顺序(地址低到高,即LSB->MSB):
1)B,G,R
2)B,G,R,A
开发者区域(Develop Area)
域编号(field no.)
长度
域名
描述
9
取决于开发者
Develop Area
可用于存储任何类型信息, 推荐用于存储应用程序特定信息(即不适用于其他产品、未被TGA格式涵盖的信息). 大小、格式取决于开发者. 普通读者可忽略这段内容, 除非了解具体格式信息.
如果包含不止1个开发者区域,则创建一个开发者目录(Developer Directory)进行映射. Developer Directory由TGA File Footer(TGA脚注)的offset(field 29.2)指定位置.
扩展区域(EXTENSION AREA)
域编号(field no.)
长度
域名
描述
10~27
495byte 未来版本可能变化
Extension Area
用于满足开发者额外文件信息的需求. 由TGA File Footer(TGA脚注)域中的Extension Area Offset(field 29.1)指定位置, 如果Offset = 0, 该域不存在; 否则, Offset表面从文件开始计算的该域位置
10
2byte
Extension Size
扩展区域长度. 对于TGA v2.0, 该值为495.
11
41byte
Author Name
图像文件作者名. C风格字符串(ASCII编码), 须以NUL byte结尾. 如果没有用到, 必须都是NULL.
12
324byte
Author Comments
作者备注. 支持最多4行(每行80字符), 每行以NUL byte终结.
13
12byte
Date/Time Stamp
图像保存时的日期、时间戳, 由6个SHORT数组成. SHORT 0: 月份(1-12); SHORT1: 日(1-31); SHORT2: 年(4个数字, 如2024); SHORT3: 时(0-23); SHORT4: 分(0-59); SHORT5: 秒(0-59). 文件本身日期可能会被操作系统修改, 该段避免了这点. 如果未使用, 0填充.
14
41byte
Job Name/ID
作业名/ID. C风格字符串, 须以NUL byte结尾. 如果未使用, 可用NUL byte或space填充(非结尾部分).
15
6byte
Job Time
图像保存时作业运行时间, 由3个SHORT值组成: SHORT 0: 时(0-65535); SHORT 1: 分(0-59); SHORT 2: 秒(0-59). 如未使用, 0填充.
16
41byte
Software ID
软件ID, C风格字符串.
17
3byte
Software Version
软件版本, C风格字符串. SHORT(byte0~1): 版本号*100; BYTE(byte 2): 版本字母. e.g 版本号4.17b, 对应SHORT=417, BYTE='b'. 如未使用, SHORT=0b0, BYTE=space
18
4byte
Key Color
图像保存时的关键颜色, 可认为是"背景颜色"或"透明颜色". 格式: A:R:G:B, 其中A(最高字节)是α通道. 如未使用, 设置为0.
19
4byte
Pixel Aspect Ratio
像素纵横比. SHORT 0: 分子(像素宽); SHORT 1: 分母(像素高). 如果都设为相同非0值, 则图像用方形像素组成; 分母为0表示未指定.
20
4byte
Gamma Value
gamma值分数形式. SHORT 0: gamma分子; SHORT 1: gamma分母. 结果值应在0~10.0, 精度1位小数. 未校正的图像结果值应为1.0. 分母设为0, 表示未使用gamma段.
21~27
这部分不常用到, 略.
TGA文件脚注(TGA FILE FOOTER)
解析TGA文件时,如何判定是Origin TGA格式(v1.0)还是New TGA格式(v2.0)?
可读取TGA文件的最后26byte脚注来实现.
合法的脚注,byte8~23为签名"TRUEVISION-XFILE". 如果检测到签名,则为New TGA,说明包含Develop Area, Extension Area;否则,为Origin TGA.
Byte 0-3: The Extension Area Offset 扩展区域位置由该值决定;
Bytes 4-7: The Developer Directory Offset 见下文;
Bytes 8-23: The Signature 签名, 用于判定是否为NEW TGA
Byte 24: ASCII Character “.” NEW TGA固定值
Byte 25: Binary zero string terminator (0x00) 固定值
注意:不要求开发者读写、使用Extension或Develop Area,这些是可选的. 但推荐文件包含TGA File Footer.
域编号(field no.)
长度
域名
描述
28
4byte
Extension Area Offset
Extension Area的offset值, 从文件开头开始算, 可用seek()函数定位. 0表示无Extension Area.
29
4byte
Developer Directory Offset
Developer Directory的offset值. 0表示无Developer Directory Area.
30
16byte
Signature
签名, NEW TGA是"TRUEVISION-XFILE"
31
1byte
Reserved Character
保留. 须为".", 否则不认为是正确的TGA文件
32
1byte
Binary Zero String Terminator
二进制0终结符. TGA脚注可解读为C风格字符串.
图像类型(Image Type)
由Field 2(Color Map Type)和Field 3(Image Type)决定的图像类型,方便判断什么时候该用什么类型.
No.
Image
Use Color Map?
Use RLE?
Color Map Type
Image Type
1
COLOR-MAPPED IMAGES
Y
N
0x01
0x01
2
TRUE-COLOR IMAGES
N
N
0x00
0x02
3
BLACK AND WHITE (UNMAPPED) IMAGES
N
N
0x00
0x03
9
RUN-LENGTH ENCODED (RLE), COLOR-MAPPED IMAGES
Y
Y
0x01
0x09
10
RUN-LENGTH ENCODED (RLE), TRUE-COLOR IMAGES
N
Y
0x00
0x0A
11
RUN-LENGTH ENCODED (RLE), BLACK AND WHITE IMAGES
N
Y
0x00
0x0B
1: 颜色表图像类型
COLOR-MAPPED IMAGES,用于存储颜色表图像,如VDA/D,TARGA M8或颜色表TrueVista图像. 该格式能快速获取、显示,但会耗费较多存储空间. 适用于存储和显示时间很关键,但文件大小不重要的情形.
文件格式要求:Color Map Type = 0x01, Image Type = 0x01.
2: 真彩图像
TRUE-COLOR IMAGES,用于存储图像,其中每个像素都由红、绿、蓝表示(例如,ICB、TARGA 16、TARGA 24、TARGA 32、 TrueVISTA图像). 适用于存储和显示时间非常重要,但文件大小不重要的情形.
文件格式要求:Color Map Type = 0x00, Image Type = 0x02.
3: 黑白图像(无颜色表)
BLACK AND WHITE (UNMAPPED) IMAGES,用于存储光栅图像,其中每个像素由灰度值表示(如TARGA 8, M8及一些TrueVista模式).
文件格式要求:Color Map Type = 0x00, Image Type = 0x03.
9: RLE压缩的颜色表图像
RUN-LENGTH ENCODED (RLE), COLOR-MAPPED IMAGES,用于存储每个像素都由颜色表索引表示的图像.RLE算法压缩图像,节约大量存储空间.
文件格式要求:Color Map Type = 0x01, Image Type = 0x09.
10: RLE压缩的真彩图像
RUN-LENGTH ENCODED (RLE), TRUE-COLOR IMAGES,用于存储光栅图像,其中每个像素由红、绿、蓝表示. RLE算法压缩图像. 该格式用于存储ICB、TARGA 16/24/32、TrueVISTA(16bit RGB, 32bit RGB模式)图像. 适用于由计算机生成的图像,包含大段相同颜色.
文件格式要求:Color Map Type = 0x00, Image Type = 0x0A.
11: RLE压缩的黑白图像
RUN-LENGTH ENCODED (RLE), BLACK AND WHITE IMAGES,用于存储光栅图像,其中每个像素由灰度值表示. RLE压缩图像. 用于存储黑白TARGE 8/M8,及计算机生成的包含大段相同颜色的图像.
文件格式要求:Color Map Type = 0x00, Image Type = 0x0B.
RLE编码
RLE(run-length encoding),即游程编码、行程编码,是一种无损文件压缩算法. 图像数据类型9, 10, 11用到了RLE压缩图像.
RLE算法思想:连续相同的数值,用 重复数 + 数值 表示. 例如,文本文件中,原始字符串"AABCCC",经RLE编码后,变成"2A1B3C".
对于图像文件,用RLE算法对图像数据(Image Data)进行编码,所得图像称为RLE图像. 其中,包含2类数据元素:RLE packet、Raw packet.
packet格式
每个packet的第1个field占1byte,称为Repetition Count field(重复数字段). 第2个field占用若干byte(取决于field 5.5),称为Pixel Value field(像素值字段).
packet格式
Packet Header
bits
field name
description
b7
Packet Type
1: This is RLE packet; 0: This is Raw packet.
b6..0
Repetition Count
(number of pixels encoded by this packet) -1. Single packet Max val.= 127; if > 127, need to use multiple packets.
Repetition Count(重复数)指明后面Pixel Value重复的次数,范围0~127;超过127,就要用新的packets.
注意:Pixel Value重复的次数 = Repetition Count + 1,即Repetition Count = 0表示重复次数1,1表示重复次数2,...,127表示重复次数128.
Pixel Data
对于RLE packet, 用单个Pixel Value表示这些连续的多个像素,而Repetition Count对连续相同像素进行计数;
对于Raw packet,像素原来是怎么存储,现在依然不变,即用多个Pixel Value表示,而Repetition Count对连续相同的像素计数.
注意:
不论哪种格式,Repetition Count ≤ 127,当重复次数超过127+1时,需用到多个packet;
连续计数时,像素不能跨行.
例如,扫描到图像的一行有128个连续相同的像素,每个像素有24bit(3byte, for RGB). 现用RLE算法进行压缩. 需要多少存储空间?
如果用Raw packet存储,那么需要3byte * 128 = 384byte,再加上1byte Repitition Count,总计385byte;
如果用RLE packet存储,那么需要3byte表示重复像素,再加上1byte Repitition Count,总计4byte.
也就是说,Raw packet并不会减少图像存储空间,相反,会增加存储空间.
关于跨行
对于RLE packet,编码像素时,即使行尾与下一行头像素相同,绝不应该跨行. 应该怎么做?
编码为独立的packet,而不是同一个. 因为这样,软件能用扫描线快速随机访问每行.
参考
TGA 2.0 File Format Specifications
TGA File Format Summary
【数据压缩】TGA文件格式分析 | CSDN
【数据压缩2】TGA格式图片文件分析 | CSDN