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_debug.h"
38 #include "util/format/u_format_yuv.h"
39
40
41 void
util_format_r8g8_b8g8_unorm_unpack_rgba_float(void * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)42 util_format_r8g8_b8g8_unorm_unpack_rgba_float(void *dst_row, unsigned dst_stride,
43 const uint8_t *src_row, unsigned src_stride,
44 unsigned width, unsigned height)
45 {
46 unsigned x, y;
47
48 for (y = 0; y < height; y += 1) {
49 float *dst = dst_row;
50 const uint32_t *src = (const uint32_t *)src_row;
51 uint32_t value;
52 float r, g0, g1, b;
53
54 for (x = 0; x + 1 < width; x += 2) {
55 value = util_cpu_to_le32(*src++);
56
57 r = ubyte_to_float((value >> 0) & 0xff);
58 g0 = ubyte_to_float((value >> 8) & 0xff);
59 b = ubyte_to_float((value >> 16) & 0xff);
60 g1 = ubyte_to_float((value >> 24) & 0xff);
61
62 dst[0] = r; /* r */
63 dst[1] = g0; /* g */
64 dst[2] = b; /* b */
65 dst[3] = 1.0f; /* a */
66 dst += 4;
67
68 dst[0] = r; /* r */
69 dst[1] = g1; /* g */
70 dst[2] = b; /* b */
71 dst[3] = 1.0f; /* a */
72 dst += 4;
73 }
74
75 if (x < width) {
76 value = util_cpu_to_le32(*src);
77
78 r = ubyte_to_float((value >> 0) & 0xff);
79 g0 = ubyte_to_float((value >> 8) & 0xff);
80 b = ubyte_to_float((value >> 16) & 0xff);
81 g1 = ubyte_to_float((value >> 24) & 0xff);
82
83 dst[0] = r; /* r */
84 dst[1] = g0; /* g */
85 dst[2] = b; /* b */
86 dst[3] = 1.0f; /* a */
87 }
88
89 src_row = (uint8_t *)src_row + src_stride;
90 dst_row = (uint8_t *)dst_row + dst_stride;
91 }
92 }
93
94
95 void
util_format_r8g8_b8g8_unorm_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)96 util_format_r8g8_b8g8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
97 const uint8_t *src_row, unsigned src_stride,
98 unsigned width, unsigned height)
99 {
100 unsigned x, y;
101
102 for (y = 0; y < height; y += 1) {
103 uint8_t *dst = dst_row;
104 const uint32_t *src = (const uint32_t *)src_row;
105 uint32_t value;
106 uint8_t r, g0, g1, b;
107
108 for (x = 0; x + 1 < width; x += 2) {
109 value = util_cpu_to_le32(*src++);
110
111 r = (value >> 0) & 0xff;
112 g0 = (value >> 8) & 0xff;
113 b = (value >> 16) & 0xff;
114 g1 = (value >> 24) & 0xff;
115
116 dst[0] = r; /* r */
117 dst[1] = g0; /* g */
118 dst[2] = b; /* b */
119 dst[3] = 0xff; /* a */
120 dst += 4;
121
122 dst[0] = r; /* r */
123 dst[1] = g1; /* g */
124 dst[2] = b; /* b */
125 dst[3] = 0xff; /* a */
126 dst += 4;
127 }
128
129 if (x < width) {
130 value = util_cpu_to_le32(*src);
131
132 r = (value >> 0) & 0xff;
133 g0 = (value >> 8) & 0xff;
134 b = (value >> 16) & 0xff;
135 g1 = (value >> 24) & 0xff;
136
137 dst[0] = r; /* r */
138 dst[1] = g0; /* g */
139 dst[2] = b; /* b */
140 dst[3] = 0xff; /* a */
141 }
142
143 src_row += src_stride/sizeof(*src_row);
144 dst_row += dst_stride/sizeof(*dst_row);
145 }
146 }
147
148
149 void
util_format_r8g8_b8g8_unorm_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)150 util_format_r8g8_b8g8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
151 const float *src_row, unsigned src_stride,
152 unsigned width, unsigned height)
153 {
154 unsigned x, y;
155
156 for (y = 0; y < height; y += 1) {
157 const float *src = src_row;
158 uint32_t *dst = (uint32_t *)dst_row;
159 float r, g0, g1, b;
160 uint32_t value;
161
162 for (x = 0; x + 1 < width; x += 2) {
163 r = 0.5f*(src[0] + src[4]);
164 g0 = src[1];
165 g1 = src[5];
166 b = 0.5f*(src[2] + src[6]);
167
168 value = (uint32_t)float_to_ubyte(r);
169 value |= (uint32_t)float_to_ubyte(g0) << 8;
170 value |= (uint32_t)float_to_ubyte(b) << 16;
171 value |= (uint32_t)float_to_ubyte(g1) << 24;
172
173 *dst++ = util_le32_to_cpu(value);
174
175 src += 8;
176 }
177
178 if (x < width) {
179 r = src[0];
180 g0 = src[1];
181 g1 = 0;
182 b = src[2];
183
184 value = (uint32_t)float_to_ubyte(r);
185 value |= (uint32_t)float_to_ubyte(g0) << 8;
186 value |= (uint32_t)float_to_ubyte(b) << 16;
187 value |= (uint32_t)float_to_ubyte(g1) << 24;
188
189 *dst = util_le32_to_cpu(value);
190 }
191
192 dst_row += dst_stride/sizeof(*dst_row);
193 src_row += src_stride/sizeof(*src_row);
194 }
195 }
196
197
198 void
util_format_r8g8_b8g8_unorm_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)199 util_format_r8g8_b8g8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
200 const uint8_t *src_row, unsigned src_stride,
201 unsigned width, unsigned height)
202 {
203 unsigned x, y;
204
205 for (y = 0; y < height; y += 1) {
206 const uint8_t *src = src_row;
207 uint32_t *dst = (uint32_t *)dst_row;
208 uint32_t r, g0, g1, b;
209 uint32_t value;
210
211 for (x = 0; x + 1 < width; x += 2) {
212 r = (src[0] + src[4] + 1) >> 1;
213 g0 = src[1];
214 g1 = src[5];
215 b = (src[2] + src[6] + 1) >> 1;
216
217 value = r;
218 value |= (uint32_t)g0 << 8;
219 value |= (uint32_t)b << 16;
220 value |= (uint32_t)g1 << 24;
221
222 *dst++ = util_le32_to_cpu(value);
223
224 src += 8;
225 }
226
227 if (x < width) {
228 r = src[0];
229 g0 = src[1];
230 g1 = 0;
231 b = src[2];
232
233 value = r;
234 value |= (uint32_t)g0 << 8;
235 value |= (uint32_t)b << 16;
236 value |= (uint32_t)g1 << 24;
237
238 *dst = util_le32_to_cpu(value);
239 }
240
241 dst_row += dst_stride/sizeof(*dst_row);
242 src_row += src_stride/sizeof(*src_row);
243 }
244 }
245
246
247 void
util_format_r8g8_b8g8_unorm_fetch_rgba(void * in_dst,const uint8_t * src,unsigned i,ASSERTED unsigned j)248 util_format_r8g8_b8g8_unorm_fetch_rgba(void *in_dst, const uint8_t *src,
249 unsigned i, ASSERTED unsigned j)
250 {
251 float *dst = in_dst;
252
253 assert(i < 2);
254 assert(j < 1);
255
256 dst[0] = ubyte_to_float(src[0]); /* r */
257 dst[1] = ubyte_to_float(src[1 + 2*i]); /* g */
258 dst[2] = ubyte_to_float(src[2]); /* b */
259 dst[3] = 1.0f; /* a */
260 }
261
262
263 void
util_format_g8r8_g8b8_unorm_unpack_rgba_float(void * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)264 util_format_g8r8_g8b8_unorm_unpack_rgba_float(void *dst_row, unsigned dst_stride,
265 const uint8_t *src_row, unsigned src_stride,
266 unsigned width, unsigned height)
267 {
268 unsigned x, y;
269
270 for (y = 0; y < height; y += 1) {
271 float *dst = dst_row;
272 const uint32_t *src = (const uint32_t *)src_row;
273 uint32_t value;
274 float r, g0, g1, b;
275
276 for (x = 0; x + 1 < width; x += 2) {
277 value = util_cpu_to_le32(*src++);
278
279 g0 = ubyte_to_float((value >> 0) & 0xff);
280 r = ubyte_to_float((value >> 8) & 0xff);
281 g1 = ubyte_to_float((value >> 16) & 0xff);
282 b = ubyte_to_float((value >> 24) & 0xff);
283
284 dst[0] = r; /* r */
285 dst[1] = g0; /* g */
286 dst[2] = b; /* b */
287 dst[3] = 1.0f; /* a */
288 dst += 4;
289
290 dst[0] = r; /* r */
291 dst[1] = g1; /* g */
292 dst[2] = b; /* b */
293 dst[3] = 1.0f; /* a */
294 dst += 4;
295 }
296
297 if (x < width) {
298 value = util_cpu_to_le32(*src);
299
300 g0 = ubyte_to_float((value >> 0) & 0xff);
301 r = ubyte_to_float((value >> 8) & 0xff);
302 g1 = ubyte_to_float((value >> 16) & 0xff);
303 b = ubyte_to_float((value >> 24) & 0xff);
304
305 dst[0] = r; /* r */
306 dst[1] = g0; /* g */
307 dst[2] = b; /* b */
308 dst[3] = 1.0f; /* a */
309 }
310
311 src_row = (uint8_t *)src_row + src_stride;
312 dst_row = (uint8_t *)dst_row + dst_stride;
313 }
314 }
315
316
317 void
util_format_g8r8_g8b8_unorm_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)318 util_format_g8r8_g8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
319 const uint8_t *src_row, unsigned src_stride,
320 unsigned width, unsigned height)
321 {
322 unsigned x, y;
323
324 for (y = 0; y < height; y += 1) {
325 uint8_t *dst = dst_row;
326 const uint32_t *src = (const uint32_t *)src_row;
327 uint32_t value;
328 uint8_t r, g0, g1, b;
329
330 for (x = 0; x + 1 < width; x += 2) {
331 value = util_cpu_to_le32(*src++);
332
333 g0 = (value >> 0) & 0xff;
334 r = (value >> 8) & 0xff;
335 g1 = (value >> 16) & 0xff;
336 b = (value >> 24) & 0xff;
337
338 dst[0] = r; /* r */
339 dst[1] = g0; /* g */
340 dst[2] = b; /* b */
341 dst[3] = 0xff; /* a */
342 dst += 4;
343
344 dst[0] = r; /* r */
345 dst[1] = g1; /* g */
346 dst[2] = b; /* b */
347 dst[3] = 0xff; /* a */
348 dst += 4;
349 }
350
351 if (x < width) {
352 value = util_cpu_to_le32(*src);
353
354 g0 = (value >> 0) & 0xff;
355 r = (value >> 8) & 0xff;
356 g1 = (value >> 16) & 0xff;
357 b = (value >> 24) & 0xff;
358
359 dst[0] = r; /* r */
360 dst[1] = g0; /* g */
361 dst[2] = b; /* b */
362 dst[3] = 0xff; /* a */
363 }
364
365 src_row += src_stride/sizeof(*src_row);
366 dst_row += dst_stride/sizeof(*dst_row);
367 }
368 }
369
370
371 void
util_format_g8r8_g8b8_unorm_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)372 util_format_g8r8_g8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
373 const float *src_row, unsigned src_stride,
374 unsigned width, unsigned height)
375 {
376 unsigned x, y;
377
378 for (y = 0; y < height; y += 1) {
379 const float *src = src_row;
380 uint32_t *dst = (uint32_t *)dst_row;
381 float r, g0, g1, b;
382 uint32_t value;
383
384 for (x = 0; x + 1 < width; x += 2) {
385 r = 0.5f*(src[0] + src[4]);
386 g0 = src[1];
387 g1 = src[5];
388 b = 0.5f*(src[2] + src[6]);
389
390 value = (uint32_t)float_to_ubyte(g0);
391 value |= (uint32_t)float_to_ubyte(r) << 8;
392 value |= (uint32_t)float_to_ubyte(g1) << 16;
393 value |= (uint32_t)float_to_ubyte(b) << 24;
394
395 *dst++ = util_le32_to_cpu(value);
396
397 src += 8;
398 }
399
400 if (x < width) {
401 r = src[0];
402 g0 = src[1];
403 g1 = 0;
404 b = src[2];
405
406 value = (uint32_t)float_to_ubyte(g0);
407 value |= (uint32_t)float_to_ubyte(r) << 8;
408 value |= (uint32_t)float_to_ubyte(g1) << 16;
409 value |= (uint32_t)float_to_ubyte(b) << 24;
410
411 *dst = util_le32_to_cpu(value);
412 }
413
414 dst_row += dst_stride/sizeof(*dst_row);
415 src_row += src_stride/sizeof(*src_row);
416 }
417 }
418
419
420 void
util_format_g8r8_g8b8_unorm_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)421 util_format_g8r8_g8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
422 const uint8_t *src_row, unsigned src_stride,
423 unsigned width, unsigned height)
424 {
425 unsigned x, y;
426
427 for (y = 0; y < height; y += 1) {
428 const uint8_t *src = src_row;
429 uint32_t *dst = (uint32_t *)dst_row;
430 uint32_t r, g0, g1, b;
431 uint32_t value;
432
433 for (x = 0; x + 1 < width; x += 2) {
434 r = (src[0] + src[4] + 1) >> 1;
435 g0 = src[1];
436 g1 = src[5];
437 b = (src[2] + src[6] + 1) >> 1;
438
439 value = g0;
440 value |= (uint32_t)r << 8;
441 value |= (uint32_t)g1 << 16;
442 value |= (uint32_t)b << 24;
443
444 *dst++ = util_le32_to_cpu(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 = g0;
456 value |= (uint32_t)r << 8;
457 value |= (uint32_t)g1 << 16;
458 value |= (uint32_t)b << 24;
459
460 *dst = util_le32_to_cpu(value);
461 }
462
463 dst_row += dst_stride/sizeof(*dst_row);
464 src_row += src_stride/sizeof(*src_row);
465 }
466 }
467
468
469 void
util_format_g8r8_g8b8_unorm_fetch_rgba(void * in_dst,const uint8_t * src,unsigned i,ASSERTED unsigned j)470 util_format_g8r8_g8b8_unorm_fetch_rgba(void *in_dst, const uint8_t *src,
471 unsigned i, ASSERTED unsigned j)
472 {
473 float *dst = in_dst;
474
475 assert(i < 2);
476 assert(j < 1);
477
478 dst[0] = ubyte_to_float(src[1]); /* r */
479 dst[1] = ubyte_to_float(src[0 + 2*i]); /* g */
480 dst[2] = ubyte_to_float(src[3]); /* b */
481 dst[3] = 1.0f; /* a */
482 }
483
484
485 void
util_format_uyvy_unpack_rgba_float(void * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)486 util_format_uyvy_unpack_rgba_float(void *dst_row, unsigned dst_stride,
487 const uint8_t *src_row, unsigned src_stride,
488 unsigned width, unsigned height)
489 {
490 unsigned x, y;
491
492 for (y = 0; y < height; y += 1) {
493 float *dst = dst_row;
494 const uint32_t *src = (const uint32_t *)src_row;
495 uint32_t value;
496 uint8_t y0, y1, u, v;
497
498 for (x = 0; x + 1 < width; x += 2) {
499 value = util_cpu_to_le32(*src++);
500
501 u = (value >> 0) & 0xff;
502 y0 = (value >> 8) & 0xff;
503 v = (value >> 16) & 0xff;
504 y1 = (value >> 24) & 0xff;
505
506 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
507 dst[3] = 1.0f; /* a */
508 dst += 4;
509
510 util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]);
511 dst[3] = 1.0f; /* a */
512 dst += 4;
513 }
514
515 if (x < width) {
516 value = util_cpu_to_le32(*src);
517
518 u = (value >> 0) & 0xff;
519 y0 = (value >> 8) & 0xff;
520 v = (value >> 16) & 0xff;
521 y1 = (value >> 24) & 0xff;
522
523 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
524 dst[3] = 1.0f; /* a */
525 }
526
527 src_row = (uint8_t *)src_row + src_stride;
528 dst_row = (uint8_t *)dst_row + dst_stride;
529 }
530 }
531
532
533 void
util_format_uyvy_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)534 util_format_uyvy_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
535 const uint8_t *src_row, unsigned src_stride,
536 unsigned width, unsigned height)
537 {
538 unsigned x, y;
539
540 for (y = 0; y < height; y += 1) {
541 uint8_t *dst = dst_row;
542 const uint32_t *src = (const uint32_t *)src_row;
543 uint32_t value;
544 uint8_t y0, y1, u, v;
545
546 for (x = 0; x + 1 < width; x += 2) {
547 value = util_cpu_to_le32(*src++);
548
549 u = (value >> 0) & 0xff;
550 y0 = (value >> 8) & 0xff;
551 v = (value >> 16) & 0xff;
552 y1 = (value >> 24) & 0xff;
553
554 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
555 dst[3] = 0xff; /* a */
556 dst += 4;
557
558 util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]);
559 dst[3] = 0xff; /* a */
560 dst += 4;
561 }
562
563 if (x < width) {
564 value = util_cpu_to_le32(*src);
565
566 u = (value >> 0) & 0xff;
567 y0 = (value >> 8) & 0xff;
568 v = (value >> 16) & 0xff;
569 y1 = (value >> 24) & 0xff;
570
571 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
572 dst[3] = 0xff; /* a */
573 }
574
575 src_row += src_stride/sizeof(*src_row);
576 dst_row += dst_stride/sizeof(*dst_row);
577 }
578 }
579
580
581 void
util_format_uyvy_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)582 util_format_uyvy_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
583 const float *src_row, unsigned src_stride,
584 unsigned width, unsigned height)
585 {
586 unsigned x, y;
587
588 for (y = 0; y < height; y += 1) {
589 const float *src = src_row;
590 uint32_t *dst = (uint32_t *)dst_row;
591 uint8_t y0, y1, u, v;
592 uint32_t value;
593
594 for (x = 0; x + 1 < width; x += 2) {
595 uint8_t y0, y1, u0, u1, v0, v1, u, v;
596
597 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
598 &y0, &u0, &v0);
599 util_format_rgb_float_to_yuv(src[4], src[5], src[6],
600 &y1, &u1, &v1);
601
602 u = (u0 + u1 + 1) >> 1;
603 v = (v0 + v1 + 1) >> 1;
604
605 value = u;
606 value |= (uint32_t)y0 << 8;
607 value |= (uint32_t)v << 16;
608 value |= (uint32_t)y1 << 24;
609
610 *dst++ = util_le32_to_cpu(value);
611
612 src += 8;
613 }
614
615 if (x < width) {
616 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
617 &y0, &u, &v);
618 y1 = 0;
619
620 value = u;
621 value |= (uint32_t)y0 << 8;
622 value |= (uint32_t)v << 16;
623 value |= (uint32_t)y1 << 24;
624
625 *dst = util_le32_to_cpu(value);
626 }
627
628 dst_row += dst_stride/sizeof(*dst_row);
629 src_row += src_stride/sizeof(*src_row);
630 }
631 }
632
633
634 void
util_format_uyvy_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)635 util_format_uyvy_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
636 const uint8_t *src_row, unsigned src_stride,
637 unsigned width, unsigned height)
638 {
639 unsigned x, y;
640
641 for (y = 0; y < height; y += 1) {
642 const uint8_t *src = src_row;
643 uint32_t *dst = (uint32_t *)dst_row;
644 uint8_t y0, y1, u, v;
645 uint32_t value;
646
647 for (x = 0; x + 1 < width; x += 2) {
648 uint8_t y0, y1, u0, u1, v0, v1, u, v;
649
650 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
651 &y0, &u0, &v0);
652 util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6],
653 &y1, &u1, &v1);
654
655 u = (u0 + u1 + 1) >> 1;
656 v = (v0 + v1 + 1) >> 1;
657
658 value = u;
659 value |= (uint32_t)y0 << 8;
660 value |= (uint32_t)v << 16;
661 value |= (uint32_t)y1 << 24;
662
663 *dst++ = util_le32_to_cpu(value);
664
665 src += 8;
666 }
667
668 if (x < width) {
669 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
670 &y0, &u, &v);
671 y1 = 0;
672
673 value = u;
674 value |= (uint32_t)y0 << 8;
675 value |= (uint32_t)v << 16;
676 value |= (uint32_t)y1 << 24;
677
678 *dst = util_le32_to_cpu(value);
679 }
680
681 dst_row += dst_stride/sizeof(*dst_row);
682 src_row += src_stride/sizeof(*src_row);
683 }
684 }
685
686
687 void
util_format_uyvy_fetch_rgba(void * in_dst,const uint8_t * src,unsigned i,ASSERTED unsigned j)688 util_format_uyvy_fetch_rgba(void *in_dst, const uint8_t *src,
689 unsigned i, ASSERTED unsigned j)
690 {
691 float *dst = in_dst;
692 uint8_t y, u, v;
693
694 assert(i < 2);
695 assert(j < 1);
696
697 y = src[1 + i*2];
698 u = src[0];
699 v = src[2];
700
701 util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]);
702
703 dst[3] = 1.0f;
704 }
705
706
707 void
util_format_yuyv_unpack_rgba_float(void * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)708 util_format_yuyv_unpack_rgba_float(void *dst_row, unsigned dst_stride,
709 const uint8_t *src_row, unsigned src_stride,
710 unsigned width, unsigned height)
711 {
712 unsigned x, y;
713
714 for (y = 0; y < height; y += 1) {
715 float *dst = dst_row;
716 const uint32_t *src = (const uint32_t *)src_row;
717 uint32_t value;
718 uint8_t y0, y1, u, v;
719
720 for (x = 0; x + 1 < width; x += 2) {
721 value = util_cpu_to_le32(*src++);
722
723 y0 = (value >> 0) & 0xff;
724 u = (value >> 8) & 0xff;
725 y1 = (value >> 16) & 0xff;
726 v = (value >> 24) & 0xff;
727
728 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
729 dst[3] = 1.0f; /* a */
730 dst += 4;
731
732 util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]);
733 dst[3] = 1.0f; /* a */
734 dst += 4;
735 }
736
737 if (x < width) {
738 value = util_cpu_to_le32(*src);
739
740 y0 = (value >> 0) & 0xff;
741 u = (value >> 8) & 0xff;
742 y1 = (value >> 16) & 0xff;
743 v = (value >> 24) & 0xff;
744
745 util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
746 dst[3] = 1.0f; /* a */
747 }
748
749 src_row = (uint8_t *)src_row + src_stride;
750 dst_row = (uint8_t *)dst_row + dst_stride;
751 }
752 }
753
754
755 void
util_format_yuyv_unpack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)756 util_format_yuyv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
757 const uint8_t *src_row, unsigned src_stride,
758 unsigned width, unsigned height)
759 {
760 unsigned x, y;
761
762 for (y = 0; y < height; y += 1) {
763 uint8_t *dst = dst_row;
764 const uint32_t *src = (const uint32_t *)src_row;
765 uint32_t value;
766 uint8_t y0, y1, u, v;
767
768 for (x = 0; x + 1 < width; x += 2) {
769 value = util_cpu_to_le32(*src++);
770
771 y0 = (value >> 0) & 0xff;
772 u = (value >> 8) & 0xff;
773 y1 = (value >> 16) & 0xff;
774 v = (value >> 24) & 0xff;
775
776 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
777 dst[3] = 0xff; /* a */
778 dst += 4;
779
780 util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]);
781 dst[3] = 0xff; /* a */
782 dst += 4;
783 }
784
785 if (x < width) {
786 value = util_cpu_to_le32(*src);
787
788 y0 = (value >> 0) & 0xff;
789 u = (value >> 8) & 0xff;
790 y1 = (value >> 16) & 0xff;
791 v = (value >> 24) & 0xff;
792
793 util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
794 dst[3] = 0xff; /* a */
795 }
796
797 src_row += src_stride/sizeof(*src_row);
798 dst_row += dst_stride/sizeof(*dst_row);
799 }
800 }
801
802
803 void
util_format_yuyv_pack_rgba_float(uint8_t * dst_row,unsigned dst_stride,const float * src_row,unsigned src_stride,unsigned width,unsigned height)804 util_format_yuyv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
805 const float *src_row, unsigned src_stride,
806 unsigned width, unsigned height)
807 {
808 unsigned x, y;
809
810 for (y = 0; y < height; y += 1) {
811 const float *src = src_row;
812 uint32_t *dst = (uint32_t *)dst_row;
813 uint8_t y0, y1, u, v;
814 uint32_t value;
815
816 for (x = 0; x + 1 < width; x += 2) {
817 uint8_t y0, y1, u0, u1, v0, v1, u, v;
818
819 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
820 &y0, &u0, &v0);
821 util_format_rgb_float_to_yuv(src[4], src[5], src[6],
822 &y1, &u1, &v1);
823
824 u = (u0 + u1 + 1) >> 1;
825 v = (v0 + v1 + 1) >> 1;
826
827 value = y0;
828 value |= (uint32_t)u << 8;
829 value |= (uint32_t)y1 << 16;
830 value |= (uint32_t)v << 24;
831
832 *dst++ = util_le32_to_cpu(value);
833
834 src += 8;
835 }
836
837 if (x < width) {
838 util_format_rgb_float_to_yuv(src[0], src[1], src[2],
839 &y0, &u, &v);
840 y1 = 0;
841
842 value = y0;
843 value |= (uint32_t)u << 8;
844 value |= (uint32_t)y1 << 16;
845 value |= (uint32_t)v << 24;
846
847 *dst = util_le32_to_cpu(value);
848 }
849
850 dst_row += dst_stride/sizeof(*dst_row);
851 src_row += src_stride/sizeof(*src_row);
852 }
853 }
854
855
856 void
util_format_yuyv_pack_rgba_8unorm(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned width,unsigned height)857 util_format_yuyv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
858 const uint8_t *src_row, unsigned src_stride,
859 unsigned width, unsigned height)
860 {
861 unsigned x, y;
862
863 for (y = 0; y < height; y += 1) {
864 const uint8_t *src = src_row;
865 uint32_t *dst = (uint32_t *)dst_row;
866 uint8_t y0, y1, u, v;
867 uint32_t value;
868
869 for (x = 0; x + 1 < width; x += 2) {
870 uint8_t y0, y1, u0, u1, v0, v1, u, v;
871
872 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
873 &y0, &u0, &v0);
874 util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6],
875 &y1, &u1, &v1);
876
877 u = (u0 + u1 + 1) >> 1;
878 v = (v0 + v1 + 1) >> 1;
879
880 value = y0;
881 value |= (uint32_t)u << 8;
882 value |= (uint32_t)y1 << 16;
883 value |= (uint32_t)v << 24;
884
885 *dst++ = util_le32_to_cpu(value);
886
887 src += 8;
888 }
889
890 if (x < width) {
891 util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
892 &y0, &u, &v);
893 y1 = 0;
894
895 value = y0;
896 value |= (uint32_t)u << 8;
897 value |= (uint32_t)y1 << 16;
898 value |= (uint32_t)v << 24;
899
900 *dst = util_le32_to_cpu(value);
901 }
902
903 dst_row += dst_stride/sizeof(*dst_row);
904 src_row += src_stride/sizeof(*src_row);
905 }
906 }
907
908
909 void
util_format_yuyv_fetch_rgba(void * in_dst,const uint8_t * src,unsigned i,ASSERTED unsigned j)910 util_format_yuyv_fetch_rgba(void *in_dst, const uint8_t *src,
911 unsigned i, ASSERTED unsigned j)
912 {
913 float *dst = in_dst;
914 uint8_t y, u, v;
915
916 assert(i < 2);
917 assert(j < 1);
918
919 y = src[0 + i*2];
920 u = src[1];
921 v = src[3];
922
923 util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]);
924
925 dst[3] = 1.0f;
926 }
927