Fawkes API  Fawkes Development Version
yuvrgb.h
1 
2 /****************************************************************************
3  * yuvrgb.h - YUV to RGB conversion - specific methods, macros and constants
4  *
5  * Created: Sat Aug 12 15:01:36 2006
6  * based on colorspaces.h from Tue Feb 23 13:49:38 2005
7  * Copyright 2005-2006 Tim Niemueller [www.niemueller.de]
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version. A runtime exception applies to
15  * this software (see LICENSE.GPL_WRE file mentioned below for details).
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Library General Public License for more details.
21  *
22  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23  */
24 
25 #ifndef FIREVISION_UTILS_COLOR_YUVRGB_H_
26 #define FIREVISION_UTILS_COLOR_YUVRGB_H_
27 
28 #include <fvutils/color/rgb.h>
29 #include <fvutils/color/yuv.h>
30 
31 namespace firevision {
32 
33 #define YUV2RGB(y, u, v, r, g, b) \
34  { \
35  r = y + ((v * 1436) >> 10); \
36  g = y - ((u * 352 + v * 731) >> 10); \
37  b = y + ((u * 1814) >> 10); \
38  r = r < 0 ? 0 : r; \
39  g = g < 0 ? 0 : g; \
40  b = b < 0 ? 0 : b; \
41  r = r > 255 ? 255 : r; \
42  g = g > 255 ? 255 : g; \
43  b = b > 255 ? 255 : b; \
44  }
45 
46 #define clip(x) (unsigned char)((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
47 
48 #define yuv411packed_to_rgb(YUV, RGB, width, height) \
49  yuv411packed_to_rgb_plainc(YUV, RGB, width, height)
50 
51 /** YUV to RGB Conversion
52  * B = 1.164(Y - 16) + 2.018(U - 128)
53  * G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
54  * R = 1.164(Y - 16) + 1.596(V - 128)
55  *
56  * Values have to be clamped to keep them in the [0-255] range.
57  * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range
58  * of [16-235] mentioned) but clamping the values into [0-255] seems to produce acceptable results.
59  * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after
60  * line
61  * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel
62  * (thus this is a 24bit RGB with one byte per color) line by line.
63  * @param width Width of the image contained in the YUV buffer
64  * @param height Height of the image contained in the YUV buffer
65  */
66 void yuv411packed_to_rgb_plainc(const unsigned char *YUV,
67  unsigned char * RGB,
68  unsigned int width,
69  unsigned int height);
70 
71 /** YUV to RGB Conversion
72  * B = 1.164(Y - 16) + 2.018(U - 128)
73  * G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
74  * R = 1.164(Y - 16) + 1.596(V - 128)
75  *
76  * Values have to be clamped to keep them in the [0-255] range.
77  * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range
78  * of [16-235] mentioned) but clamping the values into [0-255] seems to produce acceptable results.
79  * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after
80  * line
81  * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel
82  * (thus this is a 24bit RGB with one byte per color) line by line.
83  * @param width Width of the image contained in the YUV buffer
84  * @param height Height of the image contained in the YUV buffer
85  */
86 void yuv422planar_to_rgb_plainc(const unsigned char *planar,
87  unsigned char * RGB,
88  unsigned int width,
89  unsigned int height);
90 
91 void yuv422packed_to_rgb_plainc(const unsigned char *planar,
92  unsigned char * RGB,
93  const unsigned int width,
94  const unsigned int height);
95 
96 void yuv422planar_to_bgr_plainc(const unsigned char *planar,
97  unsigned char * BGR,
98  unsigned int width,
99  unsigned int height);
100 
101 void yuv422planar_to_rgb_with_alpha_plainc(const unsigned char *planar,
102  unsigned char * RGB,
103  unsigned int width,
104  unsigned int height);
105 
106 void yuv422planar_to_bgr_with_alpha_plainc(const unsigned char *planar,
107  unsigned char * BGR,
108  unsigned int width,
109  unsigned int height);
110 
111 void yuv422packed_to_bgr_with_alpha_plainc(const unsigned char *YUV,
112  unsigned char * BGR,
113  unsigned int width,
114  unsigned int height);
115 
116 #if (defined __i386__ || defined __386__ || defined __X86__ || defined _M_IX86 || defined i386)
117 void yuv411planar_to_rgb_mmx(const unsigned char *yuv,
118  unsigned char * rgb,
119  unsigned int w,
120  unsigned int h);
121 #endif
122 
123 inline void
124 pixel_yuv_to_rgb(const unsigned char y,
125  unsigned u,
126  unsigned char v,
127  unsigned char * r,
128  unsigned char * g,
129  unsigned char * b)
130 {
131  int yt, ut, vt;
132 
133  yt = y - 16;
134  ut = u - 128;
135  vt = v - 128;
136 
137  *r = clip((76284 * yt + 104595 * vt) >> 16);
138  *g = clip((76284 * yt - 25625 * ut - 53281 * vt) >> 16);
139  *b = clip((76284 * yt + 132252 * ut) >> 16);
140 }
141 
142 /* Convert a line of a RGB buffer to a line in a planar YUV422 buffer, see above for general
143  * notes about color space conversion from RGB to YUV
144  * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel
145  * (thus this is a 24bit RGB with one byte per color) line by line.
146  * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after
147  * line
148  * @param width Width of the image contained in the YUV buffer
149  * @param height Height of the image contained in the YUV buffer
150  * @param rgb_line the index of the line to be converted
151  * @param yuv_line the index of the line to convert to in the YUV buffer
152  */
153 inline void
154 convert_line_yuv422planar_to_rgb(const unsigned char *YUV,
155  unsigned char * RGB,
156  unsigned int width,
157  unsigned int height,
158  unsigned int yuv_line,
159  unsigned int rgb_line)
160 {
161  unsigned int i = 0;
162  RGB_t * r1, *r2;
163  const unsigned char *yp, *up, *vp;
164 
165  yp = YUV + (width * yuv_line);
166  up = YUV422_PLANAR_U_PLANE(YUV, width, height) + (width * yuv_line / 2);
167  vp = YUV422_PLANAR_V_PLANE(YUV, width, height) + (width * yuv_line / 2);
168 
169  RGB += 3 * width * rgb_line;
170 
171  while (i < width) {
172  r1 = (RGB_t *)RGB;
173  RGB += 3;
174  r2 = (RGB_t *)RGB;
175  RGB += 3;
176 
177  pixel_yuv_to_rgb(*yp++, *up, *vp, &(r1->R), &(r1->G), &(r1->B));
178  pixel_yuv_to_rgb(*yp++, *up++, *vp++, &(r2->R), &(r2->G), &(r2->B));
179 
180  i += 2;
181  }
182 }
183 
184 } // end namespace firevision
185 
186 #endif