rgb2yuv.cpp


 /***************************************************************************
                          yv.cpp  -  description
                             -------------------

 Convert a RGB triplet to its YUV conterpart

    begin                : Wed Aug 12 2003
    copyright            : (C) 2003 by mean
    email                : fixounet@free.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <math.h>

#include "ADM_library/default.h"


#include "colorspace.h"
#include <ADM_assert.h>

/**
 This is unoptimized because seldom called
*/
uint8_t COL_RgbToYuv(uint8_t R,uint8_t G,uint8_t B, uint8_t *y,int8_t *u,int8_t *v)
{

 float rr=R,bb=B,gg=G;
 float yy,uu,vv;

 yy=0.299*rr+   0.587*gg+  0.114*bb;
 uu=-0.169*rr+  -0.331*gg+   0.5*bb;
 vv=0.5*rr+   -0.419*gg+  -0.081*bb;


 if(uu>127) uu=127;
 if(uu<-127) uu=-127;
 *u=(int8_t)floor(uu);

 if(vv>127) vv=127;
 if(vv<-127) vv=-127;
 *v=(int8_t)floor(vv);

 if(yy>255) yy=255;
 if(yy<0) yy=0;
 *y=(uint8_t)floor(yy);

 return 1;

}
static inline uint8_t PixelClip(int16_t in)
{
    if (in > 255)
 in = 255;
   if(in<0)
    in=0;
    return (uint8_t) in;
};

         
static inline unsigned char ScaledPixelClip(long  i)
{
    return PixelClip(((i +32768) >> 16)); //  + 32768
};

//0.299 0.587 0.114
const long int cyb = 6416; //int(0.114*219*65536/255+0.5);
const long int cyg = 33038; //int(0.587*219*65536/255+0.5);
const long int cyr = 16828; //int(0.299*219*65536/255+0.5);

uint8_t COL_RawRGB32toYV12(uint8_t *data1,uint8_t *data2, uint8_t *oy,uint8_t *oy2,
    uint8_t *u, uint8_t *v,uint32_t lineSize,uint32_t height,uint32_t stride)
{


long int y1,y2;
long int y3,y4;
long int scaled_y,b_y;
long int scaled_y2,b_y2;
long int r_y,r_y2; 

uint8_t *org1,*org2;
/*
0 2 1
2 6 0
1 5 3
3 7 1
*/
#define B0 2
#define R0 0
#define M0 1

#define M1 (M0+4)
#define B1 (B0+4)
#define R1 (R0+4)
#define LEFT 0x108000

// printf("w %d h %d stride %d/n",lineSize,height,stride);
 org1=data1;
 org2=data2;
 
 long int alpha,beta,gamma;
 
    for(uint32_t yy=0;yy<(height>>1);yy++)
    {
     data1=org1;
 data2=org2;
      for (uint32_t x=0;x<(lineSize>>1);x++)
      {
     
#define MK1(source,out,row ) /
       alpha=source[B##row]; /
       alpha*=cyb; /
       beta=source[M##row]; /
       beta*=cyg; /
       gamma=source[R##row]; /
       gamma*=cyr;        /
       out=(gamma+alpha+beta+LEFT)>>16;
     
       
       //y1 = (cyb*(long int)data1[B0] + cyg*(long int)data1[M0] + cyr*(long int)data1[R0] +LEFT) >> 16;
        MK1(data1,y1,0);
        oy[0] = y1;
        //y2 = (cyb*(long int)data1[B1] + cyg*(long int)data1[M1] + cyr*(long int)data1[R1] +LEFT) >> 16;
 MK1(data1,y2,1);
        oy[1] = y2;
 
 //y3 = (cyb*(long int)data2[B0] + cyg*(long int)data2[M0] + cyr*(long int)data2[R0] +LEFT) >> 16;
 MK1(data2,y3,0);
        oy2[0] = y3;
 
        //y4 = (cyb*(long int)data2[B1] + cyg*(long int)data2[M1] + cyr*(long int)data2[R1] +LEFT) >> 16;
 MK1(data2,y4,1);
        oy2[1] = y4;


        scaled_y = (y1+y2 - 32) * 38155;
 scaled_y2 = (y3+y4 - 32) * 38155;
 
        b_y = ((data1[B0]+data1[B1]) << 15) - scaled_y;
 b_y2 = ((data2[B0]+data2[B1]) << 15) - scaled_y2;
 
 b_y=(b_y+b_y2)/2;
 
        u[0] = ScaledPixelClip((b_y >> 10)*int(1/2.018*1024+0.5) + 0x800000);  // u * int(1/2.018*1024+0.5)
       
 r_y = ((data1[R0]+data1[R1]) << 15) - scaled_y;
 r_y2 = ((data2[R0]+data2[R1]) << 15) - scaled_y2;
 r_y=(r_y+r_y2)/2;
 
        v[0] = ScaledPixelClip((r_y >> 10)* int(1/1.596*1024+0.5) + 0x800000);  // v* int(1/1.596*1024+0.5)
 
 //u[0]=128;
 //v[0]=128;
       
 oy+=2;
 oy2+=2;
 u++;
 v++;
 data1+=8;
 data2+=8;
      }
      org2+=2*stride;
       org1+=2*stride;
 oy+=lineSize;
 oy2+=lineSize; 
     }
     
  return 1;
}
uint8_t COL_YuvToRgb( uint8_t y,int8_t u,int8_t v,uint8_t *r,uint8_t *g,uint8_t *b)
{

 float rr,bb,gg;
 float yy=y,uu=u,vv=v;

 rr= yy+     1.402*vv;
 gg= yy+  -0.344*uu+   -0.714*vv;
 bb= yy+  1.772*uu     ;

 #define CLIP(x) if(x>255) x=255; else if (x<0) x=0;x=x+0.49;
 #define CVT(x,y) CLIP(x);*y=(uint8_t)floor(x);

 CVT(rr,r);
 CVT(gg,g);
 CVT(bb,b);

 return 1;

}

【来源】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值