#include <stdio.h>
#include <cstring>
int readFile(unsigned char* buf, int len,char*name){
FILE* fp = NULL;
fp = fopen(name, "rb+");
if (fp != NULL) {
fread((char*)buf, 1, len, fp);
fclose(fp);
}
}
int writeFile(unsigned char* buf, int len,char*name){
FILE* fp = NULL;
fp = fopen(name, "wb+");
if (fp != NULL) {
fwrite((char*)buf, 1, len, fp);
fclose(fp);
}
}
void RGB888_to_YUV422(int width, int height, unsigned char *rgb_buffer, unsigned char *yuv_buffer) {
int y0, u, y1, v;
for (int i = 0; i < width * height * 3; i += 6) {
// 获取RGB分量
unsigned char r0 = rgb_buffer[i];
unsigned char g0 = rgb_buffer[i + 1];
unsigned char b0 = rgb_buffer[i + 2];
unsigned char r1 = rgb_buffer[i + 3];
unsigned char g1 = rgb_buffer[i + 4];
unsigned char b1 = rgb_buffer[i + 5];
// 转换第一个像素的Y分量
y0 = (77 * r0 + 150 * g0 + 29 * b0) >> 8;
// 转换U分量
u = ((-43 * r0 - 85 * g0 + 128 * b0) >> 8) + 128;
// 转换第二个像素的Y分量
y1 = (77 * r1 + 150 * g1 + 29 * b1) >> 8;
// 转换V分量
v = ((128 * r0 - 107 * g0 - 21 * b0) >> 8) + 128;
// 将YUV分量写入缓冲区
yuv_buffer[i / 3 * 2] = u;
yuv_buffer[i / 3 * 2 + 1] = y0;
yuv_buffer[i / 3 * 2 + 2] = v;
yuv_buffer[i / 3 * 2 + 3] = y1;
}
}
int main(void){
int width = 1706;
int heigh = 1280;
//===========1706 *1279 --> 1706 *1280 ===============
unsigned char *rgbBuf = new unsigned char[1760*1280*3];
unsigned char *yuvBuf = new unsigned char[1760*1280*2];
readFile(rgbBuf,width * 1279 *3,"20240308094827.rgb");
memcpy(rgbBuf+width * 1279 *3,rgbBuf+width * 1278 *3,width*3);
writeFile(rgbBuf,width * heigh *3,"1706x1280.rgb");
//=============================================================
//===========1706 *1280 --> 1760 *1280 ===============
unsigned char *dstBuf = new unsigned char[1760*1280*3];
int dstH = 0;
int dstW = 0;
for(int h=0;h<1280;h++){
for(int w=0;w<1706;w++){
dstBuf[((dstW + dstH*1760)*3)]= rgbBuf[((w+h*width)*3)] ;//r
dstBuf[((dstW + dstH*1760)*3)+1] = rgbBuf[((w+h*width)*3)+1] ;//g
dstBuf[((dstW + dstH*1760)*3)+2] = rgbBuf[((w+h*width)*3)+2] ;//b
dstW++;
if((dstW % 32 == 0) && dstW < 1760){
dstBuf[((dstW + dstH*1760)*3)]= rgbBuf[((w+h*width)*3)] ;//r
dstBuf[((dstW + dstH*1760)*3)+1] = rgbBuf[((w+h*width)*3)+1] ;//g
dstBuf[((dstW + dstH*1760)*3)+2] = rgbBuf[((w+h*width)*3)+2] ;//b
dstW++;
}
}
dstH++;
dstW= 0;
}
writeFile(dstBuf,1760*1280*3,"1760x1280.rgb");
memcpy(rgbBuf,dstBuf,1760*1280*3);
dstW = 0;
RGB888_to_YUV422(1760, 1280, dstBuf, yuvBuf);
writeFile(yuvBuf,1760 *1280 *2,"1760x1280.uyuv");
//===============1760*1280 UYUV --> 1280*720 UYUV=============
dstH = 0;
unsigned char u,y,v,r,g,b;
//高取一半数据
for(int h=0;h<1280;h+=2){
//由于y和y1共用一组uv数据,所以宽为2个y数据为一组像素 ,1760/2 ==880
for(int w=0;w<880;w++){//880 //1280
//判断宽数据比例11取8,进行数据填充
if(w % 11 == 0 || w % 11 == 2 || w % 11 == 3 || w % 11 == 4
|| w % 11 == 6 || w % 11 == 7 || w % 11 == 8 || w % 11 == 10
){
dstBuf[(dstW + dstH*640)*4+0] = yuvBuf[(w + h*880)*4+0];//u数据填充
dstBuf[(dstW + dstH*640)*4+1] = yuvBuf[(w + h*880)*4+1];//y数据填充
dstBuf[(dstW + dstH*640)*4+2] = yuvBuf[(w + h*880)*4+2];//v数据填充
dstBuf[(dstW + dstH*640)*4+3] = yuvBuf[(w + h*880)*4+3];//y1数据填充
dstW++;
}
}
dstH++;
dstW= 0;
//判断高数据比例16比9 ,额外补多一行进行数据填充
if(h % 16 == 14){
for(int w=0;w<880;w++){
//判断宽数据比例11取8,进行数据填充
if(w % 11 == 0 || w % 11 == 2 || w % 11 == 3 || w % 11 == 4
|| w % 11 == 6 || w % 11 == 7 || w % 11 == 8 || w % 11 == 10
){
dstBuf[(dstW + dstH*640)*4+0] = yuvBuf[(w + h*880)*4+0];//u数据填充
dstBuf[(dstW + dstH*640)*4+1] = yuvBuf[(w + h*880)*4+1];//y数据填充
dstBuf[(dstW + dstH*640)*4+2] = yuvBuf[(w + h*880)*4+2];//v数据填充
dstBuf[(dstW + dstH*640)*4+3] = yuvBuf[(w + h*880)*4+3];//y1数据填充
dstW++;
}
}
dstH++;
}
dstW= 0;
}
writeFile(dstBuf,1280 *720 *2,"1280x720.uyuv");
}