一: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; } }
|