文件头
#include "pch.h"
#include
#include
#include
#include
#include
#include
using namespace std;
TGA结构体
typedef struct _TgaHeader
{
BYTE IDLength;
BYTE ColorMapType;
BYTE ImageType;
}TGAHEAD;
typedef struct _TgaHeaderCMap
{
WORD CMapStart;
WORD CMapLength;
BYTE CMapDepth;
}TGAHEADCMAP;
typedef struct _TgaHeaderImage
{
WORD XOffset;
WORD YOffset;
WORD Width;
WORD Height;
BYTE PixelDepth;
BYTE ImageDescriptor;
}TGAHEADIMG;
打开文件
int main()
{
FILE *TgaFile = NULL, *YuvFile = NULL, *RgbFile = NULL;
if ((TgaFile = fopen("D:\\数据压缩\\16.tga", "rb")) == NULL)
{
printf("tga file open failed!");
exit(0);
}
if ((YuvFile = fopen("D:\\数据压缩\\16.yuv", "wb")) == NULL)
{
printf("yuv file open failed!");
exit(0);
}
TGAHEAD tga_header;
TGAHEADCMAP tga_header_cmap;
TGAHEADIMG tga_header_img;
fread(&tga_header, 3, 1, TgaFile);
fread(&tga_header_cmap, 5, 1, TgaFile);
fread(&tga_header_img, 10, 1, TgaFile);
unsigned char* ImageData = NULL;
unsigned char* b = NULL;
unsigned char* g = NULL;
unsigned char* r = NULL;
unsigned char* R = NULL;
unsigned char* G = NULL;
unsigned char* B = NULL;
unsigned char* Y = NULL;
unsigned char* U = NULL;
unsigned char* V = NULL;
unsigned char* u = NULL;
unsigned char* v = NULL;
unsigned char* RGB = NULL;
unsigned char* YUV = NULL;
颜色表部分
if (tga_header.ColorMapType == 0)//不带颜色表
{
if (tga_header.ImageType == 0)
exit(0);
else if (tga_header.ImageType == 2)//未压缩的真彩色图像
{
int depth = tga_header_img.PixelDepth;
int width = tga_header_img.Width;
int height = tga_header_img.Height;
int size = width * height * depth / 8;//整个图像块的大小
cout << "该文件是未压缩的真彩色图像" << endl;
cout << "图像分辨率为" << width << "×" << height << endl;
cout << "像素深度为" << depth << "bit" << endl;
ImageData = new unsigned char[size];
fread(ImageData, 1, size, TgaFile);
b = (unsigned char *)malloc(sizeof(char)*(width * height));
g = (unsigned char *)malloc(sizeof(char)*(width * height));
r = (unsigned char *)malloc(sizeof(char)*(width * height));
R = (unsigned char *)malloc(sizeof(char)*(width * height));
G = (unsigned char *)malloc(sizeof(char)*(width * height));
B = (unsigned char *)malloc(sizeof(char)*(width * height));
Y = (unsigned char *)malloc(sizeof(char)*(width * height));
U = (unsigned char *)malloc(sizeof(char)*(width * height));
V = (unsigned char *)malloc(sizeof(char)*(width * height));
u = (unsigned char *)malloc(sizeof(char)*(width * height / 4));
v = (unsigned char *)malloc(sizeof(char)*(width * height / 4));
RGB = new unsigned char[width * height * 3];
打开16位的TGA
if (tga_header_img.PixelDepth == 16)*/
{
for (int j = 0, i = 0; i < width * height; i++)
{
{
b[i] = (ImageData[j] & 0x1F) << 3;
g[i] = ((ImageData[j + 1] & 0x03) << 6) + ((ImageData[j] & 0xE0) >> 2);
r[i] = ((ImageData[j + 1] & 0x7C)) << 1;
j = j + 2;
}
}
}
for (int k = 0, i = height - 1; i >= 0; i--)
{
for (int j = 0; j < width; j++)
{
RGB[k] = b[j + i * width];
RGB[k + 1] = g[j + i * width];
RGB[k + 2] = r[j + i * width];
k = k + 3;
}
}
for (int i = 0, j = 0; i < width*height * 3; i = i + 3, j++)
{
R[j] = RGB[i + 2];
G[j] = RGB[i + 1];
B[j] = RGB[i];
}
计算YUV分量
for (int i = 0, j = 0; i < width*height; i++, j++)
{
Y[j] = 0.2990*R[i] + 0.5870*G[i] + 0.1140*B[i];
U[j] = -0.1684*R[i] - 0.3316*G[i] + 0.5*B[i] + 128;
V[j] = 0.5*R[i] - 0.4187*G[i] - 0.0813*B[i] + 128;
}
对UV下采样
for (int k = 0, i = 0; i < height; i = i + 2)
{
for (int j = 0; j < width; j = j + 2)
{
u[k] = (U[width*i + j] + U[width*i + j + 1] + U[(i + 1)*width + j] + U[(i + 1)*width + j + 1]) / 4;
v[k] = (V[width*i + j] + V[width*i + j + 1] + V[(i + 1)*width + j] + V[(i + 1)*width + j + 1]) / 4;
k++;
}
}
YUV量化后码电平分配
for (int k = 0; k < width*height; k++)
{
if (Y[k] > 235)
Y[k] = 235;
if (Y[k] < 16)
Y[k] = 16;
}
for (int k = 0; k < width*height / 4; k++)
{
if (u[k] > 240)
u[k] = 240;
if (u[k] < 16)
u[k] = 16;
if (v[k] > 240)
v[k] = 240;
if (v[k] < 16)
v[k] = 16;
}
fwrite(Y, 1, width*height, YuvFile);
fwrite(u, 1, width*height / 4, YuvFile);
fwrite(v, 1, width*height / 4, YuvFile);
}
}
else
exit(0);
原TGA图
目测没有原图清楚