SDL 2.0
SDL_yuv.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "../SDL_internal.h"
22
23#include "SDL_endian.h"
24#include "SDL_video.h"
25#include "SDL_pixels_c.h"
26#include "SDL_yuv_c.h"
27
28#include "yuv2rgb/yuv_rgb.h"
29
30#define SDL_YUV_SD_THRESHOLD 576
31
32
34
35
37{
39}
40
42{
44}
45
47{
52 } else {
54 }
55 }
56 return mode;
57}
58
59static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type)
60{
63 *yuv_type = YCBCR_JPEG;
64 break;
66 *yuv_type = YCBCR_601;
67 break;
69 *yuv_type = YCBCR_709;
70 break;
71 default:
72 return SDL_SetError("Unexpected YUV conversion mode");
73 }
74 return 0;
75}
76
78{
79 return (format == SDL_PIXELFORMAT_YV12 ||
83}
84
86{
87 return (format == SDL_PIXELFORMAT_YUY2 ||
90}
91
92static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, int yuv_pitch,
93 const Uint8 **y, const Uint8 **u, const Uint8 **v, Uint32 *y_stride, Uint32 *uv_stride)
94{
95 const Uint8 *planes[3] = { NULL, NULL, NULL };
96 int pitches[3] = { 0, 0, 0 };
97
98 switch (format) {
101 pitches[0] = yuv_pitch;
102 pitches[1] = (pitches[0] + 1) / 2;
103 pitches[2] = (pitches[0] + 1) / 2;
104 planes[0] = (const Uint8 *)yuv;
105 planes[1] = planes[0] + pitches[0] * height;
106 planes[2] = planes[1] + pitches[1] * ((height + 1) / 2);
107 break;
111 pitches[0] = yuv_pitch;
112 planes[0] = (const Uint8 *)yuv;
113 break;
116 pitches[0] = yuv_pitch;
117 pitches[1] = 2 * ((pitches[0] + 1) / 2);
118 planes[0] = (const Uint8 *)yuv;
119 planes[1] = planes[0] + pitches[0] * height;
120 break;
121 default:
122 return SDL_SetError("GetYUVPlanes(): Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
123 }
124
125 switch (format) {
127 *y = planes[0];
128 *y_stride = pitches[0];
129 *v = planes[1];
130 *u = planes[2];
131 *uv_stride = pitches[1];
132 break;
134 *y = planes[0];
135 *y_stride = pitches[0];
136 *v = planes[2];
137 *u = planes[1];
138 *uv_stride = pitches[1];
139 break;
141 *y = planes[0];
142 *y_stride = pitches[0];
143 *v = *y + 3;
144 *u = *y + 1;
145 *uv_stride = pitches[0];
146 break;
148 *y = planes[0] + 1;
149 *y_stride = pitches[0];
150 *v = *y + 1;
151 *u = *y - 1;
152 *uv_stride = pitches[0];
153 break;
155 *y = planes[0];
156 *y_stride = pitches[0];
157 *v = *y + 1;
158 *u = *y + 3;
159 *uv_stride = pitches[0];
160 break;
162 *y = planes[0];
163 *y_stride = pitches[0];
164 *u = planes[1];
165 *v = *u + 1;
166 *uv_stride = pitches[1];
167 break;
169 *y = planes[0];
170 *y_stride = pitches[0];
171 *v = planes[1];
172 *u = *v + 1;
173 *uv_stride = pitches[1];
174 break;
175 default:
176 /* Should have caught this above */
177 return SDL_SetError("GetYUVPlanes[2]: Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
178 }
179 return 0;
180}
181
183 Uint32 src_format, Uint32 dst_format,
185 const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
186 Uint8 *rgb, Uint32 rgb_stride,
187 YCbCrType yuv_type)
188{
189#ifdef __SSE2__
190 if (!SDL_HasSSE2()) {
191 return SDL_FALSE;
192 }
193
194 if (src_format == SDL_PIXELFORMAT_YV12 ||
195 src_format == SDL_PIXELFORMAT_IYUV) {
196
197 switch (dst_format) {
199 yuv420_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
200 return SDL_TRUE;
202 yuv420_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
203 return SDL_TRUE;
206 yuv420_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
207 return SDL_TRUE;
210 yuv420_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
211 return SDL_TRUE;
214 yuv420_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
215 return SDL_TRUE;
218 yuv420_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
219 return SDL_TRUE;
220 default:
221 break;
222 }
223 }
224
225 if (src_format == SDL_PIXELFORMAT_YUY2 ||
226 src_format == SDL_PIXELFORMAT_UYVY ||
227 src_format == SDL_PIXELFORMAT_YVYU) {
228
229 switch (dst_format) {
231 yuv422_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
232 return SDL_TRUE;
234 yuv422_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
235 return SDL_TRUE;
238 yuv422_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
239 return SDL_TRUE;
242 yuv422_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
243 return SDL_TRUE;
246 yuv422_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
247 return SDL_TRUE;
250 yuv422_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
251 return SDL_TRUE;
252 default:
253 break;
254 }
255 }
256
257 if (src_format == SDL_PIXELFORMAT_NV12 ||
258 src_format == SDL_PIXELFORMAT_NV21) {
259
260 switch (dst_format) {
262 yuvnv12_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
263 return SDL_TRUE;
265 yuvnv12_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
266 return SDL_TRUE;
269 yuvnv12_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
270 return SDL_TRUE;
273 yuvnv12_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
274 return SDL_TRUE;
277 yuvnv12_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
278 return SDL_TRUE;
281 yuvnv12_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
282 return SDL_TRUE;
283 default:
284 break;
285 }
286 }
287#endif
288 return SDL_FALSE;
289}
290
292 Uint32 src_format, Uint32 dst_format,
294 const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
295 Uint8 *rgb, Uint32 rgb_stride,
296 YCbCrType yuv_type)
297{
298 if (src_format == SDL_PIXELFORMAT_YV12 ||
299 src_format == SDL_PIXELFORMAT_IYUV) {
300
301 switch (dst_format) {
303 yuv420_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
304 return SDL_TRUE;
306 yuv420_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
307 return SDL_TRUE;
310 yuv420_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
311 return SDL_TRUE;
314 yuv420_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
315 return SDL_TRUE;
318 yuv420_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
319 return SDL_TRUE;
322 yuv420_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
323 return SDL_TRUE;
324 default:
325 break;
326 }
327 }
328
329 if (src_format == SDL_PIXELFORMAT_YUY2 ||
330 src_format == SDL_PIXELFORMAT_UYVY ||
331 src_format == SDL_PIXELFORMAT_YVYU) {
332
333 switch (dst_format) {
335 yuv422_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
336 return SDL_TRUE;
338 yuv422_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
339 return SDL_TRUE;
342 yuv422_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
343 return SDL_TRUE;
346 yuv422_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
347 return SDL_TRUE;
350 yuv422_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
351 return SDL_TRUE;
354 yuv422_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
355 return SDL_TRUE;
356 default:
357 break;
358 }
359 }
360
361 if (src_format == SDL_PIXELFORMAT_NV12 ||
362 src_format == SDL_PIXELFORMAT_NV21) {
363
364 switch (dst_format) {
366 yuvnv12_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
367 return SDL_TRUE;
369 yuvnv12_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
370 return SDL_TRUE;
373 yuvnv12_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
374 return SDL_TRUE;
377 yuvnv12_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
378 return SDL_TRUE;
381 yuvnv12_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
382 return SDL_TRUE;
385 yuvnv12_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
386 return SDL_TRUE;
387 default:
388 break;
389 }
390 }
391 return SDL_FALSE;
392}
393
394int
396 Uint32 src_format, const void *src, int src_pitch,
397 Uint32 dst_format, void *dst, int dst_pitch)
398{
399 const Uint8 *y = NULL;
400 const Uint8 *u = NULL;
401 const Uint8 *v = NULL;
402 Uint32 y_stride = 0;
403 Uint32 uv_stride = 0;
404 YCbCrType yuv_type = YCBCR_601;
405
406 if (GetYUVPlanes(width, height, src_format, src, src_pitch, &y, &u, &v, &y_stride, &uv_stride) < 0) {
407 return -1;
408 }
409
410 if (GetYUVConversionType(width, height, &yuv_type) < 0) {
411 return -1;
412 }
413
414 if (yuv_rgb_sse(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
415 return 0;
416 }
417
418 if (yuv_rgb_std(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
419 return 0;
420 }
421
422 /* No fast path for the RGB format, instead convert using an intermediate buffer */
423 if (dst_format != SDL_PIXELFORMAT_ARGB8888) {
424 int ret;
425 void *tmp;
426 int tmp_pitch = (width * sizeof(Uint32));
427
428 tmp = SDL_malloc(tmp_pitch * height);
429 if (tmp == NULL) {
430 return SDL_OutOfMemory();
431 }
432
433 /* convert src/src_format to tmp/ARGB8888 */
434 ret = SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch);
435 if (ret < 0) {
436 SDL_free(tmp);
437 return ret;
438 }
439
440 /* convert tmp/ARGB8888 to dst/RGB */
441 ret = SDL_ConvertPixels(width, height, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch, dst_format, dst, dst_pitch);
442 SDL_free(tmp);
443 return ret;
444 }
445
446 return SDL_SetError("Unsupported YUV conversion");
447}
448
450{
452 float y[3]; /* Rfactor, Gfactor, Bfactor */
453 float u[3]; /* Rfactor, Gfactor, Bfactor */
454 float v[3]; /* Rfactor, Gfactor, Bfactor */
455};
456
457static int
458SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
459{
460 const int src_pitch_x_2 = src_pitch * 2;
461 const int height_half = height / 2;
462 const int height_remainder = (height & 0x1);
463 const int width_half = width / 2;
464 const int width_remainder = (width & 0x1);
465 int i, j;
466
467 static struct RGB2YUVFactors RGB2YUVFactorTables[SDL_YUV_CONVERSION_BT709 + 1] =
468 {
469 /* ITU-T T.871 (JPEG) */
470 {
471 0,
472 { 0.2990f, 0.5870f, 0.1140f },
473 { -0.1687f, -0.3313f, 0.5000f },
474 { 0.5000f, -0.4187f, -0.0813f },
475 },
476 /* ITU-R BT.601-7 */
477 {
478 16,
479 { 0.2568f, 0.5041f, 0.0979f },
480 { -0.1482f, -0.2910f, 0.4392f },
481 { 0.4392f, -0.3678f, -0.0714f },
482 },
483 /* ITU-R BT.709-6 */
484 {
485 16,
486 { 0.1826f, 0.6142f, 0.0620f },
487 {-0.1006f, -0.3386f, 0.4392f },
488 { 0.4392f, -0.3989f, -0.0403f },
489 },
490 };
491 const struct RGB2YUVFactors *cvt = &RGB2YUVFactorTables[SDL_GetYUVConversionModeForResolution(width, height)];
492
493#define MAKE_Y(r, g, b) (Uint8)((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset)
494#define MAKE_U(r, g, b) (Uint8)((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128)
495#define MAKE_V(r, g, b) (Uint8)((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128)
496
497#define READ_2x2_PIXELS \
498 const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
499 const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \
500 const Uint32 p3 = ((const Uint32 *)next_row)[2 * i]; \
501 const Uint32 p4 = ((const Uint32 *)next_row)[2 * i + 1]; \
502 const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \
503 const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \
504 const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; \
505
506#define READ_2x1_PIXELS \
507 const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
508 const Uint32 p2 = ((const Uint32 *)next_row)[2 * i]; \
509 const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \
510 const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \
511 const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \
512
513#define READ_1x2_PIXELS \
514 const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
515 const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \
516 const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \
517 const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \
518 const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \
519
520#define READ_1x1_PIXEL \
521 const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \
522 const Uint32 r = (p & 0x00ff0000) >> 16; \
523 const Uint32 g = (p & 0x0000ff00) >> 8; \
524 const Uint32 b = (p & 0x000000ff); \
525
526#define READ_TWO_RGB_PIXELS \
527 const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \
528 const Uint32 r = (p & 0x00ff0000) >> 16; \
529 const Uint32 g = (p & 0x0000ff00) >> 8; \
530 const Uint32 b = (p & 0x000000ff); \
531 const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i + 1]; \
532 const Uint32 r1 = (p1 & 0x00ff0000) >> 16; \
533 const Uint32 g1 = (p1 & 0x0000ff00) >> 8; \
534 const Uint32 b1 = (p1 & 0x000000ff); \
535 const Uint32 R = (r + r1)/2; \
536 const Uint32 G = (g + g1)/2; \
537 const Uint32 B = (b + b1)/2; \
538
539#define READ_ONE_RGB_PIXEL READ_1x1_PIXEL
540
541 switch (dst_format)
542 {
547 {
548 const Uint8 *curr_row, *next_row;
549
550 Uint8 *plane_y;
551 Uint8 *plane_u;
552 Uint8 *plane_v;
553 Uint8 *plane_interleaved_uv;
554 Uint32 y_stride, uv_stride, y_skip, uv_skip;
555
556 GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
557 (const Uint8 **)&plane_y, (const Uint8 **)&plane_u, (const Uint8 **)&plane_v,
558 &y_stride, &uv_stride);
559 plane_interleaved_uv = (plane_y + height * y_stride);
560 y_skip = (y_stride - width);
561
562 curr_row = (const Uint8*)src;
563
564 /* Write Y plane */
565 for (j = 0; j < height; j++) {
566 for (i = 0; i < width; i++) {
567 const Uint32 p1 = ((const Uint32 *)curr_row)[i];
568 const Uint32 r = (p1 & 0x00ff0000) >> 16;
569 const Uint32 g = (p1 & 0x0000ff00) >> 8;
570 const Uint32 b = (p1 & 0x000000ff);
571 *plane_y++ = MAKE_Y(r, g, b);
572 }
573 plane_y += y_skip;
574 curr_row += src_pitch;
575 }
576
577 curr_row = (const Uint8*)src;
578 next_row = (const Uint8*)src;
579 next_row += src_pitch;
580
581 if (dst_format == SDL_PIXELFORMAT_YV12 || dst_format == SDL_PIXELFORMAT_IYUV)
582 {
583 /* Write UV planes, not interleaved */
584 uv_skip = (uv_stride - (width + 1)/2);
585 for (j = 0; j < height_half; j++) {
586 for (i = 0; i < width_half; i++) {
588 *plane_u++ = MAKE_U(r, g, b);
589 *plane_v++ = MAKE_V(r, g, b);
590 }
591 if (width_remainder) {
593 *plane_u++ = MAKE_U(r, g, b);
594 *plane_v++ = MAKE_V(r, g, b);
595 }
596 plane_u += uv_skip;
597 plane_v += uv_skip;
598 curr_row += src_pitch_x_2;
599 next_row += src_pitch_x_2;
600 }
601 if (height_remainder) {
602 for (i = 0; i < width_half; i++) {
604 *plane_u++ = MAKE_U(r, g, b);
605 *plane_v++ = MAKE_V(r, g, b);
606 }
607 if (width_remainder) {
609 *plane_u++ = MAKE_U(r, g, b);
610 *plane_v++ = MAKE_V(r, g, b);
611 }
612 plane_u += uv_skip;
613 plane_v += uv_skip;
614 }
615 }
616 else if (dst_format == SDL_PIXELFORMAT_NV12)
617 {
618 uv_skip = (uv_stride - ((width + 1)/2)*2);
619 for (j = 0; j < height_half; j++) {
620 for (i = 0; i < width_half; i++) {
622 *plane_interleaved_uv++ = MAKE_U(r, g, b);
623 *plane_interleaved_uv++ = MAKE_V(r, g, b);
624 }
625 if (width_remainder) {
627 *plane_interleaved_uv++ = MAKE_U(r, g, b);
628 *plane_interleaved_uv++ = MAKE_V(r, g, b);
629 }
630 plane_interleaved_uv += uv_skip;
631 curr_row += src_pitch_x_2;
632 next_row += src_pitch_x_2;
633 }
634 if (height_remainder) {
635 for (i = 0; i < width_half; i++) {
637 *plane_interleaved_uv++ = MAKE_U(r, g, b);
638 *plane_interleaved_uv++ = MAKE_V(r, g, b);
639 }
640 if (width_remainder) {
642 *plane_interleaved_uv++ = MAKE_U(r, g, b);
643 *plane_interleaved_uv++ = MAKE_V(r, g, b);
644 }
645 }
646 }
647 else /* dst_format == SDL_PIXELFORMAT_NV21 */
648 {
649 uv_skip = (uv_stride - ((width + 1)/2)*2);
650 for (j = 0; j < height_half; j++) {
651 for (i = 0; i < width_half; i++) {
653 *plane_interleaved_uv++ = MAKE_V(r, g, b);
654 *plane_interleaved_uv++ = MAKE_U(r, g, b);
655 }
656 if (width_remainder) {
658 *plane_interleaved_uv++ = MAKE_V(r, g, b);
659 *plane_interleaved_uv++ = MAKE_U(r, g, b);
660 }
661 plane_interleaved_uv += uv_skip;
662 curr_row += src_pitch_x_2;
663 next_row += src_pitch_x_2;
664 }
665 if (height_remainder) {
666 for (i = 0; i < width_half; i++) {
668 *plane_interleaved_uv++ = MAKE_V(r, g, b);
669 *plane_interleaved_uv++ = MAKE_U(r, g, b);
670 }
671 if (width_remainder) {
673 *plane_interleaved_uv++ = MAKE_V(r, g, b);
674 *plane_interleaved_uv++ = MAKE_U(r, g, b);
675 }
676 }
677 }
678 }
679 break;
680
684 {
685 const Uint8 *curr_row = (const Uint8*) src;
686 Uint8 *plane = (Uint8*) dst;
687 const int row_size = (4 * ((width + 1) / 2));
688 int plane_skip;
689
690 if (dst_pitch < row_size) {
691 return SDL_SetError("Destination pitch is too small, expected at least %d\n", row_size);
692 }
693 plane_skip = (dst_pitch - row_size);
694
695 /* Write YUV plane, packed */
696 if (dst_format == SDL_PIXELFORMAT_YUY2)
697 {
698 for (j = 0; j < height; j++) {
699 for (i = 0; i < width_half; i++) {
701 /* Y U Y1 V */
702 *plane++ = MAKE_Y(r, g, b);
703 *plane++ = MAKE_U(R, G, B);
704 *plane++ = MAKE_Y(r1, g1, b1);
705 *plane++ = MAKE_V(R, G, B);
706 }
707 if (width_remainder) {
709 /* Y U Y V */
710 *plane++ = MAKE_Y(r, g, b);
711 *plane++ = MAKE_U(r, g, b);
712 *plane++ = MAKE_Y(r, g, b);
713 *plane++ = MAKE_V(r, g, b);
714 }
715 plane += plane_skip;
716 curr_row += src_pitch;
717 }
718 }
719 else if (dst_format == SDL_PIXELFORMAT_UYVY)
720 {
721 for (j = 0; j < height; j++) {
722 for (i = 0; i < width_half; i++) {
724 /* U Y V Y1 */
725 *plane++ = MAKE_U(R, G, B);
726 *plane++ = MAKE_Y(r, g, b);
727 *plane++ = MAKE_V(R, G, B);
728 *plane++ = MAKE_Y(r1, g1, b1);
729 }
730 if (width_remainder) {
732 /* U Y V Y */
733 *plane++ = MAKE_U(r, g, b);
734 *plane++ = MAKE_Y(r, g, b);
735 *plane++ = MAKE_V(r, g, b);
736 *plane++ = MAKE_Y(r, g, b);
737 }
738 plane += plane_skip;
739 curr_row += src_pitch;
740 }
741 }
742 else if (dst_format == SDL_PIXELFORMAT_YVYU)
743 {
744 for (j = 0; j < height; j++) {
745 for (i = 0; i < width_half; i++) {
747 /* Y V Y1 U */
748 *plane++ = MAKE_Y(r, g, b);
749 *plane++ = MAKE_V(R, G, B);
750 *plane++ = MAKE_Y(r1, g1, b1);
751 *plane++ = MAKE_U(R, G, B);
752 }
753 if (width_remainder) {
755 /* Y V Y U */
756 *plane++ = MAKE_Y(r, g, b);
757 *plane++ = MAKE_V(r, g, b);
758 *plane++ = MAKE_Y(r, g, b);
759 *plane++ = MAKE_U(r, g, b);
760 }
761 plane += plane_skip;
762 curr_row += src_pitch;
763 }
764 }
765 }
766 break;
767
768 default:
769 return SDL_SetError("Unsupported YUV destination format: %s", SDL_GetPixelFormatName(dst_format));
770 }
771#undef MAKE_Y
772#undef MAKE_U
773#undef MAKE_V
774#undef READ_2x2_PIXELS
775#undef READ_2x1_PIXELS
776#undef READ_1x2_PIXELS
777#undef READ_1x1_PIXEL
778#undef READ_TWO_RGB_PIXELS
779#undef READ_ONE_RGB_PIXEL
780 return 0;
781}
782
783int
785 Uint32 src_format, const void *src, int src_pitch,
786 Uint32 dst_format, void *dst, int dst_pitch)
787{
788#if 0 /* Doesn't handle odd widths */
789 /* RGB24 to FOURCC */
790 if (src_format == SDL_PIXELFORMAT_RGB24) {
791 Uint8 *y;
792 Uint8 *u;
793 Uint8 *v;
794 Uint32 y_stride;
795 Uint32 uv_stride;
796 YCbCrType yuv_type;
797
798 if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch, (const Uint8 **)&y, (const Uint8 **)&u, (const Uint8 **)&v, &y_stride, &uv_stride) < 0) {
799 return -1;
800 }
801
802 if (GetYUVConversionType(width, height, &yuv_type) < 0) {
803 return -1;
804 }
805
806 rgb24_yuv420_std(width, height, src, src_pitch, y, u, v, y_stride, uv_stride, yuv_type);
807 return 0;
808 }
809#endif
810
811 /* ARGB8888 to FOURCC */
812 if (src_format == SDL_PIXELFORMAT_ARGB8888) {
813 return SDL_ConvertPixels_ARGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch);
814 }
815
816 /* not ARGB8888 to FOURCC : need an intermediate conversion */
817 {
818 int ret;
819 void *tmp;
820 int tmp_pitch = (width * sizeof(Uint32));
821
822 tmp = SDL_malloc(tmp_pitch * height);
823 if (tmp == NULL) {
824 return SDL_OutOfMemory();
825 }
826
827 /* convert src/src_format to tmp/ARGB8888 */
828 ret = SDL_ConvertPixels(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch);
829 if (ret == -1) {
830 SDL_free(tmp);
831 return ret;
832 }
833
834 /* convert tmp/ARGB8888 to dst/FOURCC */
835 ret = SDL_ConvertPixels_ARGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch);
836 SDL_free(tmp);
837 return ret;
838 }
839}
840
841static int
843 const void *src, int src_pitch, void *dst, int dst_pitch)
844{
845 int i;
846
848 /* Y plane */
849 for (i = height; i--;) {
851 src = (const Uint8*)src + src_pitch;
852 dst = (Uint8*)dst + dst_pitch;
853 }
854
856 /* U and V planes are a quarter the size of the Y plane, rounded up */
857 width = (width + 1) / 2;
858 height = (height + 1) / 2;
859 src_pitch = (src_pitch + 1) / 2;
860 dst_pitch = (dst_pitch + 1) / 2;
861 for (i = height * 2; i--;) {
863 src = (const Uint8*)src + src_pitch;
864 dst = (Uint8*)dst + dst_pitch;
865 }
867 /* U/V plane is half the height of the Y plane, rounded up */
868 height = (height + 1) / 2;
869 width = ((width + 1) / 2)*2;
870 src_pitch = ((src_pitch + 1) / 2)*2;
871 dst_pitch = ((dst_pitch + 1) / 2)*2;
872 for (i = height; i--;) {
874 src = (const Uint8*)src + src_pitch;
875 dst = (Uint8*)dst + dst_pitch;
876 }
877 }
878 return 0;
879 }
880
881 if (IsPacked4Format(format)) {
882 /* Packed planes */
883 width = 4 * ((width + 1) / 2);
884 for (i = height; i--;) {
886 src = (const Uint8*)src + src_pitch;
887 dst = (Uint8*)dst + dst_pitch;
888 }
889 return 0;
890 }
891
892 return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV_Copy: Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
893}
894
895static int
896SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
897{
898 int y;
899 const int UVwidth = (width + 1)/2;
900 const int UVheight = (height + 1)/2;
901
902 /* Skip the Y plane */
903 src = (const Uint8 *)src + height * src_pitch;
904 dst = (Uint8 *)dst + height * dst_pitch;
905
906 if (src == dst) {
907 int UVpitch = (dst_pitch + 1)/2;
908 Uint8 *tmp;
909 Uint8 *row1 = dst;
910 Uint8 *row2 = (Uint8 *)dst + UVheight * UVpitch;
911
912 /* Allocate a temporary row for the swap */
913 tmp = (Uint8 *)SDL_malloc(UVwidth);
914 if (!tmp) {
915 return SDL_OutOfMemory();
916 }
917 for (y = 0; y < UVheight; ++y) {
918 SDL_memcpy(tmp, row1, UVwidth);
919 SDL_memcpy(row1, row2, UVwidth);
920 SDL_memcpy(row2, tmp, UVwidth);
921 row1 += UVpitch;
922 row2 += UVpitch;
923 }
924 SDL_free(tmp);
925 } else {
926 const Uint8 *srcUV;
927 Uint8 *dstUV;
928 int srcUVPitch = ((src_pitch + 1)/2);
929 int dstUVPitch = ((dst_pitch + 1)/2);
930
931 /* Copy the first plane */
932 srcUV = (const Uint8 *)src;
933 dstUV = (Uint8 *)dst + UVheight * dstUVPitch;
934 for (y = 0; y < UVheight; ++y) {
935 SDL_memcpy(dstUV, srcUV, UVwidth);
936 srcUV += srcUVPitch;
937 dstUV += dstUVPitch;
938 }
939
940 /* Copy the second plane */
941 dstUV = (Uint8 *)dst;
942 for (y = 0; y < UVheight; ++y) {
943 SDL_memcpy(dstUV, srcUV, UVwidth);
944 srcUV += srcUVPitch;
945 dstUV += dstUVPitch;
946 }
947 }
948 return 0;
949}
950
951static int
952SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
953{
954 int x, y;
955 const int UVwidth = (width + 1)/2;
956 const int UVheight = (height + 1)/2;
957 const int srcUVPitch = ((src_pitch + 1)/2);
958 const int srcUVPitchLeft = srcUVPitch - UVwidth;
959 const int dstUVPitch = ((dst_pitch + 1)/2)*2;
960 const int dstUVPitchLeft = dstUVPitch - UVwidth*2;
961 const Uint8 *src1, *src2;
962 Uint8 *dstUV;
963 Uint8 *tmp = NULL;
964#ifdef __SSE2__
965 const SDL_bool use_SSE2 = SDL_HasSSE2();
966#endif
967
968 /* Skip the Y plane */
969 src = (const Uint8 *)src + height * src_pitch;
970 dst = (Uint8 *)dst + height * dst_pitch;
971
972 if (src == dst) {
973 /* Need to make a copy of the buffer so we don't clobber it while converting */
974 tmp = (Uint8 *)SDL_malloc(2*UVheight*srcUVPitch);
975 if (!tmp) {
976 return SDL_OutOfMemory();
977 }
978 SDL_memcpy(tmp, src, 2*UVheight*srcUVPitch);
979 src = tmp;
980 }
981
982 if (reverseUV) {
983 src2 = (const Uint8 *)src;
984 src1 = src2 + UVheight * srcUVPitch;
985 } else {
986 src1 = (const Uint8 *)src;
987 src2 = src1 + UVheight * srcUVPitch;
988 }
989 dstUV = (Uint8 *)dst;
990
991 y = UVheight;
992 while (y--) {
993 x = UVwidth;
994#ifdef __SSE2__
995 if (use_SSE2) {
996 while (x >= 16) {
997 __m128i u = _mm_loadu_si128((__m128i *)src1);
998 __m128i v = _mm_loadu_si128((__m128i *)src2);
999 __m128i uv1 = _mm_unpacklo_epi8(u, v);
1000 __m128i uv2 = _mm_unpackhi_epi8(u, v);
1001 _mm_storeu_si128((__m128i*)dstUV, uv1);
1002 _mm_storeu_si128((__m128i*)(dstUV + 16), uv2);
1003 src1 += 16;
1004 src2 += 16;
1005 dstUV += 32;
1006 x -= 16;
1007 }
1008 }
1009#endif
1010 while (x--) {
1011 *dstUV++ = *src1++;
1012 *dstUV++ = *src2++;
1013 }
1014 src1 += srcUVPitchLeft;
1015 src2 += srcUVPitchLeft;
1016 dstUV += dstUVPitchLeft;
1017 }
1018
1019 if (tmp) {
1020 SDL_free(tmp);
1021 }
1022 return 0;
1023}
1024
1025static int
1026SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
1027{
1028 int x, y;
1029 const int UVwidth = (width + 1)/2;
1030 const int UVheight = (height + 1)/2;
1031 const int srcUVPitch = ((src_pitch + 1)/2)*2;
1032 const int srcUVPitchLeft = srcUVPitch - UVwidth*2;
1033 const int dstUVPitch = ((dst_pitch + 1)/2);
1034 const int dstUVPitchLeft = dstUVPitch - UVwidth;
1035 const Uint8 *srcUV;
1036 Uint8 *dst1, *dst2;
1037 Uint8 *tmp = NULL;
1038#ifdef __SSE2__
1039 const SDL_bool use_SSE2 = SDL_HasSSE2();
1040#endif
1041
1042 /* Skip the Y plane */
1043 src = (const Uint8 *)src + height * src_pitch;
1044 dst = (Uint8 *)dst + height * dst_pitch;
1045
1046 if (src == dst) {
1047 /* Need to make a copy of the buffer so we don't clobber it while converting */
1048 tmp = (Uint8 *)SDL_malloc(UVheight*srcUVPitch);
1049 if (!tmp) {
1050 return SDL_OutOfMemory();
1051 }
1052 SDL_memcpy(tmp, src, UVheight*srcUVPitch);
1053 src = tmp;
1054 }
1055
1056 if (reverseUV) {
1057 dst2 = (Uint8 *)dst;
1058 dst1 = dst2 + UVheight * dstUVPitch;
1059 } else {
1060 dst1 = (Uint8 *)dst;
1061 dst2 = dst1 + UVheight * dstUVPitch;
1062 }
1063 srcUV = (const Uint8 *)src;
1064
1065 y = UVheight;
1066 while (y--) {
1067 x = UVwidth;
1068#ifdef __SSE2__
1069 if (use_SSE2) {
1070 __m128i mask = _mm_set1_epi16(0x00FF);
1071 while (x >= 16) {
1072 __m128i uv1 = _mm_loadu_si128((__m128i*)srcUV);
1073 __m128i uv2 = _mm_loadu_si128((__m128i*)(srcUV+16));
1074 __m128i u1 = _mm_and_si128(uv1, mask);
1075 __m128i u2 = _mm_and_si128(uv2, mask);
1076 __m128i u = _mm_packus_epi16(u1, u2);
1077 __m128i v1 = _mm_srli_epi16(uv1, 8);
1078 __m128i v2 = _mm_srli_epi16(uv2, 8);
1079 __m128i v = _mm_packus_epi16(v1, v2);
1080 _mm_storeu_si128((__m128i*)dst1, u);
1081 _mm_storeu_si128((__m128i*)dst2, v);
1082 srcUV += 32;
1083 dst1 += 16;
1084 dst2 += 16;
1085 x -= 16;
1086 }
1087 }
1088#endif
1089 while (x--) {
1090 *dst1++ = *srcUV++;
1091 *dst2++ = *srcUV++;
1092 }
1093 srcUV += srcUVPitchLeft;
1094 dst1 += dstUVPitchLeft;
1095 dst2 += dstUVPitchLeft;
1096 }
1097
1098 if (tmp) {
1099 SDL_free(tmp);
1100 }
1101 return 0;
1102}
1103
1104static int
1105SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1106{
1107 int x, y;
1108 const int UVwidth = (width + 1)/2;
1109 const int UVheight = (height + 1)/2;
1110 const int srcUVPitch = ((src_pitch + 1)/2)*2;
1111 const int srcUVPitchLeft = (srcUVPitch - UVwidth*2)/sizeof(Uint16);
1112 const int dstUVPitch = ((dst_pitch + 1)/2)*2;
1113 const int dstUVPitchLeft = (dstUVPitch - UVwidth*2)/sizeof(Uint16);
1114 const Uint16 *srcUV;
1115 Uint16 *dstUV;
1116#ifdef __SSE2__
1117 const SDL_bool use_SSE2 = SDL_HasSSE2();
1118#endif
1119
1120 /* Skip the Y plane */
1121 src = (const Uint8 *)src + height * src_pitch;
1122 dst = (Uint8 *)dst + height * dst_pitch;
1123
1124 srcUV = (const Uint16 *)src;
1125 dstUV = (Uint16 *)dst;
1126 y = UVheight;
1127 while (y--) {
1128 x = UVwidth;
1129#ifdef __SSE2__
1130 if (use_SSE2) {
1131 while (x >= 8) {
1132 __m128i uv = _mm_loadu_si128((__m128i*)srcUV);
1133 __m128i v = _mm_slli_epi16(uv, 8);
1134 __m128i u = _mm_srli_epi16(uv, 8);
1135 __m128i vu = _mm_or_si128(v, u);
1136 _mm_storeu_si128((__m128i*)dstUV, vu);
1137 srcUV += 8;
1138 dstUV += 8;
1139 x -= 8;
1140 }
1141 }
1142#endif
1143 while (x--) {
1144 *dstUV++ = SDL_Swap16(*srcUV++);
1145 }
1146 srcUV += srcUVPitchLeft;
1147 dstUV += dstUVPitchLeft;
1148 }
1149 return 0;
1150}
1151
1152static int
1154 Uint32 src_format, const void *src, int src_pitch,
1155 Uint32 dst_format, void *dst, int dst_pitch)
1156{
1157 if (src != dst) {
1158 /* Copy Y plane */
1159 int i;
1160 const Uint8 *srcY = (const Uint8 *)src;
1161 Uint8 *dstY = (Uint8 *)dst;
1162 for (i = height; i--; ) {
1164 srcY += src_pitch;
1165 dstY += dst_pitch;
1166 }
1167 }
1168
1169 switch (src_format) {
1171 switch (dst_format) {
1173 return SDL_ConvertPixels_SwapUVPlanes(width, height, src, src_pitch, dst, dst_pitch);
1175 return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1177 return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1178 default:
1179 break;
1180 }
1181 break;
1183 switch (dst_format) {
1185 return SDL_ConvertPixels_SwapUVPlanes(width, height, src, src_pitch, dst, dst_pitch);
1187 return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1189 return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1190 default:
1191 break;
1192 }
1193 break;
1195 switch (dst_format) {
1197 return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1199 return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1201 return SDL_ConvertPixels_SwapNV(width, height, src, src_pitch, dst, dst_pitch);
1202 default:
1203 break;
1204 }
1205 break;
1207 switch (dst_format) {
1209 return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1211 return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1213 return SDL_ConvertPixels_SwapNV(width, height, src, src_pitch, dst, dst_pitch);
1214 default:
1215 break;
1216 }
1217 break;
1218 default:
1219 break;
1220 }
1221 return SDL_SetError("SDL_ConvertPixels_Planar2x2_to_Planar2x2: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
1222}
1223
1224#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle) \
1225 while (x >= 4) { \
1226 __m128i yuv = _mm_loadu_si128((__m128i*)srcYUV); \
1227 __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \
1228 __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \
1229 lo = _mm_shufflelo_epi16(lo, shuffle); \
1230 lo = _mm_shufflehi_epi16(lo, shuffle); \
1231 hi = _mm_shufflelo_epi16(hi, shuffle); \
1232 hi = _mm_shufflehi_epi16(hi, shuffle); \
1233 yuv = _mm_packus_epi16(lo, hi); \
1234 _mm_storeu_si128((__m128i*)dstYUV, yuv); \
1235 srcYUV += 16; \
1236 dstYUV += 16; \
1237 x -= 4; \
1238 } \
1239
1240static int
1241SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1242{
1243 int x, y;
1244 const int YUVwidth = (width + 1)/2;
1245 const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1246 const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1247 const Uint8 *srcYUV = (const Uint8 *)src;
1248 Uint8 *dstYUV = (Uint8 *)dst;
1249#ifdef __SSE2__
1250 const SDL_bool use_SSE2 = SDL_HasSSE2();
1251#endif
1252
1253 y = height;
1254 while (y--) {
1255 x = YUVwidth;
1256#ifdef __SSE2__
1257 if (use_SSE2) {
1258 PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1));
1259 }
1260#endif
1261 while (x--) {
1262 Uint8 Y1, U, Y2, V;
1263
1264 Y1 = srcYUV[0];
1265 U = srcYUV[1];
1266 Y2 = srcYUV[2];
1267 V = srcYUV[3];
1268 srcYUV += 4;
1269
1270 dstYUV[0] = U;
1271 dstYUV[1] = Y1;
1272 dstYUV[2] = V;
1273 dstYUV[3] = Y2;
1274 dstYUV += 4;
1275 }
1276 srcYUV += srcYUVPitchLeft;
1277 dstYUV += dstYUVPitchLeft;
1278 }
1279 return 0;
1280}
1281
1282static int
1283SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1284{
1285 int x, y;
1286 const int YUVwidth = (width + 1)/2;
1287 const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1288 const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1289 const Uint8 *srcYUV = (const Uint8 *)src;
1290 Uint8 *dstYUV = (Uint8 *)dst;
1291#ifdef __SSE2__
1292 const SDL_bool use_SSE2 = SDL_HasSSE2();
1293#endif
1294
1295 y = height;
1296 while (y--) {
1297 x = YUVwidth;
1298#ifdef __SSE2__
1299 if (use_SSE2) {
1300 PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0));
1301 }
1302#endif
1303 while (x--) {
1304 Uint8 Y1, U, Y2, V;
1305
1306 Y1 = srcYUV[0];
1307 U = srcYUV[1];
1308 Y2 = srcYUV[2];
1309 V = srcYUV[3];
1310 srcYUV += 4;
1311
1312 dstYUV[0] = Y1;
1313 dstYUV[1] = V;
1314 dstYUV[2] = Y2;
1315 dstYUV[3] = U;
1316 dstYUV += 4;
1317 }
1318 srcYUV += srcYUVPitchLeft;
1319 dstYUV += dstYUVPitchLeft;
1320 }
1321 return 0;
1322}
1323
1324static int
1325SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1326{
1327 int x, y;
1328 const int YUVwidth = (width + 1)/2;
1329 const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1330 const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1331 const Uint8 *srcYUV = (const Uint8 *)src;
1332 Uint8 *dstYUV = (Uint8 *)dst;
1333#ifdef __SSE2__
1334 const SDL_bool use_SSE2 = SDL_HasSSE2();
1335#endif
1336
1337 y = height;
1338 while (y--) {
1339 x = YUVwidth;
1340#ifdef __SSE2__
1341 if (use_SSE2) {
1342 PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1));
1343 }
1344#endif
1345 while (x--) {
1346 Uint8 Y1, U, Y2, V;
1347
1348 U = srcYUV[0];
1349 Y1 = srcYUV[1];
1350 V = srcYUV[2];
1351 Y2 = srcYUV[3];
1352 srcYUV += 4;
1353
1354 dstYUV[0] = Y1;
1355 dstYUV[1] = U;
1356 dstYUV[2] = Y2;
1357 dstYUV[3] = V;
1358 dstYUV += 4;
1359 }
1360 srcYUV += srcYUVPitchLeft;
1361 dstYUV += dstYUVPitchLeft;
1362 }
1363 return 0;
1364}
1365
1366static int
1367SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1368{
1369 int x, y;
1370 const int YUVwidth = (width + 1)/2;
1371 const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1372 const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1373 const Uint8 *srcYUV = (const Uint8 *)src;
1374 Uint8 *dstYUV = (Uint8 *)dst;
1375#ifdef __SSE2__
1376 const SDL_bool use_SSE2 = SDL_HasSSE2();
1377#endif
1378
1379 y = height;
1380 while (y--) {
1381 x = YUVwidth;
1382#ifdef __SSE2__
1383 if (use_SSE2) {
1384 PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(0, 3, 2, 1));
1385 }
1386#endif
1387 while (x--) {
1388 Uint8 Y1, U, Y2, V;
1389
1390 U = srcYUV[0];
1391 Y1 = srcYUV[1];
1392 V = srcYUV[2];
1393 Y2 = srcYUV[3];
1394 srcYUV += 4;
1395
1396 dstYUV[0] = Y1;
1397 dstYUV[1] = V;
1398 dstYUV[2] = Y2;
1399 dstYUV[3] = U;
1400 dstYUV += 4;
1401 }
1402 srcYUV += srcYUVPitchLeft;
1403 dstYUV += dstYUVPitchLeft;
1404 }
1405 return 0;
1406}
1407
1408static int
1409SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1410{
1411 int x, y;
1412 const int YUVwidth = (width + 1)/2;
1413 const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1414 const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1415 const Uint8 *srcYUV = (const Uint8 *)src;
1416 Uint8 *dstYUV = (Uint8 *)dst;
1417#ifdef __SSE2__
1418 const SDL_bool use_SSE2 = SDL_HasSSE2();
1419#endif
1420
1421 y = height;
1422 while (y--) {
1423 x = YUVwidth;
1424#ifdef __SSE2__
1425 if (use_SSE2) {
1426 PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0));
1427 }
1428#endif
1429 while (x--) {
1430 Uint8 Y1, U, Y2, V;
1431
1432 Y1 = srcYUV[0];
1433 V = srcYUV[1];
1434 Y2 = srcYUV[2];
1435 U = srcYUV[3];
1436 srcYUV += 4;
1437
1438 dstYUV[0] = Y1;
1439 dstYUV[1] = U;
1440 dstYUV[2] = Y2;
1441 dstYUV[3] = V;
1442 dstYUV += 4;
1443 }
1444 srcYUV += srcYUVPitchLeft;
1445 dstYUV += dstYUVPitchLeft;
1446 }
1447 return 0;
1448}
1449
1450static int
1451SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1452{
1453 int x, y;
1454 const int YUVwidth = (width + 1)/2;
1455 const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1456 const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1457 const Uint8 *srcYUV = (const Uint8 *)src;
1458 Uint8 *dstYUV = (Uint8 *)dst;
1459#ifdef __SSE2__
1460 const SDL_bool use_SSE2 = SDL_HasSSE2();
1461#endif
1462
1463 y = height;
1464 while (y--) {
1465 x = YUVwidth;
1466#ifdef __SSE2__
1467 if (use_SSE2) {
1468 PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 1, 0, 3));
1469 }
1470#endif
1471 while (x--) {
1472 Uint8 Y1, U, Y2, V;
1473
1474 Y1 = srcYUV[0];
1475 V = srcYUV[1];
1476 Y2 = srcYUV[2];
1477 U = srcYUV[3];
1478 srcYUV += 4;
1479
1480 dstYUV[0] = U;
1481 dstYUV[1] = Y1;
1482 dstYUV[2] = V;
1483 dstYUV[3] = Y2;
1484 dstYUV += 4;
1485 }
1486 srcYUV += srcYUVPitchLeft;
1487 dstYUV += dstYUVPitchLeft;
1488 }
1489 return 0;
1490}
1491
1492static int
1494 Uint32 src_format, const void *src, int src_pitch,
1495 Uint32 dst_format, void *dst, int dst_pitch)
1496{
1497 switch (src_format) {
1499 switch (dst_format) {
1501 return SDL_ConvertPixels_YUY2_to_UYVY(width, height, src, src_pitch, dst, dst_pitch);
1503 return SDL_ConvertPixels_YUY2_to_YVYU(width, height, src, src_pitch, dst, dst_pitch);
1504 default:
1505 break;
1506 }
1507 break;
1509 switch (dst_format) {
1511 return SDL_ConvertPixels_UYVY_to_YUY2(width, height, src, src_pitch, dst, dst_pitch);
1513 return SDL_ConvertPixels_UYVY_to_YVYU(width, height, src, src_pitch, dst, dst_pitch);
1514 default:
1515 break;
1516 }
1517 break;
1519 switch (dst_format) {
1521 return SDL_ConvertPixels_YVYU_to_YUY2(width, height, src, src_pitch, dst, dst_pitch);
1523 return SDL_ConvertPixels_YVYU_to_UYVY(width, height, src, src_pitch, dst, dst_pitch);
1524 default:
1525 break;
1526 }
1527 break;
1528 default:
1529 break;
1530 }
1531 return SDL_SetError("SDL_ConvertPixels_Packed4_to_Packed4: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
1532}
1533
1534static int
1536 Uint32 src_format, const void *src, int src_pitch,
1537 Uint32 dst_format, void *dst, int dst_pitch)
1538{
1539 int x, y;
1540 const Uint8 *srcY1, *srcY2, *srcU, *srcV;
1541 Uint32 srcY_pitch, srcUV_pitch;
1542 Uint32 srcY_pitch_left, srcUV_pitch_left, srcUV_pixel_stride;
1543 Uint8 *dstY1, *dstY2, *dstU1, *dstU2, *dstV1, *dstV2;
1544 Uint32 dstY_pitch, dstUV_pitch;
1545 Uint32 dst_pitch_left;
1546
1547 if (src == dst) {
1548 return SDL_SetError("Can't change YUV plane types in-place");
1549 }
1550
1551 if (GetYUVPlanes(width, height, src_format, src, src_pitch,
1552 &srcY1, &srcU, &srcV, &srcY_pitch, &srcUV_pitch) < 0) {
1553 return -1;
1554 }
1555 srcY2 = srcY1 + srcY_pitch;
1556 srcY_pitch_left = (srcY_pitch - width);
1557
1558 if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) {
1559 srcUV_pixel_stride = 2;
1560 srcUV_pitch_left = (srcUV_pitch - 2*((width + 1)/2));
1561 } else {
1562 srcUV_pixel_stride = 1;
1563 srcUV_pitch_left = (srcUV_pitch - ((width + 1)/2));
1564 }
1565
1566 if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
1567 (const Uint8 **)&dstY1, (const Uint8 **)&dstU1, (const Uint8 **)&dstV1,
1568 &dstY_pitch, &dstUV_pitch) < 0) {
1569 return -1;
1570 }
1571 dstY2 = dstY1 + dstY_pitch;
1572 dstU2 = dstU1 + dstUV_pitch;
1573 dstV2 = dstV1 + dstUV_pitch;
1574 dst_pitch_left = (dstY_pitch - 4*((width + 1)/2));
1575
1576 /* Copy 2x2 blocks of pixels at a time */
1577 for (y = 0; y < (height - 1); y += 2) {
1578 for (x = 0; x < (width - 1); x += 2) {
1579 /* Row 1 */
1580 *dstY1 = *srcY1++;
1581 dstY1 += 2;
1582 *dstY1 = *srcY1++;
1583 dstY1 += 2;
1584 *dstU1 = *srcU;
1585 *dstV1 = *srcV;
1586
1587 /* Row 2 */
1588 *dstY2 = *srcY2++;
1589 dstY2 += 2;
1590 *dstY2 = *srcY2++;
1591 dstY2 += 2;
1592 *dstU2 = *srcU;
1593 *dstV2 = *srcV;
1594
1595 srcU += srcUV_pixel_stride;
1596 srcV += srcUV_pixel_stride;
1597 dstU1 += 4;
1598 dstU2 += 4;
1599 dstV1 += 4;
1600 dstV2 += 4;
1601 }
1602
1603 /* Last column */
1604 if (x == (width - 1)) {
1605 /* Row 1 */
1606 *dstY1 = *srcY1;
1607 dstY1 += 2;
1608 *dstY1 = *srcY1++;
1609 dstY1 += 2;
1610 *dstU1 = *srcU;
1611 *dstV1 = *srcV;
1612
1613 /* Row 2 */
1614 *dstY2 = *srcY2;
1615 dstY2 += 2;
1616 *dstY2 = *srcY2++;
1617 dstY2 += 2;
1618 *dstU2 = *srcU;
1619 *dstV2 = *srcV;
1620
1621 srcU += srcUV_pixel_stride;
1622 srcV += srcUV_pixel_stride;
1623 dstU1 += 4;
1624 dstU2 += 4;
1625 dstV1 += 4;
1626 dstV2 += 4;
1627 }
1628
1629 srcY1 += srcY_pitch_left + srcY_pitch;
1630 srcY2 += srcY_pitch_left + srcY_pitch;
1631 srcU += srcUV_pitch_left;
1632 srcV += srcUV_pitch_left;
1633 dstY1 += dst_pitch_left + dstY_pitch;
1634 dstY2 += dst_pitch_left + dstY_pitch;
1635 dstU1 += dst_pitch_left + dstUV_pitch;
1636 dstU2 += dst_pitch_left + dstUV_pitch;
1637 dstV1 += dst_pitch_left + dstUV_pitch;
1638 dstV2 += dst_pitch_left + dstUV_pitch;
1639 }
1640
1641 /* Last row */
1642 if (y == (height - 1)) {
1643 for (x = 0; x < (width - 1); x += 2) {
1644 /* Row 1 */
1645 *dstY1 = *srcY1++;
1646 dstY1 += 2;
1647 *dstY1 = *srcY1++;
1648 dstY1 += 2;
1649 *dstU1 = *srcU;
1650 *dstV1 = *srcV;
1651
1652 srcU += srcUV_pixel_stride;
1653 srcV += srcUV_pixel_stride;
1654 dstU1 += 4;
1655 dstV1 += 4;
1656 }
1657
1658 /* Last column */
1659 if (x == (width - 1)) {
1660 /* Row 1 */
1661 *dstY1 = *srcY1;
1662 dstY1 += 2;
1663 *dstY1 = *srcY1++;
1664 dstY1 += 2;
1665 *dstU1 = *srcU;
1666 *dstV1 = *srcV;
1667
1668 srcU += srcUV_pixel_stride;
1669 srcV += srcUV_pixel_stride;
1670 dstU1 += 4;
1671 dstV1 += 4;
1672 }
1673 }
1674 return 0;
1675}
1676
1677static int
1679 Uint32 src_format, const void *src, int src_pitch,
1680 Uint32 dst_format, void *dst, int dst_pitch)
1681{
1682 int x, y;
1683 const Uint8 *srcY1, *srcY2, *srcU1, *srcU2, *srcV1, *srcV2;
1684 Uint32 srcY_pitch, srcUV_pitch;
1685 Uint32 src_pitch_left;
1686 Uint8 *dstY1, *dstY2, *dstU, *dstV;
1687 Uint32 dstY_pitch, dstUV_pitch;
1688 Uint32 dstY_pitch_left, dstUV_pitch_left, dstUV_pixel_stride;
1689
1690 if (src == dst) {
1691 return SDL_SetError("Can't change YUV plane types in-place");
1692 }
1693
1694 if (GetYUVPlanes(width, height, src_format, src, src_pitch,
1695 &srcY1, &srcU1, &srcV1, &srcY_pitch, &srcUV_pitch) < 0) {
1696 return -1;
1697 }
1698 srcY2 = srcY1 + srcY_pitch;
1699 srcU2 = srcU1 + srcUV_pitch;
1700 srcV2 = srcV1 + srcUV_pitch;
1701 src_pitch_left = (srcY_pitch - 4*((width + 1)/2));
1702
1703 if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
1704 (const Uint8 **)&dstY1, (const Uint8 **)&dstU, (const Uint8 **)&dstV,
1705 &dstY_pitch, &dstUV_pitch) < 0) {
1706 return -1;
1707 }
1708 dstY2 = dstY1 + dstY_pitch;
1709 dstY_pitch_left = (dstY_pitch - width);
1710
1711 if (dst_format == SDL_PIXELFORMAT_NV12 || dst_format == SDL_PIXELFORMAT_NV21) {
1712 dstUV_pixel_stride = 2;
1713 dstUV_pitch_left = (dstUV_pitch - 2*((width + 1)/2));
1714 } else {
1715 dstUV_pixel_stride = 1;
1716 dstUV_pitch_left = (dstUV_pitch - ((width + 1)/2));
1717 }
1718
1719 /* Copy 2x2 blocks of pixels at a time */
1720 for (y = 0; y < (height - 1); y += 2) {
1721 for (x = 0; x < (width - 1); x += 2) {
1722 /* Row 1 */
1723 *dstY1++ = *srcY1;
1724 srcY1 += 2;
1725 *dstY1++ = *srcY1;
1726 srcY1 += 2;
1727
1728 /* Row 2 */
1729 *dstY2++ = *srcY2;
1730 srcY2 += 2;
1731 *dstY2++ = *srcY2;
1732 srcY2 += 2;
1733
1734 *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2);
1735 *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2);
1736
1737 srcU1 += 4;
1738 srcU2 += 4;
1739 srcV1 += 4;
1740 srcV2 += 4;
1741 dstU += dstUV_pixel_stride;
1742 dstV += dstUV_pixel_stride;
1743 }
1744
1745 /* Last column */
1746 if (x == (width - 1)) {
1747 /* Row 1 */
1748 *dstY1 = *srcY1;
1749 srcY1 += 2;
1750 *dstY1++ = *srcY1;
1751 srcY1 += 2;
1752
1753 /* Row 2 */
1754 *dstY2 = *srcY2;
1755 srcY2 += 2;
1756 *dstY2++ = *srcY2;
1757 srcY2 += 2;
1758
1759 *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2);
1760 *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2);
1761
1762 srcU1 += 4;
1763 srcU2 += 4;
1764 srcV1 += 4;
1765 srcV2 += 4;
1766 dstU += dstUV_pixel_stride;
1767 dstV += dstUV_pixel_stride;
1768 }
1769
1770 srcY1 += src_pitch_left + srcY_pitch;
1771 srcY2 += src_pitch_left + srcY_pitch;
1772 srcU1 += src_pitch_left + srcUV_pitch;
1773 srcU2 += src_pitch_left + srcUV_pitch;
1774 srcV1 += src_pitch_left + srcUV_pitch;
1775 srcV2 += src_pitch_left + srcUV_pitch;
1776 dstY1 += dstY_pitch_left + dstY_pitch;
1777 dstY2 += dstY_pitch_left + dstY_pitch;
1778 dstU += dstUV_pitch_left;
1779 dstV += dstUV_pitch_left;
1780 }
1781
1782 /* Last row */
1783 if (y == (height - 1)) {
1784 for (x = 0; x < (width - 1); x += 2) {
1785 *dstY1++ = *srcY1;
1786 srcY1 += 2;
1787 *dstY1++ = *srcY1;
1788 srcY1 += 2;
1789
1790 *dstU = *srcU1;
1791 *dstV = *srcV1;
1792
1793 srcU1 += 4;
1794 srcV1 += 4;
1795 dstU += dstUV_pixel_stride;
1796 dstV += dstUV_pixel_stride;
1797 }
1798
1799 /* Last column */
1800 if (x == (width - 1)) {
1801 *dstY1 = *srcY1;
1802 *dstU = *srcU1;
1803 *dstV = *srcV1;
1804 }
1805 }
1806 return 0;
1807}
1808
1809int
1811 Uint32 src_format, const void *src, int src_pitch,
1812 Uint32 dst_format, void *dst, int dst_pitch)
1813{
1814 if (src_format == dst_format) {
1815 if (src == dst) {
1816 /* Nothing to do */
1817 return 0;
1818 }
1819 return SDL_ConvertPixels_YUV_to_YUV_Copy(width, height, src_format, src, src_pitch, dst, dst_pitch);
1820 }
1821
1822 if (IsPlanar2x2Format(src_format) && IsPlanar2x2Format(dst_format)) {
1823 return SDL_ConvertPixels_Planar2x2_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1824 } else if (IsPacked4Format(src_format) && IsPacked4Format(dst_format)) {
1825 return SDL_ConvertPixels_Packed4_to_Packed4(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1826 } else if (IsPlanar2x2Format(src_format) && IsPacked4Format(dst_format)) {
1827 return SDL_ConvertPixels_Planar2x2_to_Packed4(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1828 } else if (IsPacked4Format(src_format) && IsPlanar2x2Format(dst_format)) {
1829 return SDL_ConvertPixels_Packed4_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1830 } else {
1831 return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
1832 }
1833}
1834
1835/* vi: set ts=4 sw=4 expandtab: */
#define SDL_SetError
#define SDL_GetPixelFormatName
#define SDL_malloc
#define SDL_free
#define SDL_memcpy
#define SDL_ConvertPixels
#define SDL_HasSSE2
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
Definition: SDL_endian.h:107
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
const GLdouble * v
Definition: SDL_opengl.h:2064
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint GLint GLint dstY1
GLenum mode
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint GLint dstY
GLenum src
GLfixed u1
GLenum GLenum dst
GLint GLint GLint srcY1
GLboolean GLboolean g
GLfloat GLfloat v1
GLfixed GLfixed u2
GLenum GLint GLuint mask
GLfloat GLfloat GLfloat v2
GLenum GLint GLint GLint srcY
@ SDL_PIXELFORMAT_YVYU
Definition: SDL_pixels.h:285
@ SDL_PIXELFORMAT_RGBA8888
Definition: SDL_pixels.h:251
@ SDL_PIXELFORMAT_UYVY
Definition: SDL_pixels.h:283
@ SDL_PIXELFORMAT_BGR888
Definition: SDL_pixels.h:242
@ SDL_PIXELFORMAT_YV12
Definition: SDL_pixels.h:277
@ SDL_PIXELFORMAT_BGRX8888
Definition: SDL_pixels.h:245
@ SDL_PIXELFORMAT_RGB24
Definition: SDL_pixels.h:230
@ SDL_PIXELFORMAT_RGB888
Definition: SDL_pixels.h:236
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
@ SDL_PIXELFORMAT_YUY2
Definition: SDL_pixels.h:281
@ SDL_PIXELFORMAT_NV12
Definition: SDL_pixels.h:287
@ SDL_PIXELFORMAT_BGRA8888
Definition: SDL_pixels.h:257
@ SDL_PIXELFORMAT_NV21
Definition: SDL_pixels.h:289
@ SDL_PIXELFORMAT_IYUV
Definition: SDL_pixels.h:279
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
@ SDL_PIXELFORMAT_RGBX8888
Definition: SDL_pixels.h:239
@ SDL_PIXELFORMAT_RGB565
Definition: SDL_pixels.h:224
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_YUV_CONVERSION_MODE
The formula used for converting between YUV and RGB.
Definition: SDL_surface.h:105
@ SDL_YUV_CONVERSION_BT601
Definition: SDL_surface.h:107
@ SDL_YUV_CONVERSION_JPEG
Definition: SDL_surface.h:106
@ SDL_YUV_CONVERSION_BT709
Definition: SDL_surface.h:108
@ SDL_YUV_CONVERSION_AUTOMATIC
Definition: SDL_surface.h:109
#define G(x, y, z)
Definition: SDL_test_md5.c:74
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define READ_2x2_PIXELS
static int SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:458
static int SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:842
static int SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1241
#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle)
Definition: SDL_yuv.c:1224
#define READ_1x2_PIXELS
static int SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1535
static SDL_bool yuv_rgb_std(Uint32 src_format, Uint32 dst_format, Uint32 width, Uint32 height, const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type)
Definition: SDL_yuv.c:291
static int SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:896
int SDL_ConvertPixels_RGB_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:784
#define READ_TWO_RGB_PIXELS
static int SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
Definition: SDL_yuv.c:952
#define MAKE_U(r, g, b)
static int SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
Definition: SDL_yuv.c:1026
static int SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1367
static int SDL_ConvertPixels_Packed4_to_Packed4(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1493
static SDL_bool IsPlanar2x2Format(Uint32 format)
Definition: SDL_yuv.c:77
int SDL_ConvertPixels_YUV_to_RGB(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:395
static int SDL_ConvertPixels_Planar2x2_to_Planar2x2(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1153
#define MAKE_V(r, g, b)
static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type)
Definition: SDL_yuv.c:59
static int SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1325
static SDL_YUV_CONVERSION_MODE SDL_YUV_ConversionMode
Definition: SDL_yuv.c:33
static SDL_bool IsPacked4Format(Uint32 format)
Definition: SDL_yuv.c:85
#define READ_2x1_PIXELS
#define READ_ONE_RGB_PIXEL
static int SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1105
static int SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1678
#define SDL_YUV_SD_THRESHOLD
Definition: SDL_yuv.c:30
static SDL_bool yuv_rgb_sse(Uint32 src_format, Uint32 dst_format, Uint32 width, Uint32 height, const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type)
Definition: SDL_yuv.c:182
static int SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1451
int SDL_ConvertPixels_YUV_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1810
static int SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1409
static int SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1283
#define READ_1x1_PIXEL
#define MAKE_Y(r, g, b)
void SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode)
Set the YUV conversion mode.
Definition: SDL_yuv.c:36
static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, int yuv_pitch, const Uint8 **y, const Uint8 **u, const Uint8 **v, Uint32 *y_stride, Uint32 *uv_stride)
Definition: SDL_yuv.c:92
SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionMode()
Get the YUV conversion mode.
Definition: SDL_yuv.c:41
SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionModeForResolution(int width, int height)
Get the YUV conversion mode, returning the correct mode for the resolution when the current conversio...
Definition: SDL_yuv.c:46
#define NULL
Definition: begin_code.h:167
float u[3]
Definition: SDL_yuv.c:453
void rgb24_yuv420_std(uint32_t width, uint32_t height, const uint8_t *RGB, uint32_t RGB_stride, uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, YCbCrType yuv_type)
Definition: yuv_rgb.c:186
#define V(value)
Definition: yuv_rgb.c:35
void yuv420_rgba_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_abgr_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_bgra_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_rgb565_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_bgra_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_bgra_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_bgra_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_argb_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_rgb24_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgb24_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_abgr_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgba_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_abgr_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_argb_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgb565_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgb24_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_abgr_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_bgra_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_rgb565_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_bgra_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_argb_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_rgba_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_abgr_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_rgb24_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_rgb565_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_rgba_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgb565_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_rgb24_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_argb_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_argb_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_rgba_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_rgb24_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_rgb565_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_abgr_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_argb_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgba_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
YCbCrType
Definition: yuv_rgb.h:23
@ YCBCR_JPEG
Definition: yuv_rgb.h:24
@ YCBCR_709
Definition: yuv_rgb.h:26
@ YCBCR_601
Definition: yuv_rgb.h:25