1 
2 /*!
3  *************************************************************************************
4  * \file cconv_yuv2rgb.c
5  *
6  * \brief
7  *    YUV to RGB color conversion
8  *
9  * \author
10  *    Main contributors (see contributors.h for copyright, address and affiliation details)
11  *     - Woo-Shik Kim                    <wooshik.kim@usc.edu>
12  *************************************************************************************
13  */
14 #include "contributors.h"
15 #include "global.h"
16 #include "memalloc.h"
17 #include "img_distortion.h"
18 
19 #define YUV2RGB_YOFFSET
20 
21 //YUV to RGB conversion
22 #ifdef YUV2RGB_YOFFSET
23 #define OFFSET_Y 16
24 static const float K0 = 1.164f;
25 static const float K1 = 1.596f;
26 static const float K2 = 0.391f;
27 static const float K3 = 0.813f;
28 static const float K4 = 2.018f;
29 #else
30 static const float K0 = 1.000f;
31 static const float K1 = 1.402f;
32 static const float K2 = 0.34414f;
33 static const float K3 = 0.71414f;
34 static const float K4 = 1.772f;
35 #endif
36 
create_RGB_memory(VideoParameters * p_Vid)37 int create_RGB_memory(VideoParameters *p_Vid)
38 {
39   int memory_size = 0;
40   int j;
41   for( j = 0; j < 3; j++ )
42   {
43     memory_size += get_mem2Dpel (&p_Vid->imgRGB_src.data[j], p_Vid->height, p_Vid->width);
44   }
45   for( j = 0; j < 3; j++ )
46   {
47     memory_size += get_mem2Dpel (&p_Vid->imgRGB_ref.data[j], p_Vid->height, p_Vid->width);
48   }
49 
50   return memory_size;
51 }
52 
delete_RGB_memory(VideoParameters * p_Vid)53 void delete_RGB_memory(VideoParameters *p_Vid)
54 {
55   int i;
56   for( i = 0; i < 3; i++ )
57   {
58     free_mem2Dpel(p_Vid->imgRGB_src.data[i]);
59   }
60   for( i = 0; i < 3; i++ )
61   {
62     free_mem2Dpel(p_Vid->imgRGB_ref.data[i]);
63   }
64 }
65 
init_YUVtoRGB(VideoParameters * p_Vid,InputParameters * p_Inp)66 void init_YUVtoRGB(VideoParameters *p_Vid, InputParameters *p_Inp)
67 {
68   float conv_scale = (float) (65536.0f);
69 
70   p_Vid->wka0 = float2int(  conv_scale * K0);
71   p_Vid->wka1 = float2int(  conv_scale * K1);
72   p_Vid->wka2 = float2int( -conv_scale * K2);
73   p_Vid->wka3 = float2int( -conv_scale * K3);
74   p_Vid->wka4 = float2int(  conv_scale * K4);
75 
76 #ifdef YUV2RGB_YOFFSET
77   p_Vid->offset_y = OFFSET_Y << (p_Inp->output.bit_depth[0] - 8);
78   p_Vid->offset_cr = 1 << (p_Inp->output.bit_depth[0] - 1);
79 #endif
80 }
81 
82 /*!
83 *************************************************************************************
84 * \brief
85 *    YUV to RGB conversion
86 *    ITU 601 with and without offset consideration
87 *    Upsampling by repetition of chroma samples in case of 4:2:0 and 4:2:2
88 *    Method not support for 4:0:0 content
89 *************************************************************************************
90 */
YUVtoRGB(VideoParameters * p_Vid,ImageStructure * YUV,ImageStructure * RGB)91 void YUVtoRGB(VideoParameters *p_Vid, ImageStructure *YUV, ImageStructure *RGB)
92 {
93   int i, j, j_cr, i_cr;
94   int sy, su, sv;
95   int wbuv, wguv, wruv;
96   imgpel *Y, *U, *V, *R, *G, *B;
97   FrameFormat format = YUV->format;
98   int width = format.width[0];
99   int height = format.height[0];
100   int max_value = format.max_value[0];
101 
102   // Color conversion
103   for (j = 0; j < height; j++)
104   {
105     j_cr = j >> p_Vid->shift_cr_y;
106     Y = YUV->data[0][j];
107     U = YUV->data[1][j_cr];
108     V = YUV->data[2][j_cr];
109     R = RGB->data[0][j];
110     G = RGB->data[1][j];
111     B = RGB->data[2][j];
112 
113     for (i = 0; i < width; i++)
114     {
115       i_cr = i >> p_Vid->shift_cr_x;
116 
117       su = U[i_cr] - p_Vid->offset_cr;
118       sv = V[i_cr] - p_Vid->offset_cr;
119 
120       wruv = p_Vid->wka1 * sv;
121       wguv = p_Vid->wka2 * su + p_Vid->wka3 * sv;
122       wbuv = p_Vid->wka4 * su;
123 
124 #ifdef YUV2RGB_YOFFSET // Y offset value of 16 is considered
125       sy = p_Vid->wka0 * (Y[i] - p_Vid->offset_y);
126 #else
127       sy = p_Vid->wka0 * Y[i];
128 #endif
129 
130       R[i] = (imgpel) iClip1( max_value, rshift_rnd(sy + wruv, 16));
131       G[i] = (imgpel) iClip1( max_value, rshift_rnd(sy + wguv, 16));
132       B[i] = (imgpel) iClip1( max_value, rshift_rnd(sy + wbuv, 16));
133     }
134   }
135   // Setting RGB FrameFormat
136   RGB->format = format;  // copy format information from YUV to RGB
137   RGB->format.yuv_format  = YUV444;
138   RGB->format.color_model = CM_RGB;
139   RGB->format.pixel_format = BGR;
140   RGB->format.height[1]   = format.height[0];
141   RGB->format.width[1]    = format.width[0];
142   for (i = 1; i < 3; i++)
143   {
144     RGB->format.size_cmp[i]     = format.size_cmp[0];
145     RGB->format.bit_depth[i]    = format.bit_depth[0];
146     RGB->format.max_value[i]    = max_value;
147     RGB->format.max_value_sq[i] = format.max_value_sq[0];
148   }
149 }
150