📄 yuvtorgb.cpp
字号:
#include "YUVtoRGB.h"
#include <stdio.h>
static double* crv_tab;
static double* cbu_tab;
static double* cgu_tab;
static double* cgv_tab;
static unsigned char* ryv_tab;
static unsigned char* rbu_tab;
static unsigned char *clp;
static int* g_TransformTableX;
static int* g_TransformTableXUV;
static int* g_TransformTableY;
static int* g_TransformTableFillY;
extern int g_RectWidth;
extern int g_RectHeight;
static struct TNeoColorRGB {
unsigned char r, g, b, a;
} *neoColorRGB;
void InitConvertTable()
{
int i, j, ind;
clp = (unsigned char*)malloc(1024);
for (i=0; i<384; i++)
clp[i] =0;
ind=384;
for (i=0;i<256; i++)
clp[ind++]=i;
ind=640;
for (i=0;i<384;i++)
clp[ind++]=255;
// Generate crv
crv_tab = (double*)malloc(256*sizeof(double));
for (i = 0; i < 256; i++)
crv_tab[i] = 1.370705 * (i-128) + 384;
// Generate cgv
cgv_tab = (double*)malloc(256*sizeof(double));
for (i = 0; i < 256; i++)
cgv_tab[i] = 0.698001 * (i-128) - 384;
// Generate cgu
cgu_tab = (double*)malloc(256*sizeof(double));
for (i = 0; i < 256; i++)
cgu_tab[i] = 0.337633 * (i-128);
// Generate cbu
cbu_tab = (double*)malloc(256*sizeof(double));
for (i = 0; i < 256; i++)
cbu_tab[i] = 1.732446 * (i-128) + 384;
// Generate ryv
ryv_tab = (unsigned char*)malloc(256*256);
for (j = 0; j < 256; j++)
for (i = 0; i < 256; i++)
ryv_tab[i*256 + j] = clp[(int)(j + crv_tab[i])];
// Generate rbu
rbu_tab = (unsigned char*)malloc(256*256);
for (j = 0; j < 256; j++)
for (i = 0; i < 256; i++)
rbu_tab[i*256 + j] = clp[(int)(j + cbu_tab[i])];
neoColorRGB = (TNeoColorRGB*)malloc(64*64*64*4);
TNeoColorRGB* tNeoColorRGB = neoColorRGB;
unsigned char y1, u1, v1;
for (int v = 0; v < 64; v++)
for (int u = 0; u < 64; u++)
for (int y = 0; y < 64; y++)
{
y1 = y << 2;
u1 = u << 2;
v1 = v << 2;
tNeoColorRGB->r = rbu_tab[y1 + (u1 << 8)];
tNeoColorRGB->g = clp[(int)(y1 - cgv_tab[v1] - cgu_tab[u1])];
tNeoColorRGB->b = ryv_tab[y1 + (v1 << 8)];
tNeoColorRGB->a = 0xFF;
tNeoColorRGB++;
}
if (crv_tab)
{
free(crv_tab);
crv_tab = NULL;
}
if (cbu_tab)
{
free(cbu_tab);
cbu_tab = NULL;
}
/*
if (cgu_tab)
{
free(cgu_tab);
cgu_tab = NULL;
}
if (cgv_tab)
{
free(cgv_tab);
cgv_tab = NULL;
}
*/
}
void DestroyConvertTable()
{
if (clp)
{
free(clp);
clp = NULL;
}
if (ryv_tab)
{
free(ryv_tab);
ryv_tab = NULL;
}
if (rbu_tab)
{
free(rbu_tab);
rbu_tab = NULL;
}
if (crv_tab)
{
free(crv_tab);
crv_tab = NULL;
}
if (cbu_tab)
{
free(cbu_tab);
cbu_tab = NULL;
}
if (cgu_tab)
{
free(cgu_tab);
cgu_tab = NULL;
}
if (cgv_tab)
{
free(cgv_tab);
cgv_tab = NULL;
}
if (neoColorRGB)
{
free(neoColorRGB);
neoColorRGB = NULL;
}
}
void ConvertYUV2BGRFast(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
const int width, int height, const int realwidth)
{
register unsigned char *py1,*py2;
register int *tNeoColorRGB;
register int *d1, *d2;
register int *_neoColorRGB = (int*)neoColorRGB;
int j;
// if (realwidth > 320)
// realwidth = 320;
const int bytetonextrow_src0 = width+width-realwidth;
const int bytetonextrow_src1 = (width-realwidth) >> 1;
const int bytetonextrow_dst = 640-realwidth;
if (width == 0)
return;
py1=src0;
py2=py1+width;
d1=(int*)dst_ori + (320 * ((240-height) >> 1)) + ((320-realwidth) >> 1);
d2=d1+320;
if (height > 240)
height = 240;
for (j = height; j > 0; j -= 2) {
for (register int i = realwidth; i > 0; i -= 2) {
tNeoColorRGB = _neoColorRGB + (((*src1) >> 2) << 6) + (((*src2) >> 2) << 12);
src1++;
src2++;
*d1 = *(tNeoColorRGB + (*py1 >> 2));
*d2 = *(tNeoColorRGB + (*py2 >> 2));
d1[1] = *(tNeoColorRGB + (py1[1] >> 2));
d2[1] = *(tNeoColorRGB + (py2[1] >> 2));
py1 += 2;
py2 += 2;
d1 += 2;
d2 += 2;
}
d1 += bytetonextrow_dst;
d2 += bytetonextrow_dst;
py1 += bytetonextrow_src0;
py2 += bytetonextrow_src0;
src1+= bytetonextrow_src1;
src2+= bytetonextrow_src1;
}
}
void CreateTransformTable(const int /*width*/, int height, int realwidth, int newrealwidth, int newheight)
{
int tnewheight = newheight;
int tnewrealwidth = newrealwidth;
if (newrealwidth * height / newheight < realwidth)
newheight = height * newrealwidth / realwidth;
else
newrealwidth = realwidth * newheight / height;
const double incy_x = (realwidth + 0.0) / newrealwidth;
const double incy_y = (newheight + 0.0) / height;
const double incuv_x = incy_x / 2;
DestroyTransformTable();
g_TransformTableX = (int*)malloc(newrealwidth*sizeof(int));
for (int i = 0; i < newrealwidth; i++)
{
g_TransformTableX[newrealwidth-i-1] = (int)(incy_x*i);
}
g_TransformTableXUV = (int*)malloc(newrealwidth*sizeof(int));
for (int i = 0; i < newrealwidth; i++)
{
g_TransformTableXUV[(newrealwidth)-i-1] = (int)(incuv_x*i);
}
if (newrealwidth > realwidth)
{
g_TransformTableFillY = (int*)malloc(newheight*sizeof(int));
for (int i = 0; i < newheight; i++)
g_TransformTableFillY[i] = 0;
g_TransformTableY = (int*)malloc(height*sizeof(int));
for (int i = 0; i < height; i++)
{
g_TransformTableY[height-i-1] = tnewrealwidth*(int)(incy_y*i);
g_TransformTableFillY[(int)(incy_y*i)] = 1;
}
}
else
{
g_TransformTableFillY = (int*)malloc(height*sizeof(int));
for (int i = 0; i < height; i++)
g_TransformTableFillY[i] = 0;
g_TransformTableY = (int*)malloc(height*sizeof(int));
for (int i = 0; i < height; i++)
{
g_TransformTableY[height-i-1] = tnewrealwidth*(int)(incy_y*i);
}
g_TransformTableFillY[height-1] = 1;
for (int i = 1; i < height; i++)
{
if (g_TransformTableY[height-i-1] != g_TransformTableY[height-i-2])
g_TransformTableFillY[height-i-1] = 1;
}
}
}
void DestroyTransformTable()
{
if (g_TransformTableX)
{
free(g_TransformTableX);
g_TransformTableX = NULL;
}
if (g_TransformTableXUV)
{
free(g_TransformTableXUV);
g_TransformTableXUV = NULL;
}
if (g_TransformTableY)
{
free(g_TransformTableY);
g_TransformTableY = NULL;
}
if (g_TransformTableFillY)
{
free(g_TransformTableFillY);
g_TransformTableFillY = NULL;
}
}
void ConvertYUV2BGRNeoFast(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
const int width, int height, int realwidth, int newrealwidth, int newheight)
{
if (realwidth % 2 == 1)
realwidth--;
if (width == 0)
return;
int tnewrealwidth = newrealwidth;
int tnewheight = newheight;
if (newrealwidth * height / newheight < realwidth)
tnewheight = height * newrealwidth / realwidth;
else
tnewrealwidth = realwidth * newheight / height;
if (!g_TransformTableX)
CreateTransformTable(width, height, realwidth, newrealwidth, newheight);
if (tnewrealwidth > realwidth)
ConvertYUV2BGRNeoFastScaleUp(src0, src1, src2, dst_ori, width, height, realwidth, newrealwidth, newheight);
else
ConvertYUV2BGRNeoFastScaleDown(src0, src1, src2, dst_ori, width, height, realwidth, newrealwidth, newheight);
}
void ConvertYUV2BGRNeoFastScaleUp(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
const int width, int height, int realwidth, const int newrealwidth, int newheight)
{
register unsigned char *py1,*py2;
register int *tNeoColorRGB;
register int *d1, *d2;
register int *_neoColorRGB = (int*)neoColorRGB;
int j;
register unsigned char* src1i = src1;
register unsigned char* src2i = src2;
unsigned char* dst_ori_i = dst_ori;
int tnewrealwidth = newrealwidth;
if (newrealwidth * height / newheight < realwidth)
{
dst_ori += (((((newheight-(height * newrealwidth / realwidth)) >> 1) * newrealwidth)) << 2);
newheight = height * newrealwidth / realwidth;
dst_ori_i = dst_ori;
}
else
{
dst_ori += ((newrealwidth - (realwidth * newheight / height)) >> 1) << 2;
tnewrealwidth = realwidth * newheight / height;
}
if (tnewrealwidth % 2 == 1)
tnewrealwidth--;
if (tnewrealwidth % 4 != 0)
tnewrealwidth -= 2;
if (tnewrealwidth < 0)
tnewrealwidth = 0;
if (width == 0)
return;
for (j = height-1; j >= 0; j -= 2) {
d1 = (int*)dst_ori + g_TransformTableY[j];
d2 = (int*)dst_ori + g_TransformTableY[j-1];
py1 = src0 + (height-j-1) * width;
py2 = src0 + (height-j ) * width;
register int diff = ((height-j-1) * width) >> 2;
src1i = src1 + diff;
src2i = src2 + diff;
for (register int i = tnewrealwidth-1; i >= 0; i -= 4) {
tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);
*d1 = *(tNeoColorRGB + (py1[g_TransformTableX[i]] >> 2));
*d2 = *(tNeoColorRGB + (py2[g_TransformTableX[i]] >> 2));
d1[1] = *(tNeoColorRGB + (py1[g_TransformTableX[i-1]] >> 2));
d2[1] = *(tNeoColorRGB + (py2[g_TransformTableX[i-1]] >> 2));
d1[2] = *(tNeoColorRGB + (py1[g_TransformTableX[i-2]] >> 2));
d2[2] = *(tNeoColorRGB + (py2[g_TransformTableX[i-2]] >> 2));
d1[3] = *(tNeoColorRGB + (py1[g_TransformTableX[i-3]] >> 2));
d2[3] = *(tNeoColorRGB + (py2[g_TransformTableX[i-3]] >> 2));
d1 += 4;
d2 += 4;
}
}
for (register int i = 0; i < newheight; i++)
{
if (g_TransformTableFillY[i] == 0)
memcpy((int*)dst_ori_i + (i)*newrealwidth, (int*)dst_ori_i + (i-1)*newrealwidth, newrealwidth << 2);
}
}
void ConvertYUV2BGRNeoFastScaleDown(unsigned char *src0, register unsigned char *src1, register unsigned char *src2,unsigned char *dst_ori,
const int width, int height, int realwidth, const int newrealwidth, int newheight)
{
register unsigned char *py1,*py2;
register int *tNeoColorRGB;
register int *d1, *d2;
register int *_neoColorRGB = (int*)neoColorRGB;
int j;
register unsigned char* src1i = src1;
register unsigned char* src2i = src2;
int tnewrealwidth = newrealwidth;
//if (newrealwidth * height / newheight < realwidth)
// newheight = height * newrealwidth / realwidth;
//else
// tnewrealwidth = realwidth * newheight / height;
if (newrealwidth * height / newheight < realwidth)
{
dst_ori += (((((newheight-(height * newrealwidth / realwidth)) >> 1) * newrealwidth)) << 2);
newheight = height * newrealwidth / realwidth;
}
else
{
dst_ori += ((newrealwidth - (realwidth * newheight / height)) >> 1) << 2;
tnewrealwidth = realwidth * newheight / height;
}
if (tnewrealwidth % 2 == 1)
tnewrealwidth--;
if (width == 0)
return;
for (j = height-1; j >= 0; j -= 2) {
register int diff = ((height-j-1) * width) >> 2;
src1i = src1 + diff;
src2i = src2 + diff;
if (g_TransformTableFillY[j] && g_TransformTableFillY[j-1])
{
d1 = (int*)dst_ori + g_TransformTableY[j];
d2 = (int*)dst_ori + g_TransformTableY[j-1];
py1 = src0 + (height-j-1) * width;
py2 = src0 + (height-j ) * width;
for (register int i = tnewrealwidth-1; i >= 0; i -= 2)
{
tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);
*d1 = *(tNeoColorRGB + (py1[g_TransformTableX[i]] >> 2));
*d2 = *(tNeoColorRGB + (py2[g_TransformTableX[i]] >> 2));
d1[1] = *(tNeoColorRGB + (py1[g_TransformTableX[i-1]] >> 2));
d2[1] = *(tNeoColorRGB + (py2[g_TransformTableX[i-1]] >> 2));
d1 += 2;
d2 += 2;
}
}
else if (g_TransformTableFillY[j])
{
d1 = (int*)dst_ori + g_TransformTableY[j];
py1 = src0 + (height-j-1) * width;
for (register int i = tnewrealwidth-1; i >= 0; i -= 2)
{
tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);
*d1 = *(tNeoColorRGB + (py1[g_TransformTableX[i]] >> 2));
d1[1] = *(tNeoColorRGB + (py1[g_TransformTableX[i-1]] >> 2));
d1 += 2;
}
}
else if (g_TransformTableFillY[j-1])
{
d2 = (int*)dst_ori + g_TransformTableY[j-1];
py2 = src0 + (height-j ) * width;
for (register int i = tnewrealwidth-1; i >= 0; i -= 2)
{
tNeoColorRGB = _neoColorRGB + (((src1i[g_TransformTableXUV[i]]) >> 2) << 6) + (((src2i[g_TransformTableXUV[i]]) >> 2) << 12);
*d2 = *(tNeoColorRGB + (py2[g_TransformTableX[i]] >> 2));
d2[1] = *(tNeoColorRGB + (py2[g_TransformTableX[i-1]] >> 2));
d2 += 2;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -