📄 yuv2rgb.c
字号:
/**************************************************************************
* *
* This software is an implementation of a part of one or more MPEG-4 Video tools as *
* specified in ISO/IEC 14496-2 standard. Those intending to use this *
* software module in hardware or software products are advised that its *
* use may infringe existing patents or copyrights, and any such use *
* would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies, will have no liability for use of *
* this software or modifications or derivatives thereof. *
* *
/***************************************************************************************
*This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* The GPL can be found at: http://www.gnu.org/copyleft/gpl.html *
* * *
* *
* *
* Authors: *
* Marc Dukette
* Pedro Mateu
**************************************************************************************/
#include <memory.h>
#include "portab.h"
#include "yuv2rgb.h"
//unsigned char LimitValues[768]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
//255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255};
#if defined(GAPI)||(defined(_USEVIDBUFF))
#ifdef MIPS
#ifdef HPC
#define DisplayWidth 800
#define DisplayHeight 480
#define VisibleWidth 800
#define VisibleHeight 480
#else
#define DisplayWidth 256
#define DisplayHeight 320
#define VisibleWidth 240
#define VisibleHeight 320
#endif
#else
#ifdef IPAQ
#define DisplayWidth 320
#define DisplayHeight 240
#define VisibleWidth 320
#define VisibleHeight 240
#else
#ifdef HPC
#define VisibleWidth 640
#define DisplayWidth 640
#define VisibleHeight 240
#define DisplayHeight 240
#else
#define VisibleWidth 240
#define DisplayWidth 240
#define VisibleHeight 320
#define DisplayHeight 320
#endif
#endif
#endif
#else
#ifdef HPC
#define VisibleWidth 640
#define DisplayWidth 640
#define VisibleHeight 240
#define DisplayHeight 240
#else
#define VisibleWidth 240
#define DisplayWidth 240
#define VisibleHeight 320
#define DisplayHeight 320
#endif
#endif
// 16 greyscale level - aero 1530,Monopaq
#ifdef _GREYSCALE_16
#define _S(a) (a)>255 ? 255 : a
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, int stride_dest, int Dither,int Brightness,uint8_t *puc_yp,uint8_t *puc_up,uint8_t *puc_vp, __int8 slowopt, int invert)
{
register int x,y;
unsigned char *pus_out;
register unsigned int l,l2; //luminance (brightness) value
register unsigned int quant_error_l;
register unsigned int mask=0;
if (stride_dest<0) stride_dest=0;
if (Dither==1){mask=0x0F;}
if ((height_y)>VisibleHeight) height_y=VisibleHeight;
if ((width_y)>VisibleWidth) width_y=VisibleWidth;
pus_out = (unsigned char *) puc_out;
quant_error_l=0;
for (y=0; y<height_y; y++)
{
for (x=0;x<width_y;x+=2)
{
l = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l&mask;
l2 = _S(puc_y[x+1]+quant_error_l+Brightness);
quant_error_l=l2&mask;
pus_out[0] = (unsigned char) (l&0xF0)|((l2&0xF0)>>4);
pus_out++;
}
puc_y += stride_y;
pus_out+=(stride_dest>>1);
}
}
void yuv2rgb_565Z(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, int nExtra, int Dither,int Brightness,uint8_t *puc_yp,uint8_t *puc_up,uint8_t *puc_vp, __int8 slowopt, int invert)
{
register int x,y;
unsigned int l,l2;
unsigned int quant_error_l;
register unsigned int mask=0;
unsigned char *pus_out;
int we;
if (nExtra<0) nExtra=0;
if (Dither==1){mask=0x0F;}
if ((height_y<<1)>VisibleHeight) height_y=VisibleHeight>>1;
if ((width_y<<1)>VisibleWidth) width_y=VisibleWidth>>1;
we=width_y+(nExtra>>1);
pus_out = (unsigned char *) puc_out;
quant_error_l=0;
for (y=0; y<height_y; y++)
{
for (x=0;x<width_y; x++)
{
l = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l&mask;
l2 = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l2&mask;
pus_out[0] = (unsigned char) (l&0xF0)|((l2&0xF0)>>4);
pus_out[we] = (unsigned char) (l2&0xF0)|((l&0xF0)>>4);
pus_out++;
}
pus_out+=we;
pus_out+=(nExtra>>1);
puc_y += stride_y;
}
}
void yuv2rgb_565R(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, int Extra, int Dither,int Brightness,uint8_t *puc_yp,uint8_t *puc_up,uint8_t *puc_vp, __int8 slowopt, int invert)
{
register int x,y;
unsigned char *pus_out;
register unsigned int l,l2;
register unsigned int mask=0;
register unsigned int quant_error_l;
if (Extra<0) Extra=0;
if (Dither==1){mask=0x0F;}
pus_out = (unsigned char *) puc_out;
quant_error_l=0;
for (y=0; y<(height_y>>1); y++)
{
pus_out = (unsigned char *) puc_out;
pus_out+=y;
for (x=width_y-1;x!=0;x--)
{
l = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l&mask;
l2 = _S(puc_y[x+stride_y]+quant_error_l+Brightness);
quant_error_l=l2&mask;
pus_out[0] = (unsigned char)(l&0xF0)|((l2&0xF0)>>4);
pus_out+=(height_y+Extra)>>1;
}
puc_y += (stride_y<<1);
}
}
void yuv2rgb_565RZ(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, int nExtra, int Dither,int Brightness,uint8_t *puc_yp,uint8_t *puc_up,uint8_t *puc_vp, __int8 slowopt, int invert)
{
register int x,y;
unsigned char *pus_out;
register unsigned int l;
register unsigned int quant_error_l;
register unsigned int mask=0;
if (nExtra<0) nExtra=0;
if (Dither==1){mask=0x0F;}
if ((width_y<<1)>VisibleHeight) width_y=VisibleHeight>>1;
if ((height_y<<1)>VisibleWidth) height_y=VisibleWidth>>1;
pus_out = (unsigned char *) puc_out;
quant_error_l=0;
for (y=0; y<height_y; y++)
{
pus_out = (unsigned char *) puc_out;
pus_out+=y;
for (x=width_y-1;x!=0;x--)
{
l= _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l&0x0F;
pus_out[0] = pus_out[(height_y+nExtra)] =(unsigned char)(l&0xF0)|((l&0xF0)>>4);
pus_out+=(height_y+nExtra)<<1;
}
puc_y += stride_y;
}
}
// 4 greyscale level- NINO300,...
#elif _GREYSCALE_4
#ifdef MIPS
#define _S(a) (a)>255 ? 255 : a
void yuv2rgb_565(
uint8_t *puc_y, int stride_y,
uint8_t *puc_out,
int width_y, int height_y,int stride_dest, int Dither)
{
//YUV2RGB MIPS ASM v1.1
//
//v1.1=>peque駉 aumento de velocidad
//SE => yuv2rgb para unidades de 4 grises (NINO 300...)
__asm ( //creamos nueva pila y salvamos registros
"addiu sp,sp,-36;"
"sw $18,20(sp);"
"sw $17,16(sp);"
"sw $16,12(sp);"
//calculamos stride_uv
"srl $14,$5,1;"
//cargamos todas las variables necesarias
"lw $18,56(sp);"//cargamos stride_dest
"lw $2,52(sp);"
// "lw $13,48(sp);"
// "lw $25,44(sp);"
"lbu $10,0($4);"
"srl $18,$18,2;");//para poder usar stride_dest como pixels
__asm(
//diferencias de strides
"sub $16,$5,$7;"
"srl $8,$7,1;"
"sub $14,$14,$8;"
//
"addi $11,$0,0;"
"addi $12,$0,0;"
"srl $17,$7,2;"
"add $17,$6,$17;"
//dividimos Y por 2 y comenzamos bucle
"srl $2,$2,1;"
"bucle_y:add $15,$4,$5;"
"srl $3,$7,2;"
//bucle x
"add $17,$17,$18;");//dst_buf2+
//luminancia 1
__asm( "bucle_x:add $10,$10,$11;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $11,$10,0x003F;"
"andi $24,$10,0x00C0;"
"lbu $10,1($4);"
//"srl $24,$9,6;"
//primer punto ,ahora procesamos segundo.
//luminancia 2
"add $10,$10,$11;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $11,$10,0x003F;"
"andi $9,$10,0x00C0;"
"srl $9,$9,2;"
"lbu $10,2($4);"
"or $24,$24,$9;"
);
//luminancia 3
__asm( "add $10,$10,$11;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $11,$10,0x003F;"
"andi $9,$10,0x00C0;"
"lbu $10,3($4);"
"srl $9,$9,4;"
"or $24,$24,$9;"
//primer punto ,ahora procesamos segundo.
//luminancia 4
//cargamos aqui para no tener interbloqueo
"add $10,$10,$11;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $11,$10,0x003F;"
"andi $9,$10,0x00C0;"
"lbu $10,0($15);"
"srl $9,$9,6;"
"or $24,$24,$9;"
//presentamos el punto
"sb $24,0($6);"
);
__asm( //f2-luminacia 1
"add $10,$10,$12;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $12,$10,0x003F;"
"andi $24,$10,0x00C0;"
//"srl $24,$9,6;"
"lbu $10,1($15);"//cargamos aqui para no tener interbloqueo
//primer punto ,ahora procesamos segundo.
//f2-luminacia 2
"add $10,$10,$12;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $12,$10,0x003F;"
"andi $9,$10,0x00C0;"
"srl $9,$9,2;"
"lbu $10,2($15);"
"or $24,$24,$9;"
//presentamos el punto
);
__asm( //f2-luminacia 3
"add $10,$10,$12;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $12,$10,0x003F;"
"andi $9,$10,0x00C0;"
"lbu $10,3($15);"//cargamos aqui para no tener interbloqueo
"srl $9,$9,4;"
"or $24,$24,$9;"
//primer punto ,ahora procesamos segundo.
//f2-luminacia 4
"add $10,$10,$12;"
"addi $10,$10,-16;"
"srl $9,$10,16;"
"srlv $10,$10,$9;"
"sll $9,$10,23;"
"sra $9,$9,31;"
"or $10,$10,$9;"
"andi $12,$10,0x003F;"
"andi $9,$10,0x00C0;"
"lbu $10,4($4);"
"srl $9,$9,6;"
"or $24,$24,$9;"
//presentamos el punto
"sb $24,0($17);" );
//incrementamos todos los punteros y volvemos al bucle
__asm(
"addi $4,$4,+4;"
"addi $15,$15,+4;"
"addi $3,$3,-1;"
"addi $6,$6,+1;"
"addi $17,$17,+1;"
"bgtz $3,bucle_x;"
"add $4,$15,$16;"
//cargamos aqui para no tener interbloqueo
"lbu $10,0($4);"
"add $6,$6,$18;"//dest+stride_dest
"add $6,$6,$18;"
"add $17,$17,$18;"
"addi $2,$2,-1;"
"srl $8,$7,2;"
"add $6,$6,$8;"
"add $17,$17,$8;"
"bgtz $2,bucle_y;"
//restauramos registros, la pila y finalizamos
"lw $16,12(sp);"
"lw $17,16(sp);"
"lw $18,20(sp);"
"addiu sp,sp,+36;"
);}
#else
#define _S(a) (a)>255 ? 255 : a
void yuv2rgb_565(uint8_t *puc_y, int stride_y,
uint8_t *puc_out, int width_y, int height_y,int stride_dest, int Dither,int Brightness)
{
register int x,y;
unsigned char *pus_out;
register unsigned int l,l2,l3,l4;
unsigned int quant_error_l;
register unsigned int mask=0;
if (stride_dest<0) stride_dest=0;
if (Dither==1){mask=0x3F;}
pus_out = (unsigned char *) puc_out;
quant_error_l=0;
for (y=0; y<height_y; y++)
{
for (x=0;x<width_y;x+=4)
{
l = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l&mask;
l2 = _S(puc_y[x+1]+quant_error_l+Brightness);
quant_error_l=l2&mask;
l3 = _S(puc_y[x+2]+quant_error_l+Brightness);
quant_error_l=l3&mask;
l4 = _S(puc_y[x+3]+quant_error_l+Brightness);
quant_error_l=l4&mask;
pus_out[0] = (unsigned char) (l&0xC0)|((l2&0xC0)>>2)|((l3&0xC0)>>4)|((l4&0xC0)>>6);
pus_out++;
}
puc_y += stride_y;
pus_out+=(stride_dest>>2);
}
}
#endif
void yuv2rgb_565Z(uint8_t *puc_y, int stride_y, uint8_t *puc_out, int width_y, int height_y, int nExtra, int Dither,int Brightness)
{
register int x,y;
unsigned int l,l2,l3,l4;
unsigned int quant_error_l;
unsigned char *pus_out;
register unsigned int mask=0;
int we;
if (nExtra<0) nExtra=0;
if (Dither==1){mask=0x3F;}
we=(width_y>>1)+(nExtra>>2);
pus_out = (unsigned char *) puc_out;
quant_error_l=0;
for (y=0; y<height_y; y++)
{
for (x=0;x<width_y;x+=2)
{
l = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l&mask;
l2 = _S(puc_y[x]+quant_error_l+Brightness);
quant_error_l=l2&mask;
l3 = _S(puc_y[x+1]+quant_error_l+Brightness);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -