📄 yuv2rgb.c
字号:
#include <memory.h>
#include "portab.h"
#include "yuv2rgb.h"
/**
*
**/
void (*convert_yuv)(unsigned char *puc_y, int stride_y,
unsigned char *puc_u, unsigned char *puc_v, int stride_uv,
unsigned char *bmp, int width_y, int height_y,
unsigned int stride_out);
/**
*
**/
#define _S(a) (a)>255 ? 255 : (a)<0 ? 0 : (a)
#define _R(y,u,v) (0x2568*(y) + 0x3343*(u)) /0x2000
#define _G(y,u,v) (0x2568*(y) - 0x0c92*(v) - 0x1a1e*(u)) /0x2000
#define _B(y,u,v) (0x2568*(y) + 0x40cf*(v)) /0x2000
struct lookuptable
{
int32_t m_plY[256];
int32_t m_plRV[256];
int32_t m_plGV[256];
int32_t m_plGU[256];
int32_t m_plBU[256];
};
static struct lookuptable lut;
void init_yuv2rgb()
{
int i;
for(i=0; i<256; i++)
{
if(i>=16)
if(i>240)
lut.m_plY[i]=lut.m_plY[240];
else
lut.m_plY[i]=298*(i-16);
else
lut.m_plY[i]=0;
if((i>=16) && (i<=240))
{
lut.m_plRV[i]=408*(i-128);
lut.m_plGV[i]=-208*(i-128);
lut.m_plGU[i]=-100*(i-128);
lut.m_plBU[i]=517*(i-128);
}
else if(i<16)
{
lut.m_plRV[i]=408*(16-128);
lut.m_plGV[i]=-208*(16-128);
lut.m_plGU[i]=-100*(16-128);
lut.m_plBU[i]=517*(16-128);
}
else
{
lut.m_plRV[i]=lut.m_plRV[240];
lut.m_plGV[i]=lut.m_plGV[240];
lut.m_plGU[i]=lut.m_plGU[240];
lut.m_plBU[i]=lut.m_plBU[240];
}
}
}
void yuv2rgb_32(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int _stride_out)
{
int x, y;
int stride_diff = 4 * (_stride_out - width_y);
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
for (y=0; y<height_y; y++)
{
for (x=0; x<width_y; x++)
{
signed int _r,_g,_b;
signed int r, g, b;
signed int y, u, v;
y = puc_y[x] - 16;
u = puc_u[x>>1] - 128;
v = puc_v[x>>1] - 128;
_r = _R(y,u,v);
_g = _G(y,u,v);
_b = _B(y,u,v);
r = _S(_r);
g = _S(_g);
b = _S(_b);
puc_out[0] = r;
puc_out[1] = g;
puc_out[2] = b;
puc_out[3] = 0;
puc_out+=4;
}
puc_y += stride_y;
if (y%2) {
puc_u += stride_uv;
puc_v += stride_uv;
}
puc_out += stride_diff;
}
}
void yuv2rgb_24(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int _stride_out)
{
int x, y;
int stride_diff = 6*_stride_out - 3*width_y;
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
for (y=0; y<height_y; y+=2)
{
uint8_t* pY=puc_y;
uint8_t* pY1=puc_y+stride_y;
uint8_t* pU=puc_u;
uint8_t* pV=puc_v;
uint8_t* pOut2=puc_out+3*_stride_out;
for (x=0; x<width_y; x+=2)
{
int R, G, B;
int Y;
unsigned int tmp;
R=lut.m_plRV[*pU];
G=lut.m_plGV[*pU];
pU++;
G+=lut.m_plGU[*pV];
B=lut.m_plBU[*pV];
pV++;
#define PUT_COMPONENT(p,v,i) \
tmp=(unsigned int)(v); \
if(tmp < 0x10000) \
p[i]=tmp>>8; \
else \
p[i]=(tmp >> 24) ^ 0xff;
Y=lut.m_plY[*pY];
pY++;
PUT_COMPONENT(puc_out, R+Y, 0);
PUT_COMPONENT(puc_out, G+Y, 1);
PUT_COMPONENT(puc_out, B+Y, 2);
Y=lut.m_plY[*pY];
pY++;
PUT_COMPONENT(puc_out, R+Y, 3);
PUT_COMPONENT(puc_out, G+Y, 4);
PUT_COMPONENT(puc_out, B+Y, 5);
Y=lut.m_plY[*pY1];
pY1++;
PUT_COMPONENT(pOut2, R+Y, 0);
PUT_COMPONENT(pOut2, G+Y, 1);
PUT_COMPONENT(pOut2, B+Y, 2);
Y=lut.m_plY[*pY1];
pY1++;
PUT_COMPONENT(pOut2, R+Y, 3);
PUT_COMPONENT(pOut2, G+Y, 4);
PUT_COMPONENT(pOut2, B+Y, 5);
puc_out+=6;
pOut2+=6;
}
puc_y += 2*stride_y;
puc_u += stride_uv;
puc_v += stride_uv;
puc_out += stride_diff;
}
}
/***/
#define _S(a) (a)>255 ? 255 : (a)<0 ? 0 : (a)
#define _R(y,u,v) (0x2568*(y) + 0x3343*(u)) /0x2000
#define _G(y,u,v) (0x2568*(y) - 0x0c92*(v) - 0x1a1e*(u)) /0x2000
#define _B(y,u,v) (0x2568*(y) + 0x40cf*(v)) /0x2000
#define _mR 0x7c00
#define _mG 0x03e0
#define _mB 0x001f
#define _Ps555(r,g,b) (((r) << 7) & _mR) | (((g) << 2) & _mG) | (((b) >> 3) & _mB)
#define _Ps565(r,g,b) ( ((r & 0xF8) >> 3) | (((g & 0xF8) << 3)) | (((b & 0xF8) << 8)) )
void yuv2rgb_555(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int _stride_out)
{
int x, y;
unsigned short *pus_out;
int stride_diff = _stride_out - width_y;
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
pus_out = (unsigned short *) puc_out;
for (y=0; y<height_y; y++)
{
for (x=0; x<width_y; x++)
{
signed int _r,_g,_b;
signed int r, g, b;
signed int y, u, v;
y = puc_y[x] - 16;
u = puc_u[x>>1] - 128;
v = puc_v[x>>1] - 128;
_r = _R(y,u,v);
_g = _G(y,u,v);
_b = _B(y,u,v);
r = _S(_r);
g = _S(_g);
b = _S(_b);
pus_out[0] = _Ps555(b,g,r);
pus_out++;
}
puc_y += stride_y;
if (y%2) {
puc_u += stride_uv;
puc_v += stride_uv;
}
pus_out += stride_diff;
}
}
/***/
void yuv2rgb_565(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int _stride_out)
{
int x, y;
unsigned short *pus_out;
int stride_diff = _stride_out - width_y;
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
pus_out = (unsigned short *) puc_out;
for (y=0; y<height_y; y++)
{
for (x=0; x<width_y; x++)
{
signed int _r,_g,_b;
signed int r, g, b;
signed int y, u, v;
y = puc_y[x] - 16;
u = puc_u[x>>1] - 128;
v = puc_v[x>>1] - 128;
_r = _R(y,u,v);
_g = _G(y,u,v);
_b = _B(y,u,v);
r = _S(_r);
g = _S(_g);
b = _S(_b);
pus_out[0] = (unsigned short) _Ps565(r,g,b);
pus_out++;
}
puc_y += stride_y;
if (y%2) {
puc_u += stride_uv;
puc_v += stride_uv;
}
pus_out += stride_diff;
}
}
void yuy2_out(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int stride_out)
{
int y;
uint8_t* puc_out2;
unsigned int stride_diff = 4 * stride_out - 2 * width_y;
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
puc_out2 = puc_out + 2 * stride_out;
for (y=height_y/2; y; y--) {
register uint8_t *py, *py2, *pu, *pv;
register int x;
uint32_t tmp;
py = puc_y;
py2 = puc_y + stride_y;
pu = puc_u;
pv = puc_v;
for (x=width_y/2; x; x--) {
tmp = *(py++);
tmp |= *(pu++) << 8;
tmp |= *(py++) << 16;
tmp |= *(pv++) << 24;
*(uint32_t*)puc_out=tmp;
puc_out += 4;
tmp &= 0xFF00FF00;
tmp |= *(py2++);
tmp |= *(py2++) << 16;
*(uint32_t*)puc_out2=tmp;
puc_out2 += 4;
}
puc_y += 2*stride_y;
puc_u += stride_uv;
puc_v += stride_uv;
puc_out += stride_diff;
puc_out2 += stride_diff;
}
}
void uyvy_out(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int stride_out)
{
int y;
uint8_t* puc_out2;
unsigned int stride_diff = 4 * stride_out - 2 * width_y;
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
puc_out2 = puc_out + 2 * stride_out;
for (y=height_y/2; y; y--) {
register uint8_t *py, *py2, *pu, *pv;
register int x;
uint32_t tmp;
py = puc_y;
py2 = puc_y + stride_y;
pu = puc_u;
pv = puc_v;
for (x=width_y/2; x; x--) {
tmp = *(pu++);
tmp |= *(py++) << 8;
tmp |= *(pv++) << 16;
tmp |= *(py++) << 24;
*(uint32_t*)puc_out=tmp;
puc_out += 4;
tmp &= 0x00FF00FF;
tmp |= *(py2++) << 8;
tmp |= *(py2++) << 24;
*(uint32_t*)puc_out2=tmp;
puc_out2 += 4;
}
puc_y += 2*stride_y;
puc_u += stride_uv;
puc_v += stride_uv;
puc_out += stride_diff;
puc_out2 += stride_diff;
}
}
void yuv12_out(uint8_t *puc_y, int stride_y,
uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
uint8_t *puc_out, int width_y, int height_y,
unsigned int stride_out)
{
int i;
unsigned char * pauc_out[3];
if (height_y < 0) {
height_y = -height_y;
puc_y += (height_y - 1) * stride_y ;
puc_u += (height_y/2 - 1) * stride_uv;
puc_v += (height_y/2 - 1) * stride_uv;
stride_y = -stride_y;
stride_uv = -stride_uv;
}
pauc_out[0] = puc_out;
pauc_out[1] = puc_out + stride_out * height_y;
pauc_out[2] = puc_out + stride_out * height_y * 5 / 4;
for (i=0; i<height_y; i++) {
memcpy(pauc_out[0], puc_y, width_y);
pauc_out[0] += stride_out;
puc_y += stride_y;
}
for (i=0; i<height_y/2; i++) {
memcpy(pauc_out[2], puc_u, width_y/2);
memcpy(pauc_out[1], puc_v, width_y/2);
pauc_out[1] += stride_out/2;
pauc_out[2] += stride_out/2;
puc_u += stride_uv;
puc_v += stride_uv;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -