SDL  2.0
testyuv_cvt.c File Reference
#include "SDL.h"
#include "testyuv_cvt.h"
+ Include dependency graph for testyuv_cvt.c:

Go to the source code of this file.

Functions

static float clip3 (float x, float y, float z)
 
static void RGBtoYUV (Uint8 *rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
 
static void ConvertRGBtoPlanar2x2 (Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
 
static void ConvertRGBtoPacked4 (Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
 
SDL_bool ConvertRGBtoYUV (Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
 
int CalculateYUVPitch (Uint32 format, int width)
 

Function Documentation

◆ CalculateYUVPitch()

int CalculateYUVPitch ( Uint32  format,
int  width 
)

Definition at line 282 of file testyuv_cvt.c.

References SDL_PIXELFORMAT_IYUV, SDL_PIXELFORMAT_NV12, SDL_PIXELFORMAT_NV21, SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_YV12, and SDL_PIXELFORMAT_YVYU.

Referenced by main(), and run_automated_tests().

283 {
284  switch (format)
285  {
290  return width;
294  return 4*((width + 1)/2);
295  default:
296  return 0;
297  }
298 }
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572

◆ clip3()

static float clip3 ( float  x,
float  y,
float  z 
)
static

Definition at line 18 of file testyuv_cvt.c.

Referenced by RGBtoYUV().

19 {
20  return ((z < x) ? x : ((z > y) ? y : z));
21 }
GLdouble GLdouble z
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574

◆ ConvertRGBtoPacked4()

static void ConvertRGBtoPacked4 ( Uint32  format,
Uint8 src,
int  pitch,
Uint8 out,
int  w,
int  h,
SDL_YUV_CONVERSION_MODE  mode,
int  monochrome,
int  luminance 
)
static

Definition at line 192 of file testyuv_cvt.c.

References RGBtoYUV(), SDL_assert, SDL_floorf, SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_YVYU, and V.

Referenced by ConvertRGBtoYUV().

193 {
194  int x, y;
195  int yuv[2][3];
196  Uint8 *Y1, *Y2, *U, *V;
197  Uint8 *rgb;
198  int rgb_row_advance = (pitch - w*3);
199 
200  rgb = src;
201 
202  switch (format) {
204  Y1 = out;
205  U = out+1;
206  Y2 = out+2;
207  V = out+3;
208  break;
210  U = out;
211  Y1 = out+1;
212  V = out+2;
213  Y2 = out+3;
214  break;
216  Y1 = out;
217  V = out+1;
218  Y2 = out+2;
219  U = out+3;
220  break;
221  default:
222  SDL_assert(!"Unsupported packed YUV format");
223  return;
224  }
225 
226  for (y = 0; y < h; ++y) {
227  for (x = 0; x < (w - 1); x += 2) {
228  RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance);
229  rgb += 3;
230  *Y1 = (Uint8)yuv[0][0];
231  Y1 += 4;
232 
233  RGBtoYUV(rgb, yuv[1], mode, monochrome, luminance);
234  rgb += 3;
235  *Y2 = (Uint8)yuv[1][0];
236  Y2 += 4;
237 
238  *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f);
239  U += 4;
240 
241  *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f);
242  V += 4;
243  }
244  /* Last column */
245  if (x == (w - 1)) {
246  RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance);
247  rgb += 3;
248  *Y2 = *Y1 = (Uint8)yuv[0][0];
249  Y1 += 4;
250  Y2 += 4;
251 
252  *U = (Uint8)yuv[0][1];
253  U += 4;
254 
255  *V = (Uint8)yuv[0][2];
256  V += 4;
257  }
258  rgb += rgb_row_advance;
259  }
260 }
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLfloat GLfloat GLfloat GLfloat h
static void RGBtoYUV(Uint8 *rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
Definition: testyuv_cvt.c:23
GLenum src
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
uint8_t Uint8
Definition: SDL_stdinc.h:157
GLenum mode
GLubyte GLubyte GLubyte GLubyte w
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define SDL_floorf
#define V(value)
Definition: yuv_rgb.c:35

◆ ConvertRGBtoPlanar2x2()

static void ConvertRGBtoPlanar2x2 ( Uint32  format,
Uint8 src,
int  pitch,
Uint8 out,
int  w,
int  h,
SDL_YUV_CONVERSION_MODE  mode,
int  monochrome,
int  luminance 
)
static

Definition at line 76 of file testyuv_cvt.c.

References RGBtoYUV(), SDL_assert, SDL_floorf, SDL_PIXELFORMAT_IYUV, SDL_PIXELFORMAT_NV12, SDL_PIXELFORMAT_NV21, SDL_PIXELFORMAT_YV12, and V.

Referenced by ConvertRGBtoYUV().

77 {
78  int x, y;
79  int yuv[4][3];
80  Uint8 *Y1, *Y2, *U, *V;
81  Uint8 *rgb1, *rgb2;
82  int rgb_row_advance = (pitch - w*3) + pitch;
83  int UV_advance;
84 
85  rgb1 = src;
86  rgb2 = src + pitch;
87 
88  Y1 = out;
89  Y2 = Y1 + w;
90  switch (format) {
92  V = (Y1 + h * w);
93  U = V + ((h + 1)/2)*((w + 1)/2);
94  UV_advance = 1;
95  break;
97  U = (Y1 + h * w);
98  V = U + ((h + 1)/2)*((w + 1)/2);
99  UV_advance = 1;
100  break;
102  U = (Y1 + h * w);
103  V = U + 1;
104  UV_advance = 2;
105  break;
107  V = (Y1 + h * w);
108  U = V + 1;
109  UV_advance = 2;
110  break;
111  default:
112  SDL_assert(!"Unsupported planar YUV format");
113  return;
114  }
115 
116  for (y = 0; y < (h - 1); y += 2) {
117  for (x = 0; x < (w - 1); x += 2) {
118  RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
119  rgb1 += 3;
120  *Y1++ = (Uint8)yuv[0][0];
121 
122  RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance);
123  rgb1 += 3;
124  *Y1++ = (Uint8)yuv[1][0];
125 
126  RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance);
127  rgb2 += 3;
128  *Y2++ = (Uint8)yuv[2][0];
129 
130  RGBtoYUV(rgb2, yuv[3], mode, monochrome, luminance);
131  rgb2 += 3;
132  *Y2++ = (Uint8)yuv[3][0];
133 
134  *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1])/4.0f + 0.5f);
135  U += UV_advance;
136 
137  *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2])/4.0f + 0.5f);
138  V += UV_advance;
139  }
140  /* Last column */
141  if (x == (w - 1)) {
142  RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
143  rgb1 += 3;
144  *Y1++ = (Uint8)yuv[0][0];
145 
146  RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance);
147  rgb2 += 3;
148  *Y2++ = (Uint8)yuv[2][0];
149 
150  *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[2][1])/2.0f + 0.5f);
151  U += UV_advance;
152 
153  *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[2][2])/2.0f + 0.5f);
154  V += UV_advance;
155  }
156  Y1 += w;
157  Y2 += w;
158  rgb1 += rgb_row_advance;
159  rgb2 += rgb_row_advance;
160  }
161  /* Last row */
162  if (y == (h - 1)) {
163  for (x = 0; x < (w - 1); x += 2) {
164  RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
165  rgb1 += 3;
166  *Y1++ = (Uint8)yuv[0][0];
167 
168  RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance);
169  rgb1 += 3;
170  *Y1++ = (Uint8)yuv[1][0];
171 
172  *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f);
173  U += UV_advance;
174 
175  *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f);
176  V += UV_advance;
177  }
178  /* Last column */
179  if (x == (w - 1)) {
180  RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
181  *Y1++ = (Uint8)yuv[0][0];
182 
183  *U = (Uint8)yuv[0][1];
184  U += UV_advance;
185 
186  *V = (Uint8)yuv[0][2];
187  V += UV_advance;
188  }
189  }
190 }
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLfloat GLfloat GLfloat GLfloat h
static void RGBtoYUV(Uint8 *rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
Definition: testyuv_cvt.c:23
GLenum src
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
uint8_t Uint8
Definition: SDL_stdinc.h:157
GLenum mode
GLubyte GLubyte GLubyte GLubyte w
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define SDL_floorf
#define V(value)
Definition: yuv_rgb.c:35

◆ ConvertRGBtoYUV()

SDL_bool ConvertRGBtoYUV ( Uint32  format,
Uint8 src,
int  pitch,
Uint8 out,
int  w,
int  h,
SDL_YUV_CONVERSION_MODE  mode,
int  monochrome,
int  luminance 
)

Definition at line 262 of file testyuv_cvt.c.

References ConvertRGBtoPacked4(), ConvertRGBtoPlanar2x2(), SDL_FALSE, SDL_PIXELFORMAT_IYUV, SDL_PIXELFORMAT_NV12, SDL_PIXELFORMAT_NV21, SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_YV12, SDL_PIXELFORMAT_YVYU, and SDL_TRUE.

Referenced by main(), and run_automated_tests().

263 {
264  switch (format)
265  {
270  ConvertRGBtoPlanar2x2(format, src, pitch, out, w, h, mode, monochrome, luminance);
271  return SDL_TRUE;
275  ConvertRGBtoPacked4(format, src, pitch, out, w, h, mode, monochrome, luminance);
276  return SDL_TRUE;
277  default:
278  return SDL_FALSE;
279  }
280 }
static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
Definition: testyuv_cvt.c:192
GLfloat GLfloat GLfloat GLfloat h
GLenum src
static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
Definition: testyuv_cvt.c:76
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLenum mode
GLubyte GLubyte GLubyte GLubyte w

◆ RGBtoYUV()

static void RGBtoYUV ( Uint8 rgb,
int *  yuv,
SDL_YUV_CONVERSION_MODE  mode,
int  monochrome,
int  luminance 
)
static

Definition at line 23 of file testyuv_cvt.c.

References clip3(), G, SDL_floorf, SDL_YUV_CONVERSION_BT709, SDL_YUV_CONVERSION_JPEG, and V.

Referenced by ConvertRGBtoPacked4(), and ConvertRGBtoPlanar2x2().

24 {
26  /* Full range YUV */
27  yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
28  yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
29  yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
30  } else {
31  // This formula is from Microsoft's documentation:
32  // https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx
33  // L = Kr * R + Kb * B + (1 - Kr - Kb) * G
34  // Y = floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5);
35  // U = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5));
36  // V = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5));
37  float S, Z, R, G, B, L, Kr, Kb, Y, U, V;
38 
40  /* BT.709 */
41  Kr = 0.2126f;
42  Kb = 0.0722f;
43  } else {
44  /* BT.601 */
45  Kr = 0.299f;
46  Kb = 0.114f;
47  }
48 
49  S = 255.0f;
50  Z = 0.0f;
51  R = rgb[0];
52  G = rgb[1];
53  B = rgb[2];
54  L = Kr * R + Kb * B + (1 - Kr - Kb) * G;
55  Y = (Uint8)SDL_floorf((219*(L-Z)/S + 16) + 0.5f);
56  U = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(B-L) / ((1.0f-Kb)*S) + 128) + 0.5f));
57  V = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(R-L) / ((1.0f-Kr)*S) + 128) + 0.5f));
58 
59  yuv[0] = (Uint8)Y;
60  yuv[1] = (Uint8)U;
61  yuv[2] = (Uint8)V;
62  }
63 
64  if (monochrome) {
65  yuv[1] = 128;
66  yuv[2] = 128;
67  }
68 
69  if (luminance != 100) {
70  yuv[0] = yuv[0] * luminance / 100;
71  if (yuv[0] > 255)
72  yuv[0] = 255;
73  }
74 }
GLfloat f
uint8_t Uint8
Definition: SDL_stdinc.h:157
GLenum mode
static float clip3(float x, float y, float z)
Definition: testyuv_cvt.c:18
#define G(x, y, z)
Definition: SDL_test_md5.c:74
#define SDL_floorf
#define V(value)
Definition: yuv_rgb.c:35