TGA文件格式

TGA文件是计算机图像文件一种 。TGA是由美国Truevision公司为其显示卡开发的一种图像文件格式,已被国际上的图形、图像工业所接受。现已成为数字化图像,以及运用光线跟踪算法所产生的高质量图像的常用格式。TGA文件的扩展名为·tga,该格式支持压缩,使用不失真的压缩算法,可以带通道图,另外还支持行程编码压缩。

 

文件格式介绍如下:

Tga常见的格式有非压缩RGB和压缩RGB两种格式。文件的第三个Byte位作为标记:2为非压缩RGB格式,10为压缩RGB格式。它们的具体格式如下:

1、非压缩格式

图片类型:2-非压缩RGB格式

 

名称

偏移

长度

说明

图像信息字段长度

0

1

本字段是 1 字节无符号整型,指出图像信息字段( 见本子表的后面 )长度,其取值范围是 0 到 255 ,当它为 0 时表示没有图像的信息字段。

颜色表类型

1

1

0 表示没有颜色表,1 表示颜色表存在。由于本格式是无颜色表的,因此此项通常被忽略。

图像类型码

2

1

该字段总为 2 , 这也是此类型为格式 2 的原因。

颜色表规格字段

颜色表首址

3

2

颜色表首的入口索引,整型(低位-高位) 

如果颜色表字段为0,则忽略该字段

颜色表的长度

5

2

颜色表的表项总数,整型(低位-高位)

颜色表项位数

7

1

位数(bit),16 代表 16 位 TGA ,24 代表 24 位 TGA ,32 代表 32 位 TGA

图像规格字段

图像 X 坐标起始位置

8

2

图像左下角 X坐标的整型(低位-高位)值

图像 Y 坐标起始位置

10

2

图像左下角 Y坐标的整型(低位-高位)值

图像宽度

12

2

以像素为单位,图像宽度的整型(低位-高位)

图像高度

14

2

以像素为单位,图像宽度的整型(低位-高位)

图像每像素存储占用位数

16

2

它的值为16,24 或 32 等等。决定了该图像是 TGA 16,TGA24,TGA 32 等等。

图像描述符字节

17

1

bits 3-0 - 每像素对应的属性位的位数;

对于TGA 16, 该值为 0 或 1,对于 TGA 24,该值为 0,对于 TGA 32,该值为 8。

bit 4 - 保留,必须为 0

bit 5 - 屏幕起始位置标志

0 = 原点在左下角

1 = 原点在左上角

对于 truevision 图像必须为 0

bits 7-6 - 交叉数据存储标志

00 = 无交叉

01 = 两路奇/偶交叉

10 = 四路交叉

11 = 保留

图像信息字段

18

可变

包含一个自由格式的,长度是图像由“图像信息字段”指定。它常常被忽略(即偏移 0 处值为 0 ),注意其最大可以含有 255 个字符。如果需要存储更多信息,可以放在图像数据之后。

颜色表数据

可变

可变

如果颜色表类型为 0,则该域不存在,否则越过该域直接读取图像颜色表规格中描述了每项的字节数,为 2,3,4 之一。

图像数据

可变

可变

RGB颜色数据,存放顺序为:BBB GGG RRR (AAA)

2、压缩格式

图片类型:10-压缩RGB格式

 

名称

偏移

长度

说明

图像信息字段长度

0

1

本字段是 1 字节无符号整型,指出图像信息字段( 见本子表的后面 )长度,其取值范围是 0 到 255 ,当它为 0 时表示没有图像的信息字段。

颜色表类型

1

1

0 表示没有颜色表,1 表示颜色表存在。由于本格式是无颜色表的,因此此项通常被忽略。

图像类型码

2

1

该字段总为 10 , 这也是此类型为格式 10 的原因。

颜色表规格字段

颜色表首址

3

2

颜色表首的入口索引,整型(低位-高位) 

如果颜色表字段为0,则忽略该字段

颜色表的长度

5

2

颜色表的表项总数,整型(低位-高位)

颜色表项位数

7

1

位数(bit),16 代表 16 位 TGA ,24 代表 24 位 TGA ,32 代表 32 位 TGA

图像规格字段

图像 X 坐标起始位置

8

2

图像左下角 X坐标的整型(低位-高位)值

图像 Y 坐标起始位置

10

2

图像左下角 Y坐标的整型(低位-高位)值

图像宽度

12

2

