一:tga图像格式
https://blog.csdn.net/blues1021/article/details/45438673
tga存储格式:移小端模式存储,包括格式规定以及RGB数据,也就是BGR形式存放(直接读入即可),图片左上角的一行像素可能放在文件内存中的最后一行,或者文件内存中的一行就是左上角一行数据,tga头文件记录了调色板偏移大小和规格,图像像素的偏移大小和规格,常见格式有非压缩RGB和压缩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:压缩格式
名称 |
偏移 |
长度 |
说明 |
||
图像信息字段长度 |
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格式是:bgra8888,以四位数据存储:eg 0x00428119 ;则低位到高位依次为bgra,则b为19,这里所说的存储位置与数据位置正好相反。
二:gif图片格式
https://blog.csdn.net/poisx/article/details/79122506
https://www.cnblogs.com/senior-engineer/p/9548347.html(png格式)
https://blog.csdn.net/yun_hen/article/details/78134636 (bmp像素格式解析)
https://blog.csdn.net/aidem_brown/article/details/80500637(bmp像素格式)
https://www.xuebuyuan.com/800319.html(mov格式)
我这采用的mov格式是argb8888
GIF内部按块划分,包括数据块和控制块两部分,
二:转换公式:(RGB)
Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16
Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128
R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
B' = 1.164*(Y’-16) + 2.017*(Cb'-128)
部分程序
unsigned int rgb_y = 0x00428119, rgb_u = 0x00dab670, rgb_v = 0x0070a3ee;//00eea370;
unsigned int est_y = 0x00001080, est_uv = 0x00008080;
for (i = 0; i < height; i++)
{
for (j = 0; j < wid; j += 4)
{
rgba1 = pReadBuf[j];
rgba2 = pReadBuf[j+1];
rgba3 = pReadBuf[j+2];
rgba4 = pReadBuf[j+3];
//UFIR8UU:字节的四个数相乘
y1 = UBYTESEL(UFIR8UU(rgba1, rgb_y) + est_y, 1); //y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
y2 = UBYTESEL(UFIR8UU(rgba2, rgb_y) + est_y, 1);
y3 = UBYTESEL(UFIR8UU(rgba3, rgb_y) + est_y, 1);
y4 = UBYTESEL(UFIR8UU(rgba4, rgb_y) + est_y, 1);
u1 = UBYTESEL(IFIR8UI(rgba1, rgb_u) + est_uv, 1);//u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
u2 = UBYTESEL(IFIR8UI(rgba3, rgb_u) + est_uv, 1);
v1 = UBYTESEL(IFIR8UI(rgba2, rgb_v) + est_uv, 1);
v2 = UBYTESEL(IFIR8UI(rgba4, rgb_v) + est_uv, 1);//v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
a1 = UBYTESEL(rgba1, alpha);
a2 = UBYTESEL(rgba2, alpha);
a3 = UBYTESEL(rgba3, alpha);
a4 = UBYTESEL(rgba4, alpha);
if(a1 > 253) a1 = 253;
if(a2 > 253) a2 = 253;
if(a3 > 253) a3 = 253;
if(a4 > 253) a4 = 253;
pWriteBuf[j ] = PACK16LSB(y1, PACKBYTES(u1, a1));
pWriteBuf[j+1] = PACK16LSB(y2, PACKBYTES(v1, a2));
pWriteBuf[j+2] = PACK16LSB(y3, PACKBYTES(u2, a3));
pWriteBuf[j+3] = PACK16LSB(y4, PACKBYTES(v2, a4));
}
for (j = wid; j < width; j++)
{
rgba1 = pReadBuf[j];
y1 = UBYTESEL(UFIR8UU(rgba1, rgb_y) + est_y, 1);
if (width & 0x01)
{
u1 = UBYTESEL(IFIR8UI(rgba1, rgb_v) + est_uv, 1);
}
else
{
u1 = UBYTESEL(IFIR8UI(rgba1, rgb_u) + est_uv, 1);
}
pWriteBuf[j] = PACK16LSB(y1, PACKBYTES(u1, UBYTESEL(rgba1, alpha)));
}
pWriteBuf += width;
if (tgaFormat == 0)
{
pReadBuf += width;
}
else
{
pReadBuf -= width;
}
}