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/yuv.h>
29 #include <fvutils/color/rgb.h>
30 
31 namespace firevision {
32 #if 0 /* just to make Emacs auto-indent happy */
33 }
34 #endif
35 
36 
37 #define YUV2RGB(y, u, v, r, g, b) {\
38  r = y + ((v*1436) >> 10); \
39  g = y - ((u*352 + v*731) >> 10); \
40  b = y + ((u*1814) >> 10); \
41  r = r < 0 ? 0 : r; \
42  g = g < 0 ? 0 : g; \
43  b = b < 0 ? 0 : b; \
44  r = r > 255 ? 255 : r; \
45  g = g > 255 ? 255 : g; \
46  b = b > 255 ? 255 : b; }
47 
48 
49 #define clip(x) (unsigned char)( (x) < 0 ? 0 : ( (x) > 255 ? 255 : (x) ) )
50 
51 
52 #define yuv411packed_to_rgb(YUV, RGB, width, height) yuv411packed_to_rgb_plainc(YUV, RGB, width, height)
53 
54 
55 
56 /** YUV to RGB Conversion
57  * B = 1.164(Y - 16) + 2.018(U - 128)
58  * G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
59  * R = 1.164(Y - 16) + 1.596(V - 128)
60  *
61  * Values have to be clamped to keep them in the [0-255] range.
62  * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range
63  * of [16-235] mentioned) but clamping the values into [0-255] seems to produce acceptable results.
64  * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after
65  * line
66  * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel
67  * (thus this is a 24bit RGB with one byte per color) line by line.
68  * @param width Width of the image contained in the YUV buffer
69  * @param height Height of the image contained in the YUV buffer
70  */
71 void yuv411packed_to_rgb_plainc(const unsigned char *YUV, unsigned char *RGB,
72  unsigned int width, unsigned int height);
73 
74 
75 /** YUV to RGB Conversion
76  * B = 1.164(Y - 16) + 2.018(U - 128)
77  * G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
78  * R = 1.164(Y - 16) + 1.596(V - 128)
79  *
80  * Values have to be clamped to keep them in the [0-255] range.
81  * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range
82  * of [16-235] mentioned) but clamping the values into [0-255] seems to produce acceptable results.
83  * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after
84  * line
85  * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel
86  * (thus this is a 24bit RGB with one byte per color) line by line.
87  * @param width Width of the image contained in the YUV buffer
88  * @param height Height of the image contained in the YUV buffer
89  */
90 void yuv422planar_to_rgb_plainc(const unsigned char *planar, unsigned char *RGB,
91  unsigned int width, unsigned int height);
92 
93 void yuv422packed_to_rgb_plainc(const unsigned char *planar, unsigned char *RGB,
94  const unsigned int width, const unsigned int height);
95 
96 void yuv422planar_to_bgr_plainc(const unsigned char *planar, unsigned char *BGR,
97  unsigned int width, unsigned int height);
98 
99 
100 void yuv422planar_to_rgb_with_alpha_plainc(const unsigned char *planar, unsigned char *RGB,
101  unsigned int width, unsigned int height);
102 
103 void yuv422planar_to_bgr_with_alpha_plainc(const unsigned char *planar, unsigned char *BGR,
104  unsigned int width, unsigned int height);
105 
106 void yuv422packed_to_bgr_with_alpha_plainc(const unsigned char *YUV, unsigned char *BGR,
107  unsigned int width, unsigned int height);
108 
109 
110 #if (defined __i386__ || \
111  defined __386__ || \
112  defined __X86__ || \
113  defined _M_IX86 || \
114  defined i386 )
115 void yuv411planar_to_rgb_mmx (const unsigned char *yuv, unsigned char *rgb,
116  unsigned int w, unsigned int h);
117 #endif
118 
119 
120 
121 inline void
122 pixel_yuv_to_rgb(const unsigned char y, unsigned u, unsigned char v,
123  unsigned char *r, unsigned char *g, unsigned char *b)
124 {
125  int yt, ut, vt;
126 
127  yt = y - 16;
128  ut = u - 128;
129  vt = v - 128;
130 
131  *r = clip( (76284 * yt + 104595 * vt ) >> 16 );
132  *g = clip( (76284 * yt - 25625 * ut - 53281 * vt ) >> 16 );
133  *b = clip( (76284 * yt + 132252 * ut ) >> 16 );
134 
135 }
136 
137 
138 /* Convert a line of a RGB buffer to a line in a planar YUV422 buffer, see above for general
139  * notes about color space conversion from RGB to YUV
140  * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel
141  * (thus this is a 24bit RGB with one byte per color) line by line.
142  * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after
143  * line
144  * @param width Width of the image contained in the YUV buffer
145  * @param height Height of the image contained in the YUV buffer
146  * @param rgb_line the index of the line to be converted
147  * @param yuv_line the index of the line to convert to in the YUV buffer
148  */
149 inline void
150 convert_line_yuv422planar_to_rgb(const unsigned char *YUV, unsigned char *RGB,
151  unsigned int width, unsigned int height,
152  unsigned int yuv_line, unsigned int rgb_line)
153 {
154  unsigned int i = 0;
155  RGB_t *r1, *r2;
156  const unsigned char *yp, *up, *vp;
157 
158  yp = YUV + (width * yuv_line);
159  up = YUV422_PLANAR_U_PLANE(YUV, width, height) + (width * yuv_line / 2);
160  vp = YUV422_PLANAR_V_PLANE(YUV, width, height) + (width * yuv_line / 2);
161 
162  RGB += 3 * width * rgb_line;
163 
164  while (i < width) {
165  r1 = (RGB_t *)RGB;
166  RGB += 3;
167  r2 = (RGB_t *)RGB;
168  RGB += 3;
169 
170  pixel_yuv_to_rgb(*yp++, *up, *vp, &(r1->R), &(r1->G), &(r1->B));
171  pixel_yuv_to_rgb(*yp++, *up++, *vp++, &(r2->R), &(r2->G), &(r2->B));
172 
173  i += 2;
174  }
175 }
176 
177 } // end namespace firevision
178 
179 #endif