以像素为单位,图像宽度的整型(低位-高位)

图像高度

14

2

以像素为单位,图像宽度的整型(低位-高位)

图像每像素存储占用位数

16

2

它的值为16,24 或 32 等等。决定了该图像是 TGA 16,TGA24,TGA 32 等等。

图像描述符字节

17

1

bits 3-0 - 每像素对应的属性位的位数;

对于TGA 16, 该值为 0 或 1,对于 TGA 24,该值为 0,对于 TGA 32,该值为 8。

bit 4 - 保留,必须为 0

bit 5 - 屏幕起始位置标志

0 = 原点在左下角

1 = 原点在左上角

对于 truevision 图像必须为 0

bits 7-6 - 交叉数据存储标志

00 = 无交叉

01 = 两路奇/偶交叉

10 = 四路交叉

11 = 保留

图像信息字段

18

可变

包含一个自由格式的,长度是图像由“图像信息字段”指定。它常常被忽略(即偏移 0 处值为 0 ),注意其最大可以含有 255 个字符。如果需要存储更多信息,可以放在图像数据之后。

颜色表数据

可变

可变

如果颜色表类型为 0,则该域不存在,否则越过该域直接读取图像颜色表规格中描述了每项的字节数,为 2,3,4 之一。

图像数据

可变

可变

采用RLE压缩后的RGB颜色数据。

Tga的压缩算法采用了RLE算法,RLE算法的基本思想是将数据分为两大类:

A:连续的不重复字节

B:连续的重复字节

RLE算法应用于RGB格式的图片压缩中,则把数据分为:

A:连续的不重复像素颜色值

B:连续的重复像素颜色值

然后将数据按这两类数据分成若干长度不相等数据块,每个数据块的开始都是一个1个字节长度的header(RLE在纯数据压缩中header位2个字节16位),后面紧跟着data数据块,如下。

 

Header(1个字节)

Data(变长)

每个header的第一位作为标记:0表示A类颜色数据,1表示B类颜色数据。剩下的7位意义如下:

对于A类数据:表示data有多少个像素的RGB颜色值。取值0-127,0表示1个像素,所以最多为128个像素,data块则为这些不重复的像素RGB颜色值。

对于B类数据:表示有多少个像素具有相同的RGB颜色值。取值0-127,0表示1个像素,所以最多为128个像素,data仅包含一个像素的颜色值,即为重复的那个颜色值。

实现将TGA文件(非压缩)加载到内存的代码如下(OpenGL)

 

bool LoadTGA(TextureImage *texture, char *filename) // Loads A TGA File Into Memory
{ 
	GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
	GLubyte TGAcompare[12]; // Used To Compare TGA Header
	GLubyte header[6]; // First 6 Useful Bytes From The Header
	GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
	GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
	GLuint temp; // Temporary Variable
	GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP)

	FILE *file = fopen(filename, "rb"); // Open The TGA File

	if( file==NULL || // Does File Even Exist?
		fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read?
		memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want?
		fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes
	{
		if (file == NULL) // Did The File Even Exist? *Added Jim Strong*
			return FALSE; // Return False
		else // Otherwise
		{
			fclose(file); // If Anything Failed, Close The File
			return FALSE; // Return False
		}
	}

	texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
	texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)

	if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero
		texture->height <=0 || // Is The Height Less Than Or Equal To Zero
		(header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit?
	{
		fclose(file); // If Anything Failed, Close The File
		return FALSE; // Return False
	}

	texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32)
	bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel
	imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data

	texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data

	if( texture->imageData==NULL || // Does The Storage Memory Exist?
		fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved?
	{
		if(texture->imageData!=NULL) // Was Image Data Loaded
			free(texture->imageData); // If So, Release The Image Data

		fclose(file); // Close The File
		return FALSE; // Return False
	}

	for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel) // Loop Through The Image Data
	{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
		temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i'
		texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
		texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
	}

	fclose (file); // Close The File

	// Build A Texture From The Data
	glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs

	glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered

	if (texture[0].bpp==24) // Was The TGA 24 Bits
	{
		type=GL_RGB; // If So Set The 'type' To GL_RGB
	}

	glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);

	return true; // Texture Building Went Ok, Return True
}

 

上面只是简单的介绍了TGA文件格式的一些情况,更详细的细节和代码可参考下面的链接:

TGA格式介绍(1)

TGA格式介绍(2)


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值