Merge branch '7.8'
[mesa.git] / src / gallium / auxiliary / util / u_format_yuv.c
1 /**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 **************************************************************************/
27
28
29 /**
30 * @file
31 * YUV and RGB subsampled formats conversion.
32 *
33 * @author Jose Fonseca <jfonseca@vmware.com>
34 */
35
36
37 #include "util/u_format_yuv.h"
38
39
40 void
41 util_format_r8g8_b8g8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
42 const uint8_t *src_row, unsigned src_stride,
43 unsigned width, unsigned height)
44 {
45 unsigned x, y;
46
47 for (y = 0; y < height; y += 1) {
48 float *dst = dst_row;
49 const uint32_t *src = (const uint32_t *)src_row;
50 uint32_t value;
51 float r, g0, g1, b;
52
53 for (x = 0; x + 1 < width; x += 2) {
54 value = *src++;
55
56 #ifdef PIPE_ARCH_BIG_ENDIAN
57 value = util_bswap32(value);
58 #endif
59
60 r = ubyte_to_float((value >> 0) & 0xff);
61 g0 = ubyte_to_float((value >> 8) & 0xff);
62 b = ubyte_to_float((value >> 16) & 0xff);
63 g1 = ubyte_to_float((value >> 24) & 0xff);
64
65 dst[0] = r; /* r */
66 dst[1] = g0; /* g */
67 dst[2] = b; /* b */
68 dst[3] = 1.0f; /* a */
69 dst += 4;
70
71 dst[0] = r; /* r */
72 dst[1] = g1; /* g */
73 dst[2] = b; /* b */
74 dst[3] = 1.0f; /* a */
75 dst += 4;
76 }
77
78 if (x < width) {
79 value = *src;
80
81 #ifdef PIPE_ARCH_BIG_ENDIAN
82 value = util_bswap32(value);
83 #endif
84
85 r = ubyte_to_float((value >> 0) & 0xff);
86 g0 = ubyte_to_float((value >> 8) & 0xff);
87 b = ubyte_to_float((value >> 16) & 0xff);
88 g1 = ubyte_to_float((value >> 24) & 0xff);
89
90 dst[0] = r; /* r */
91 dst[1] = g0; /* g */
92 dst[2] = b; /* b */
93 dst[3] = 1.0f; /* a */
94 }
95
96 src_row += src_stride/sizeof(*src_row);
97 dst_row += dst_stride/sizeof(*dst_row);
98 }
99 }
100
101
102 void
103 util_format_r8g8_b8g8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
104 const uint8_t *src_row, unsigned src_stride,
105 unsigned width, unsigned height)
106 {
107 unsigned x, y;
108
109 for (y = 0; y < height; y += 1) {
110 uint8_t *dst = dst_row;
111 const uint32_t *src = (const uint32_t *)src_row;
112 uint32_t value;
113 uint8_t r, g0, g1, b;
114
115 for (x = 0; x + 1 < width; x += 2) {
116 value = *src++;
117
118 #ifdef PIPE_ARCH_BIG_ENDIAN
119 value = util_bswap32(value);
120 #endif
121
122 r = (value >> 0) & 0xff;
123 g0 = (value >> 8) & 0xff;
124 b = (value >> 16) & 0xff;
125 g1 = (value >> 24) & 0xff;
126
127 dst[0] = r; /* r */
128 dst[1] = g0; /* g */
129 dst[2] = b; /* b */
130 dst[3] = 0xff; /* a */
131 dst += 4;
132
133 dst[0] = r; /* r */
134 dst[1] = g1; /* g */
135 dst[2] = b; /* b */
136 dst[3] = 0xff; /* a */
137 dst += 4;
138 }
139
140 if (x < width) {
141 value = *src;
142
143 #ifdef PIPE_ARCH_BIG_ENDIAN
144 value = util_bswap32(value);
145 #endif
146
147 r = (value >> 0) & 0xff;
148 g0 = (value >> 8) & 0xff;
149 b = (value >> 16) & 0xff;
150 g1 = (value >> 24) & 0xff;
151
152 dst[0] = r; /* r */
153 dst[1] = g0; /* g */
154 dst[2] = b; /* b */
155 dst[3] = 0xff; /* a */
156 }
157
158 src_row += src_stride/sizeof(*src_row);
159 dst_row += dst_stride/sizeof(*dst_row);
160 }
161 }
162
163
164 void
165 util_format_r8g8_b8g8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
166 const float *src_row, unsigned src_stride,
167 unsigned width, unsigned height)
168 {
169 unsigned x, y;
170
171 for (y = 0; y < height; y += 1) {
172 const float *src = src_row;
173 uint32_t *dst = (uint32_t *)dst_row;
174 float r, g0, g1, b;
175 uint32_t value;
176
177 for (x = 0; x + 1 < width; x += 2) {
178 r = 0.5f*(src[0] + src[4]);
179 g0 = src[1];
180 g1 = src[5];
181 b = 0.5f*(src[2] + src[6]);
182
183 value = float_to_ubyte(r);
184 value |= float_to_ubyte(g0) << 8;
185 value |= float_to_ubyte(b) << 16;
186 value |= float_to_ubyte(g1) << 24;
187
188 #ifdef PIPE_ARCH_BIG_ENDIAN
189 value = util_bswap32(value);
190 #endif
191
192 *dst++ = value;
193
194 src += 8;
195 }
196
197 if (x < width) {
198 r = src[0];
199 g0 = src[1];
200 g1 = 0;
201 b = src[2];
202
203 value = float_to_ubyte(r);
204 value |= float_to_ubyte(g0) << 8;
205 value |= float_to_ubyte(b) << 16;
206 value |= float_to_ubyte(g1) << 24;
207
208 #ifdef PIPE_ARCH_BIG_ENDIAN
209 value = util_bswap32(value);
210 #endif
211
212 *dst = value;
213 }
214
215 dst_row += dst_stride/sizeof(*dst_row);
216 src_row += src_stride/sizeof(*src_row);
217 }
218 }
219
220
221 void
222 util_format_r8g8_b8g8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
223 const uint8_t *src_row, unsigned src_stride,
224 unsigned width, unsigned height)
225 {
226 unsigned x, y;
227
228 for (y = 0; y < height; y += 1) {
229 const uint8_t *src = src_row;
230 uint32_t *dst = (uint32_t *)dst_row;
231 uint32_t r, g0, g1, b;
232 uint32_t value;
233
234 for (x = 0; x + 1 < width; x += 2) {
235 r = (src[0] + src[4] + 1) >> 1;
236 g0 = src[1];
237 g1 = src[5];
238 b = (src[2] + src[6] + 1) >> 1;
239
240 value = r;
241 value |= g0 << 8;
242 value |= b << 16;
243 value |= g1 << 24;
244
245 #ifdef PIPE_ARCH_BIG_ENDIAN
246 value = util_bswap32(value);
247 #endif
248
249 *dst++ = value;
250
251 src += 8;
252 }
253
254 if (x < width) {
255 r = src[0];
256 g0 = src[1];
257 g1 = 0;
258 b = src[2];
259
260 value = r;
261 value |= g0 << 8;
262 value |= b << 16;
263 value |= g1 << 24;
264
265 #ifdef PIPE_ARCH_BIG_ENDIAN
266 value = util_bswap32(value);
267 #endif
268
269 *dst = value;
270 }
271
272 dst_row += dst_stride/sizeof(*dst_row);
273 src_row += src_stride/sizeof(*src_row);
274 }
275 }
276
277
278 void
279 util_format_r8g8_b8g8_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
280 unsigned i, unsigned j)
281 {
282 assert(i < 2);
283 assert(j < 1);
284
285 dst[0] = ubyte_to_float(src[0]); /* r */
286 dst[1] = ubyte_to_float(src[1 + 2*i]); /* g */
287 dst[2] = ubyte_to_float(src[2]); /* b */
288 dst[3] = 1.0f; /* a */
289 }
290
291
292 void
293 util_format_g8r8_g8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
294 const uint8_t *src_row, unsigned src_stride,
295 unsigned width, unsigned height)
296 {
297 unsigned x, y;
298
299 for (y = 0; y < height; y += 1) {
300 float *dst = dst_row;
301 const uint32_t *src = (const uint32_t *)src_row;
302 uint32_t value;
303 float r, g0, g1, b;
304
305 for (x = 0; x + 1 < width; x += 2) {
306 value = *src++;
307
308 #ifdef PIPE_ARCH_BIG_ENDIAN
309 value = util_bswap32(value);
310 #endif
311
312 g0 = ubyte_to_float((value >> 0) & 0xff);
313 r = ubyte_to_float((value >> 8) & 0xff);
314 g1 = ubyte_to_float((value >> 16) & 0xff);
315 b = ubyte_to_float((value >> 24) & 0xff);
316
317 dst[0] = r; /* r */
318 dst[1] = g0; /* g */
319 dst[2] = b; /* b */
320 dst[3] = 1.0f; /* a */
321 dst += 4;
322
323 dst[0] = r; /* r */
324 dst[1] = g1; /* g */
325 dst[2] = b; /* b */
326 dst[3] = 1.0f; /* a */
327 dst += 4;
328 }
329
330 if (x < width) {
331 value = *src;
332
333 #ifdef PIPE_ARCH_BIG_ENDIAN
334 value = util_bswap32(value);
335 #endif
336
337 g0 = ubyte_to_float((value >> 0) & 0xff);
338 r = ubyte_to_float((value >> 8) & 0xff);
339 g1 = ubyte_to_float((value >> 16) & 0xff);
340 b = ubyte_to_float((value >> 24) & 0xff);
341
342 dst[0] = r; /* r */
343 dst[1] = g0; /* g */
344 dst[2] = b; /* b */
345 dst[3] = 1.0f; /* a */
346 }
347
348 src_row += src_stride/sizeof(*src_row);
349 dst_row += dst_stride/sizeof(*dst_row);
350 }
351 }
352
353
354 void
355 util_format_g8r8_g8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
356 const uint8_t *src_row, unsigned src_stride,
357 unsigned width, unsigned height)
358 {
359 unsigned x, y;
360
361 for (y = 0; y < height; y += 1) {
362 uint8_t *dst = dst_row;
363 const uint32_t *src = (const uint32_t *)src_row;
364 uint32_t value;
365 uint8_t r, g0, g1, b;
366
367 for (x = 0; x + 1 < width; x += 2) {
368 value = *src++;
369
370 #ifdef PIPE_ARCH_BIG_ENDIAN
371 value = util_bswap32(value);
372 #endif
373
374 g0 = (value >> 0) & 0xff;
375 r = (value >> 8) & 0xff;
376 g1 = (value >> 16) & 0xff;
377 b = (value >> 24) & 0xff;
378
379 dst[0] = r; /* r */
380 dst[1] = g0; /* g */
381 dst[2] = b; /* b */
382 dst[3] = 0xff; /* a */
383 dst += 4;
384
385 dst[0] = r; /* r */
386 dst[1] = g1; /* g */
387 dst[2] = b; /* b */
388 dst[3] = 0xff; /* a */
389 dst += 4;
390 }
391
392 if (x < width) {
393 value = *src;
394
395 #ifdef PIPE_ARCH_BIG_ENDIAN
396 value = util_bswap32(value);
397 #endif
398
399 g0 = (value >> 0) & 0xff;
400 r = (value >> 8) & 0xff;
401 g1 = (value >> 16) & 0xff;
402 b = (value >> 24) & 0xff;
403
404 dst[0] = r; /* r */
405 dst[1] = g0; /* g */
406 dst[2] = b; /* b */
407 dst[3] = 0xff; /* a */
408 }
409
410 src_row += src_stride/sizeof(*src_row);
411 dst_row += dst_stride/sizeof(*dst_row);
412 }
413 }
414
415
416 void
417 util_format_g8r8_g8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
418 const float *src_row, unsigned src_stride,
419 unsigned width, unsigned height)
420 {
421 unsigned x, y;
422
423 for (y = 0; y < height; y += 1) {
424 const float *src = src_row;
425 uint32_t *dst = (uint32_t *)dst_row;
426 float r, g0, g1, b;
427 uint32_t value;
428
429 for (x = 0; x + 1 < width; x += 2) {
430 r = 0.5f*(src[0] + src[4]);
431 g0 = src[1];
432 g1 = src[5];
433 b = 0.5f*(src[2] + src[6]);
434
435 value = float_to_ubyte(g0);
436 value |= float_to_ubyte(r) << 8;
437 value |= float_to_ubyte(g1) << 16;
438 value |= float_to_ubyte(b) << 24;
439
440 #ifdef PIPE_ARCH_BIG_ENDIAN
441 value = util_bswap32(value);
442 #endif
443
444 *dst++ = value;
445
446 src += 8;
447 }
448
449 if (x < width) {
450 r = src[0];
451 g0 = src[1];
452 g1 = 0;
453 b = src[2];
454
455 value = float_to_ubyte(g0);
456 value |= float_to_ubyte(r) << 8;
457 value |= float_to_ubyte(g1) << 16;
458 value |= float_to_ubyte(b) << 24;
459
460 #ifdef PIPE_ARCH_BIG_ENDIAN
461 value = util_bswap32(value);
462 #endif
463
464 *dst = value;
465 }
466
467 dst_row += dst_stride/sizeof(*dst_row);
468 src_row += src_stride/sizeof(*src_row);
469 }
470 }
471
472
473 void
474 util_format_g8r8_g8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
475 const uint8_t *src_row, unsigned src_stride,
476 unsigned width, unsigned height)
477 {
478 unsigned x, y;
479
480 for (y = 0; y < height; y += 1) {
481 const uint8_t *src = src_row;
482 uint32_t *dst = (uint32_t *)dst_row;
483 uint32_t r, g0, g1, b;
484 uint32_t value;
485
486 for (x = 0; x + 1 < width; x += 2) {
487 r = (src[0] + src[4] + 1) >> 1;
488 g0 = src[1];
489 g1 = src[5];
490 b = (src[2] + src[6] + 1) >> 1;
491
492 value = g0;
493 value |= r << 8;
494 value |= g1 << 16;
495 value |= b << 24;
496
497 #ifdef PIPE_ARCH_BIG_ENDIAN
498 value = util_bswap32(value);
499 #endif
500
501 *dst++ = value;
502
503 src += 8;
504 }
505
506 if (x < width) {
507 r = src[0];
508 g0 = src[1];
509 g1 = 0;
510 b = src[2];
511
512 value = g0;
513 value |= r << 8;
514 value |= g1 << 16;
515 value |= b << 24;
516
517 #ifdef PIPE_ARCH_BIG_ENDIAN
518 value = util_bswap32(value);
519 #endif
520
521 *dst = value;
522 }
523
524 dst_row += dst_stride/sizeof(*dst_row);
525 src_row += src_stride/sizeof(*src_row);
526 }
527 }
528
529
530 void
531 util_format_g8r8_g8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
532 unsigned i, unsigned j)
533 {
534 assert(i < 2);
535 assert(j < 1);
536
537 dst[0] = ubyte_to_float(src[1]); /* r */
538 dst[1] = ubyte_to_float(src[0 + 2*i]); /* g */
539 dst[2] = ubyte_to_float(src[3]); /* b */
540 dst[3] = 1.0f; /* a */
541 }
542
543
544 void
545 util_format_uyvy_unpack_rgba_float(float *dst_row, unsigned dst_stride,
546 const uint8_t *src_row, unsigned src_stride,
547 unsigned width, unsigned height)
548 {
549 unsigned x, y;
550
551 for (y = 0; y < height; y += 1) {
552 float *dst = dst_row;
553 const uint32_t *src = (const uint32_t *)src_row;
554 uint32_t value;
555 uint8_t y0, y1, u, v;
556
557 for (x = 0; x + 1 < width; x += 2) {
558 value = *src++;
559
560 #ifdef PIPE_ARCH_BIG_ENDIAN
561 value = util_bswap32(value);
562 #endif
563
564 u = (value >> 0) & 0xff;
565 y0 = (value >> 8) & 0xff;
566 v = (value >> 16) & 0xff;
567 y1 = (value >> 24) & 0xff;
568
569 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
570 dst[3] = 1.0f; /* a */
571 dst += 4;
572
573 util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]);
574 dst[3] = 1.0f; /* a */
575 dst += 4;
576 }
577
578 if (x < width) {
579 value = *src;
580
581 #ifdef PIPE_ARCH_BIG_ENDIAN
582 value = util_bswap32(value);
583 #endif
584
585 u = (value >> 0) & 0xff;
586 y0 = (value >> 8) & 0xff;
587 v = (value >> 16) & 0xff;
588 y1 = (value >> 24) & 0xff;
589
590 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
591 dst[3] = 1.0f; /* a */
592 }
593
594 src_row += src_stride/sizeof(*src_row);
595 dst_row += dst_stride/sizeof(*dst_row);
596 }
597 }
598
599
600 void
601 util_format_uyvy_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
602 const uint8_t *src_row, unsigned src_stride,
603 unsigned width, unsigned height)
604 {
605 unsigned x, y;
606
607 for (y = 0; y < height; y += 1) {
608 uint8_t *dst = dst_row;
609 const uint32_t *src = (const uint32_t *)src_row;
610 uint32_t value;
611 uint8_t y0, y1, u, v;
612
613 for (x = 0; x + 1 < width; x += 2) {
614 value = *src++;
615
616 #ifdef PIPE_ARCH_BIG_ENDIAN
617 value = util_bswap32(value);
618 #endif
619
620 u = (value >> 0) & 0xff;
621 y0 = (value >> 8) & 0xff;
622 v = (value >> 16) & 0xff;
623 y1 = (value >> 24) & 0xff;
624
625 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
626 dst[3] = 0xff; /* a */
627 dst += 4;
628
629 util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]);
630 dst[3] = 0xff; /* a */
631 dst += 4;
632 }
633
634 if (x < width) {
635 value = *src;
636
637 #ifdef PIPE_ARCH_BIG_ENDIAN
638 value = util_bswap32(value);
639 #endif
640
641 u = (value >> 0) & 0xff;
642 y0 = (value >> 8) & 0xff;
643 v = (value >> 16) & 0xff;
644 y1 = (value >> 24) & 0xff;
645
646 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
647 dst[3] = 0xff; /* a */
648 }
649
650 src_row += src_stride/sizeof(*src_row);
651 dst_row += dst_stride/sizeof(*dst_row);
652 }
653 }
654
655
656 void
657 util_format_uyvy_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
658 const float *src_row, unsigned src_stride,
659 unsigned width, unsigned height)
660 {
661 unsigned x, y;
662
663 for (y = 0; y < height; y += 1) {
664 const float *src = src_row;
665 uint32_t *dst = (uint32_t *)dst_row;
666 uint8_t y0, y1, u, v;
667 uint32_t value;
668
669 for (x = 0; x + 1 < width; x += 2) {
670 uint8_t y0, y1, u0, u1, v0, v1, u, v;
671
672 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
673 &y0, &u0, &v0);
674 util_format_rgb_float_to_yuv(src[4], src[5], src[6],
675 &y1, &u1, &v1);
676
677 u = (u0 + u1 + 1) >> 1;
678 v = (v0 + v1 + 1) >> 1;
679
680 value = u;
681 value |= y0 << 8;
682 value |= v << 16;
683 value |= y1 << 24;
684
685 #ifdef PIPE_ARCH_BIG_ENDIAN
686 value = util_bswap32(value);
687 #endif
688
689 *dst++ = value;
690
691 src += 8;
692 }
693
694 if (x < width) {
695 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
696 &y0, &u, &v);
697 y1 = 0;
698
699 value = u;
700 value |= y0 << 8;
701 value |= v << 16;
702 value |= y1 << 24;
703
704 #ifdef PIPE_ARCH_BIG_ENDIAN
705 value = util_bswap32(value);
706 #endif
707
708 *dst = value;
709 }
710
711 dst_row += dst_stride/sizeof(*dst_row);
712 src_row += src_stride/sizeof(*src_row);
713 }
714 }
715
716
717 void
718 util_format_uyvy_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
719 const uint8_t *src_row, unsigned src_stride,
720 unsigned width, unsigned height)
721 {
722 unsigned x, y;
723
724 for (y = 0; y < height; y += 1) {
725 const uint8_t *src = src_row;
726 uint32_t *dst = (uint32_t *)dst_row;
727 uint8_t y0, y1, u, v;
728 uint32_t value;
729
730 for (x = 0; x + 1 < width; x += 2) {
731 uint8_t y0, y1, u0, u1, v0, v1, u, v;
732
733 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
734 &y0, &u0, &v0);
735 util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6],
736 &y1, &u1, &v1);
737
738 u = (u0 + u1 + 1) >> 1;
739 v = (v0 + v1 + 1) >> 1;
740
741 value = u;
742 value |= y0 << 8;
743 value |= v << 16;
744 value |= y1 << 24;
745
746 #ifdef PIPE_ARCH_BIG_ENDIAN
747 value = util_bswap32(value);
748 #endif
749
750 *dst++ = value;
751
752 src += 8;
753 }
754
755 if (x < width) {
756 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
757 &y0, &u, &v);
758 y1 = 0;
759
760 value = u;
761 value |= y0 << 8;
762 value |= v << 16;
763 value |= y1 << 24;
764
765 #ifdef PIPE_ARCH_BIG_ENDIAN
766 value = util_bswap32(value);
767 #endif
768
769 *dst = value;
770 }
771
772 dst_row += dst_stride/sizeof(*dst_row);
773 src_row += src_stride/sizeof(*src_row);
774 }
775 }
776
777
778 void
779 util_format_uyvy_fetch_rgba_float(float *dst, const uint8_t *src,
780 unsigned i, unsigned j)
781 {
782 uint8_t y, u, v;
783
784 assert(i < 2);
785 assert(j < 1);
786
787 y = src[1 + i*2];
788 u = src[0];
789 v = src[2];
790
791 util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]);
792
793 dst[3] = 1.0f;
794 }
795
796
797 void
798 util_format_yuyv_unpack_rgba_float(float *dst_row, unsigned dst_stride,
799 const uint8_t *src_row, unsigned src_stride,
800 unsigned width, unsigned height)
801 {
802 unsigned x, y;
803
804 for (y = 0; y < height; y += 1) {
805 float *dst = dst_row;
806 const uint32_t *src = (const uint32_t *)src_row;
807 uint32_t value;
808 uint8_t y0, y1, u, v;
809
810 for (x = 0; x + 1 < width; x += 2) {
811 value = *src++;
812
813 #ifdef PIPE_ARCH_BIG_ENDIAN
814 value = util_bswap32(value);
815 #endif
816
817 y0 = (value >> 0) & 0xff;
818 u = (value >> 8) & 0xff;
819 y1 = (value >> 16) & 0xff;
820 v = (value >> 24) & 0xff;
821
822 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
823 dst[3] = 1.0f; /* a */
824 dst += 4;
825
826 util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]);
827 dst[3] = 1.0f; /* a */
828 dst += 4;
829 }
830
831 if (x < width) {
832 value = *src;
833
834 #ifdef PIPE_ARCH_BIG_ENDIAN
835 value = util_bswap32(value);
836 #endif
837
838 y0 = (value >> 0) & 0xff;
839 u = (value >> 8) & 0xff;
840 y1 = (value >> 16) & 0xff;
841 v = (value >> 24) & 0xff;
842
843 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
844 dst[3] = 1.0f; /* a */
845 }
846
847 src_row += src_stride/sizeof(*src_row);
848 dst_row += dst_stride/sizeof(*dst_row);
849 }
850 }
851
852
853 void
854 util_format_yuyv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
855 const uint8_t *src_row, unsigned src_stride,
856 unsigned width, unsigned height)
857 {
858 unsigned x, y;
859
860 for (y = 0; y < height; y += 1) {
861 uint8_t *dst = dst_row;
862 const uint32_t *src = (const uint32_t *)src_row;
863 uint32_t value;
864 uint8_t y0, y1, u, v;
865
866 for (x = 0; x + 1 < width; x += 2) {
867 value = *src++;
868
869 #ifdef PIPE_ARCH_BIG_ENDIAN
870 value = util_bswap32(value);
871 #endif
872
873 y0 = (value >> 0) & 0xff;
874 u = (value >> 8) & 0xff;
875 y1 = (value >> 16) & 0xff;
876 v = (value >> 24) & 0xff;
877
878 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
879 dst[3] = 0xff; /* a */
880 dst += 4;
881
882 util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]);
883 dst[3] = 0xff; /* a */
884 dst += 4;
885 }
886
887 if (x < width) {
888 value = *src;
889
890 #ifdef PIPE_ARCH_BIG_ENDIAN
891 value = util_bswap32(value);
892 #endif
893
894 y0 = (value >> 0) & 0xff;
895 u = (value >> 8) & 0xff;
896 y1 = (value >> 16) & 0xff;
897 v = (value >> 24) & 0xff;
898
899 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
900 dst[3] = 0xff; /* a */
901 }
902
903 src_row += src_stride/sizeof(*src_row);
904 dst_row += dst_stride/sizeof(*dst_row);
905 }
906 }
907
908
909 void
910 util_format_yuyv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
911 const float *src_row, unsigned src_stride,
912 unsigned width, unsigned height)
913 {
914 unsigned x, y;
915
916 for (y = 0; y < height; y += 1) {
917 const float *src = src_row;
918 uint32_t *dst = (uint32_t *)dst_row;
919 uint8_t y0, y1, u, v;
920 uint32_t value;
921
922 for (x = 0; x + 1 < width; x += 2) {
923 uint8_t y0, y1, u0, u1, v0, v1, u, v;
924
925 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
926 &y0, &u0, &v0);
927 util_format_rgb_float_to_yuv(src[4], src[5], src[6],
928 &y1, &u1, &v1);
929
930 u = (u0 + u1 + 1) >> 1;
931 v = (v0 + v1 + 1) >> 1;
932
933 value = y0;
934 value |= u << 8;
935 value |= y1 << 16;
936 value |= v << 24;
937
938 #ifdef PIPE_ARCH_BIG_ENDIAN
939 value = util_bswap32(value);
940 #endif
941
942 *dst++ = value;
943
944 src += 8;
945 }
946
947 if (x < width) {
948 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
949 &y0, &u, &v);
950 y1 = 0;
951
952 value = y0;
953 value |= u << 8;
954 value |= y1 << 16;
955 value |= v << 24;
956
957 #ifdef PIPE_ARCH_BIG_ENDIAN
958 value = util_bswap32(value);
959 #endif
960
961 *dst = value;
962 }
963
964 dst_row += dst_stride/sizeof(*dst_row);
965 src_row += src_stride/sizeof(*src_row);
966 }
967 }
968
969
970 void
971 util_format_yuyv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
972 const uint8_t *src_row, unsigned src_stride,
973 unsigned width, unsigned height)
974 {
975 unsigned x, y;
976
977 for (y = 0; y < height; y += 1) {
978 const uint8_t *src = src_row;
979 uint32_t *dst = (uint32_t *)dst_row;
980 uint8_t y0, y1, u, v;
981 uint32_t value;
982
983 for (x = 0; x + 1 < width; x += 2) {
984 uint8_t y0, y1, u0, u1, v0, v1, u, v;
985
986 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
987 &y0, &u0, &v0);
988 util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6],
989 &y1, &u1, &v1);
990
991 u = (u0 + u1 + 1) >> 1;
992 v = (v0 + v1 + 1) >> 1;
993
994 value = y0;
995 value |= u << 8;
996 value |= y1 << 16;
997 value |= v << 24;
998
999 #ifdef PIPE_ARCH_BIG_ENDIAN
1000 value = util_bswap32(value);
1001 #endif
1002
1003 *dst++ = value;
1004
1005 src += 8;
1006 }
1007
1008 if (x < width) {
1009 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
1010 &y0, &u, &v);
1011 y1 = 0;
1012
1013 value = y0;
1014 value |= u << 8;
1015 value |= y1 << 16;
1016 value |= v << 24;
1017
1018 #ifdef PIPE_ARCH_BIG_ENDIAN
1019 value = util_bswap32(value);
1020 #endif
1021
1022 *dst = value;
1023 }
1024
1025 dst_row += dst_stride/sizeof(*dst_row);
1026 src_row += src_stride/sizeof(*src_row);
1027 }
1028 }
1029
1030
1031 void
1032 util_format_yuyv_fetch_rgba_float(float *dst, const uint8_t *src,
1033 unsigned i, unsigned j)
1034 {
1035 uint8_t y, u, v;
1036
1037 assert(i < 2);
1038 assert(j < 1);
1039
1040 y = src[0 + i*2];
1041 u = src[1];
1042 v = src[3];
1043
1044 util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]);
1045
1046 dst[3] = 1.0f;
1047 }