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
31namespace 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 */
66void 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 */
86void yuv422planar_to_rgb_plainc(const unsigned char *planar,
87 unsigned char * RGB,
88 unsigned int width,
89 unsigned int height);
90
91void yuv422packed_to_rgb_plainc(const unsigned char *planar,
92 unsigned char * RGB,
93 const unsigned int width,
94 const unsigned int height);
95
96void yuv422planar_to_bgr_plainc(const unsigned char *planar,
97 unsigned char * BGR,
98 unsigned int width,
99 unsigned int height);
100
101void yuv422planar_to_rgb_with_alpha_plainc(const unsigned char *planar,
102 unsigned char * RGB,
103 unsigned int width,
104 unsigned int height);
105
106void yuv422planar_to_bgr_with_alpha_plainc(const unsigned char *planar,
107 unsigned char * BGR,
108 unsigned int width,
109 unsigned int height);
110
111void 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)
117void yuv411planar_to_rgb_mmx(const unsigned char *yuv,
118 unsigned char * rgb,
119 unsigned int w,
120 unsigned int h);
121#endif
122
123inline void
124pixel_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 */
153inline void
154convert_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