UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
pixfmt_conv.c
Go to the documentation of this file.
1
16/* Copyright (c) 2005-2023 CESNET z.s.p.o.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, is permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 *
29 * 3. All advertising materials mentioning features or use of this software
30 * must display the following acknowledgement:
31 *
32 * This product includes software developed by CESNET z.s.p.o.
33 *
34 * 4. Neither the name of the CESNET nor the names of its contributors may be
35 * used to endorse or promote products derived from this software without
36 * specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
39 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
40 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
41 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
42 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
43 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
45 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 *
51 */
52
53#define __STDC_WANT_LIB_EXT1__ 1
54
55#ifdef HAVE_CONFIG_H
56#include "config.h"
57#endif // HAVE_CONFIG_H
58#include "config_unix.h"
59#include "config_win32.h"
60
61#include <assert.h>
62
63#include "color.h"
64#include "compat/qsort_s.h"
65#include "debug.h"
66#include "pixfmt_conv.h"
67#include "utils/macros.h" // to_fourcc, OPTIMEZED_FOR, CLAMP
68#include "video_codec.h"
69
70#ifdef __SSSE3__
71#include "tmmintrin.h"
72#endif
73
74#ifdef WORDS_BIGENDIAN
75#define BYTE_SWAP(x) (3 - x)
76#else
77#define BYTE_SWAP(x) x
78#endif
79
87static void vc_copylinev210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
88 int gshift, int bshift)
89{
90 UNUSED(rshift);
91 UNUSED(gshift);
92 UNUSED(bshift);
93 struct {
94 unsigned a:10;
95 unsigned b:10;
96 unsigned c:10;
97 unsigned p1:2;
98 } const *s;
99 register uint32_t *d;
100 register uint32_t tmp;
101
102 d = (uint32_t *)(void *) dst;
103 s = (const void *)src;
104
105 while (dst_len >= 12) {
106 tmp = (s->a >> 2) | (s->b >> 2) << 8 | (((s)->c >> 2) << 16);
107 s++;
108 *(d++) = tmp | ((s->a >> 2) << 24);
109 tmp = (s->b >> 2) | (((s)->c >> 2) << 8);
110 s++;
111 *(d++) = tmp | ((s->a >> 2) << 16) | ((s->b >> 2) << 24);
112 tmp = (s->c >> 2);
113 s++;
114 *(d++) =
115 tmp | ((s->a >> 2) << 8) | ((s->b >> 2) << 16) |
116 ((s->c >> 2) << 24);
117 s++;
118
119 dst_len -= 12;
120 }
121 if (dst_len >= 4) {
122 tmp = (s->a >> 2) | (s->b >> 2) << 8 | (((s)->c >> 2) << 16);
123 s++;
124 *(d++) = tmp | ((s->a >> 2) << 24);
125 }
126 if (dst_len >= 8) {
127 tmp = (s->b >> 2) | (((s)->c >> 2) << 8);
128 s++;
129 *(d++) = tmp | ((s->a >> 2) << 16) | ((s->b >> 2) << 24);
130 }
131}
132
137static void vc_copylineYUYV(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
138 int gshift, int bshift)
139{
140 UNUSED(rshift);
141 UNUSED(gshift);
142 UNUSED(bshift);
143#if defined __SSE2__
144 register uint32_t *d;
145 register const uint32_t *s;
146 const uint32_t * const end = (uint32_t *)(void *) dst + dst_len / 4;
147
148 uint32_t mask[4] = {
149 0xff00ff00ul,
150 0xff00ff00ul,
151 0xff00ff00ul,
152 0xff00ff00ul};
153
154 d = (uint32_t *)(void *) dst;
155 s = (const uint32_t *)(const void *) src;
156
157 assert(dst_len % 4 == 0);
158
159 if((dst_len % 16 == 0)) {
160 asm("movdqu (%0), %%xmm4\n"
161 "movdqa %%xmm4, %%xmm5\n"
162 "psrldq $1, %%xmm5\n"
163 : :"r"(mask));
164 while(d < end) {
165 asm volatile ("movdqu (%0), %%xmm0\n"
166 "movdqu %%xmm0, %%xmm1\n"
167 "pand %%xmm4, %%xmm0\n"
168 "psrldq $1, %%xmm0\n"
169 "pand %%xmm5, %%xmm1\n"
170 "pslldq $1, %%xmm1\n"
171 "por %%xmm0, %%xmm1\n"
172 "movdqu %%xmm1, (%1)\n"::"r" (s), "r"(d));
173 s += 4;
174 d += 4;
175 }
176 } else {
177 while(d < end) {
178 register uint32_t tmp = *s;
179 *d = ((tmp & 0x00ff0000) << 8) | ((tmp & 0xff000000) >> 8) |
180 ((tmp & 0x000000ff) << 8) | ((tmp & 0x0000ff00) >> 8);
181 s++;
182 d++;
183
184 }
185 }
186#else
187 char u, y1, v, y2;
188 OPTIMIZED_FOR (int x = 0; x <= dst_len - 4; x += 4) {
189 y1 = *src++;
190 u = *src++;
191 y2 = *src++;
192 v = *src++;
193 *dst++ = u;
194 *dst++ = y1;
195 *dst++ = v;
196 *dst++ = y2;
197 }
198#endif
199}
200
211static void
212vc_copyliner10k(unsigned char * __restrict dst, const unsigned char * __restrict src, int len, int rshift,
213 int gshift, int bshift)
214{
215 struct {
216 unsigned r:8;
217
218 unsigned gh:6;
219 unsigned p1:2;
220
221 unsigned bh:4;
222 unsigned p2:2;
223 unsigned gl:2;
224
225 unsigned p3:2;
226 unsigned p4:2;
227 unsigned bl:4;
228 } const *s;
229 register uint32_t *d;
230 register uint32_t tmp;
231 uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
232
233 d = (uint32_t *)(void *) dst;
234 s = (const void *) src;
235
236 while (len >= 16) {
237 tmp =
238 (alpha_mask | s->
239 r << rshift) | (((s->gh << 2) | s->
240 gl) << gshift) | (((s->bh << 4) | s->
241 bl) << bshift);
242 s++;
243 *(d++) = tmp;
244 tmp =
245 (alpha_mask | s->
246 r << rshift) | (((s->gh << 2) | s->
247 gl) << gshift) | (((s->bh << 4) | s->
248 bl) << bshift);
249 s++;
250 *(d++) = tmp;
251 tmp =
252 (alpha_mask | s->
253 r << rshift) | (((s->gh << 2) | s->
254 gl) << gshift) | (((s->bh << 4) | s->
255 bl) << bshift);
256 s++;
257 *(d++) = tmp;
258 tmp =
259 (alpha_mask | s->
260 r << rshift) | (((s->gh << 2) | s->
261 gl) << gshift) | (((s->bh << 4) | s->
262 bl) << bshift);
263 s++;
264 *(d++) = tmp;
265 len -= 16;
266 }
267 while (len >= 4) {
268 tmp =
269 (alpha_mask | s->
270 r << rshift) | (((s->gh << 2) | s->
271 gl) << gshift) | (((s->bh << 4) | s->
272 bl) << bshift);
273 s++;
274 *(d++) = tmp;
275 len -= 4;
276 }
277}
278
279static void
280vc_copyliner10ktoRG48(unsigned char * __restrict dst, const unsigned char * __restrict src, int dstlen, int rshift,
281 int gshift, int bshift) {
282 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
283 while (dstlen > 0) {
284 dst[1] = *src++; // Rhi
285 unsigned int byte2 = *src++;
286 unsigned int byte3 = *src++;
287 unsigned int byte4 = *src++;
288 dst[0] = byte2 & 0xC0U; // Rlo
289 dst[3] = byte2 << 2U | byte3 >> 6U; // Ghi
290 dst[2] = (byte3 & 0x30U) << 2U; // Glo
291 dst[5] = (byte3 & 0xFU) << 4U | byte4 >> 4U; // Bhi
292 dst[4] = (byte4 & 0xCU) << 4U; // Blo
293 dst += 6;
294 dstlen -= 6;
295 }
296}
297
298static void vc_copyliner10ktoY416(unsigned char * __restrict dst, const unsigned char * __restrict src, int dstlen, int rshift,
299 int gshift, int bshift) {
300 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
301 enum {
302 D_DEPTH = 16,
303 };
304 assert((uintptr_t) dst % 2 == 0);
305 const struct color_coeffs *cfs = get_color_coeffs(D_DEPTH);
306 uint16_t *d = (void *) dst;
307 OPTIMIZED_FOR (int x = 0; x < dstlen; x += 8) {
308 unsigned int byte1 = *src++;
309 unsigned int byte2 = *src++;
310 unsigned int byte3 = *src++;
311 unsigned int byte4 = *src++;
312 comp_type_t r, g, b;
313 r = byte1 << 8U | (byte2 & 0xC0U);
314 g = (byte2 & 0x3FU) << 10U | (byte3 & 0xF0U) << 2U;
315 b = (byte3 & 0xFU) << 12U | (byte4 & 0xFCU) << 4U;
316 comp_type_t u =
317 (RGB_TO_CB(cfs, r, g, b) >> COMP_BASE) +
318 (1 << (D_DEPTH - 1));
319 *d++ = CLAMP_LIMITED_CBCR(u, D_DEPTH);
320 comp_type_t y =
321 (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) +
322 (1 << (D_DEPTH - 4));
323 *d++ = CLAMP_LIMITED_Y(y, D_DEPTH);
324 comp_type_t v =
325 (RGB_TO_CR(cfs, r, g, b) >> COMP_BASE) +
326 (1 << (D_DEPTH - 4));
327 *d++ = CLAMP_LIMITED_CBCR(v, D_DEPTH);
328 *d++ = 0xFFFFU;
329 }
330}
331
332static void vc_copyliner10ktoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dstlen, int rshift,
333 int gshift, int bshift) {
334 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
335 OPTIMIZED_FOR (int x = 0; x < dstlen; x += 3) {
336 *(dst++) = src[0];
337 *(dst++) = src[1] << 2 | src[2] >> 6;
338 *(dst++) = src[2] << 4 | src[3] >> 4;
339 src += 4;
340 }
341}
342
353static void
354vc_copylineR12LtoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dstlen, int rshift,
355 int gshift, int bshift)
356{
357 UNUSED(rshift);
358 UNUSED(gshift);
359 UNUSED(bshift);
360
361 OPTIMIZED_FOR (int x = 0; x <= dstlen - 24; x += 24) {
362 uint8_t tmp;
363 tmp = src[BYTE_SWAP(0)] >> 4;
364 tmp |= src[BYTE_SWAP(1)] << 4;
365 *dst++ = tmp; // r0
366 *dst++ = src[BYTE_SWAP(2)]; // g0
367 tmp = src[BYTE_SWAP(3)]>> 4;
368 src += 4;
369 tmp |= src[BYTE_SWAP(0)] << 4;
370 *dst++ = tmp; // b0
371 *dst++ = src[BYTE_SWAP(1)]; // r1
372 tmp = src[BYTE_SWAP(2)] >> 4;
373 tmp |= src[BYTE_SWAP(3)] << 4;
374 src += 4;
375 *dst++ = tmp; // g1
376 *dst++ = src[BYTE_SWAP(0)]; // b1
377 tmp = src[BYTE_SWAP(1)] >> 4;
378 tmp |= src[BYTE_SWAP(2)] << 4;
379 *dst++ = tmp; // r2
380 *dst++ = src[BYTE_SWAP(3)]; // g2
381 src += 4;
382 tmp = src[BYTE_SWAP(0)] >> 4;
383 tmp |= src[BYTE_SWAP(1)] << 4;
384 *dst++ = tmp; // b2
385 *dst++ = src[BYTE_SWAP(2)]; // r3
386 tmp = src[BYTE_SWAP(3)] >> 4;
387 src += 4;
388 tmp |= src[BYTE_SWAP(0)] << 4;
389 *dst++ = tmp; // g3
390 *dst++ = src[BYTE_SWAP(1)]; // b3
391 tmp = src[BYTE_SWAP(2)] >> 4;
392 tmp |= src[BYTE_SWAP(3)] << 4;
393 src += 4;
394 *dst++ = tmp; // r4
395 *dst++ = src[BYTE_SWAP(0)]; // g4
396 tmp = src[BYTE_SWAP(1)] >> 4;
397 tmp |= src[BYTE_SWAP(2)] << 4;
398 *dst++ = tmp; // b4
399 *dst++ = src[BYTE_SWAP(3)]; // r5
400 src += 4;
401 tmp = src[BYTE_SWAP(0)] >> 4;
402 tmp |= src[BYTE_SWAP(1)] << 4;
403 *dst++ = tmp; // g5
404 *dst++ = src[BYTE_SWAP(2)]; // b5
405 tmp = src[BYTE_SWAP(3)] >> 4;
406 src += 4;
407 tmp |= src[BYTE_SWAP(0)] << 4;
408 *dst++ = tmp; // r6
409 *dst++ = src[BYTE_SWAP(1)]; // g6
410 tmp = src[BYTE_SWAP(2)] >> 4;
411 tmp |= src[BYTE_SWAP(3)] << 4;
412 src += 4;
413 *dst++ = tmp; // b6
414 *dst++ = src[BYTE_SWAP(0)]; // r7
415 tmp = src[BYTE_SWAP(1)] >> 4;
416 tmp |= src[BYTE_SWAP(2)] << 4;
417 *dst++ = tmp; // g7
418 *dst++ = src[BYTE_SWAP(3)]; // b7
419 src += 4;
420 }
421}
422
433static void
434vc_copylineR12L(unsigned char *dst, const unsigned char *src, int dstlen, int rshift,
435 int gshift, int bshift)
436{
437 assert((uintptr_t) dst % sizeof(uint32_t) == 0);
438 uint32_t *d = (uint32_t *)(void *) dst;
439 uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
440
441 OPTIMIZED_FOR (int x = 0; x <= dstlen - 32; x += 32) {
442 uint8_t tmp;
443 uint8_t r, g, b;
444 tmp = src[BYTE_SWAP(0)] >> 4;
445 tmp |= src[BYTE_SWAP(1)] << 4;
446 r = tmp; // r0
447 g = src[BYTE_SWAP(2)]; // g0
448 tmp = src[BYTE_SWAP(3)]>> 4;
449 src += 4;
450 tmp |= src[BYTE_SWAP(0)] << 4;
451 b = tmp; // b0
452 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
453 r = src[BYTE_SWAP(1)]; // r1
454 tmp = src[BYTE_SWAP(2)] >> 4;
455 tmp |= src[BYTE_SWAP(3)] << 4;
456 src += 4;
457 g = tmp; // g1
458 b = src[BYTE_SWAP(0)]; // b1
459 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
460 tmp = src[BYTE_SWAP(1)] >> 4;
461 tmp |= src[BYTE_SWAP(2)] << 4;
462 r = tmp; // r2
463 g = src[BYTE_SWAP(3)]; // g2
464 src += 4;
465 tmp = src[BYTE_SWAP(0)] >> 4;
466 tmp |= src[BYTE_SWAP(1)] << 4;
467 b = tmp; // b2
468 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
469 r = src[BYTE_SWAP(2)]; // r3
470 tmp = src[BYTE_SWAP(3)] >> 4;
471 src += 4;
472 tmp |= src[BYTE_SWAP(0)] << 4;
473 g = tmp; // g3
474 b = src[BYTE_SWAP(1)]; // b3
475 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
476 tmp = src[BYTE_SWAP(2)] >> 4;
477 tmp |= src[BYTE_SWAP(3)] << 4;
478 src += 4;
479 r = tmp; // r4
480 g = src[BYTE_SWAP(0)]; // g4
481 tmp = src[BYTE_SWAP(1)] >> 4;
482 tmp |= src[BYTE_SWAP(2)] << 4;
483 b = tmp; // b4
484 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
485 r = src[BYTE_SWAP(3)]; // r5
486 src += 4;
487 tmp = src[BYTE_SWAP(0)] >> 4;
488 tmp |= src[BYTE_SWAP(1)] << 4;
489 g = tmp; // g5
490 b = src[BYTE_SWAP(2)]; // b5
491 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
492 tmp = src[BYTE_SWAP(3)] >> 4;
493 src += 4;
494 tmp |= src[BYTE_SWAP(0)] << 4;
495 r = tmp; // r6
496 g = src[BYTE_SWAP(1)]; // g6
497 tmp = src[BYTE_SWAP(2)] >> 4;
498 tmp |= src[BYTE_SWAP(3)] << 4;
499 src += 4;
500 b = tmp; // b6
501 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
502 r = src[BYTE_SWAP(0)]; // r7
503 tmp = src[BYTE_SWAP(1)] >> 4;
504 tmp |= src[BYTE_SWAP(2)] << 4;
505 g = tmp; // g7
506 b = src[BYTE_SWAP(3)]; // b7
507 src += 4;
508 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
509 }
510}
511
522void
523vc_copylineRGBA(unsigned char * __restrict dst, const unsigned char * __restrict src, int len, int rshift,
524 int gshift, int bshift)
525{
526 register uint32_t *d = (uint32_t *)(void *) dst;
527 register const uint32_t *s = (const uint32_t *)(const void *) src;
528 register uint32_t tmp;
529
530 if (rshift == 0 && gshift == 8 && bshift == 16) {
531 memcpy(dst, src, len);
532 } else {
533 uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
534 while (len >= 16) {
535 register unsigned int r, g, b;
536 tmp = *(s++);
537 r = tmp & 0xff;
538 g = (tmp >> 8) & 0xff;
539 b = (tmp >> 16) & 0xff;
540 tmp = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
541 *(d++) = tmp;
542 tmp = *(s++);
543 r = tmp & 0xff;
544 g = (tmp >> 8) & 0xff;
545 b = (tmp >> 16) & 0xff;
546 tmp = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
547 *(d++) = tmp;
548 tmp = *(s++);
549 r = tmp & 0xff;
550 g = (tmp >> 8) & 0xff;
551 b = (tmp >> 16) & 0xff;
552 tmp = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
553 *(d++) = tmp;
554 tmp = *(s++);
555 r = tmp & 0xff;
556 g = (tmp >> 8) & 0xff;
557 b = (tmp >> 16) & 0xff;
558 tmp = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
559 *(d++) = tmp;
560 len -= 16;
561 }
562 while (len >= 4) {
563 register unsigned int r, g, b;
564 tmp = *(s++);
565 r = tmp & 0xff;
566 g = (tmp >> 8) & 0xff;
567 b = (tmp >> 16) & 0xff;
568 tmp = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
569 *(d++) = tmp;
570 len -= 4;
571 }
572 }
573}
574
579static void vc_copylineDVS10toV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
580 int gshift, int bshift)
581{
582 UNUSED(rshift);
583 UNUSED(gshift);
584 UNUSED(bshift);
585 unsigned int *d;
586 const unsigned int *s1;
587 register unsigned int a,b;
588 d = (unsigned int *)(void *) dst;
589 s1 = (const unsigned int *)(const void *) src;
590
591 OPTIMIZED_FOR (int x = 0; x <= dst_len - 4; x += 4) {
592 a = b = *s1++;
593 b = ((b >> 24) * 0x00010101) & 0x00300c03;
594 a <<= 2;
595 b |= a & (0xff<<2);
596 a <<= 2;
597 b |= a & (0xff00<<4);
598 a <<= 2;
599 b |= a & (0xff0000<<6);
600 *d++ = b;
601 }
602}
603
604/* convert 10bits Cb Y Cr A Y Cb Y A to 8bits Cb Y Cr Y Cb Y */
605
606/* TODO: undo it - currently this decoder is broken */
607#if 0 /* !(__APPLE__ || HAVE_32B_LINUX) */
608
609void vc_copylineDVS10(unsigned char *dst, unsigned char *src, int src_len)
610{
611 register unsigned char *_d = dst, *_s = src;
612
613 while (src_len > 0) {
614
615 asm("movd %0, %%xmm4\n": :"r"(0xffffff));
616
617 asm volatile ("movdqa (%0), %%xmm0\n"
618 "movdqa 16(%0), %%xmm5\n"
619 "movdqa %%xmm0, %%xmm1\n"
620 "movdqa %%xmm0, %%xmm2\n"
621 "movdqa %%xmm0, %%xmm3\n"
622 "pand %%xmm4, %%xmm0\n"
623 "movdqa %%xmm5, %%xmm6\n"
624 "movdqa %%xmm5, %%xmm7\n"
625 "movdqa %%xmm5, %%xmm8\n"
626 "pand %%xmm4, %%xmm5\n"
627 "pslldq $4, %%xmm4\n"
628 "pand %%xmm4, %%xmm1\n"
629 "pand %%xmm4, %%xmm6\n"
630 "pslldq $4, %%xmm4\n"
631 "psrldq $1, %%xmm1\n"
632 "psrldq $1, %%xmm6\n"
633 "pand %%xmm4, %%xmm2\n"
634 "pand %%xmm4, %%xmm7\n"
635 "pslldq $4, %%xmm4\n"
636 "psrldq $2, %%xmm2\n"
637 "psrldq $2, %%xmm7\n"
638 "pand %%xmm4, %%xmm3\n"
639 "pand %%xmm4, %%xmm8\n"
640 "por %%xmm1, %%xmm0\n"
641 "psrldq $3, %%xmm3\n"
642 "psrldq $3, %%xmm8\n"
643 "por %%xmm2, %%xmm0\n"
644 "por %%xmm6, %%xmm5\n"
645 "por %%xmm3, %%xmm0\n"
646 "por %%xmm7, %%xmm5\n"
647 "movdq2q %%xmm0, %%mm0\n"
648 "por %%xmm8, %%xmm5\n"
649 "movdqa %%xmm5, %%xmm1\n"
650 "pslldq $12, %%xmm5\n"
651 "psrldq $4, %%xmm1\n"
652 "por %%xmm5, %%xmm0\n"
653 "psrldq $8, %%xmm0\n"
654 "movq %%mm0, (%1)\n"
655 "movdq2q %%xmm0, %%mm1\n"
656 "movdq2q %%xmm1, %%mm2\n"
657 "movq %%mm1, 8(%1)\n"
658 "movq %%mm2, 16(%1)\n"::"r" (_s), "r"(_d));
659 _s += 32;
660 _d += 24;
661 src_len -= 32;
662 }
663}
664
665#else
666
671static void vc_copylineDVS10(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
672 int gshift, int bshift)
673{
674 UNUSED(rshift);
675 UNUSED(gshift);
676 UNUSED(bshift);
677 int src_len = dst_len / 1.5; /* right units */
678 register const uint64_t *s;
679 register uint64_t *d;
680
681 register uint64_t a1, a2, a3, a4;
682
683 d = (uint64_t *)(void *) dst;
684 s = (const uint64_t *)(const void *) src;
685
686 OPTIMIZED_FOR (int x = 0; x <= src_len - 16; x += 16) {
687 a1 = *(s++);
688 a2 = *(s++);
689 a3 = *(s++);
690 a4 = *(s++);
691
692 a1 = (a1 & 0xffffff) | ((a1 >> 8) & 0xffffff000000LL);
693 a2 = (a2 & 0xffffff) | ((a2 >> 8) & 0xffffff000000LL);
694 a3 = (a3 & 0xffffff) | ((a3 >> 8) & 0xffffff000000LL);
695 a4 = (a4 & 0xffffff) | ((a4 >> 8) & 0xffffff000000LL);
696
697 *(d++) = a1 | (a2 << 48); /* 0xa2|a2|a1|a1|a1|a1|a1|a1 */
698 *(d++) = (a2 >> 16) | (a3 << 32); /* 0xa3|a3|a3|a3|a2|a2|a2|a2 */
699 *(d++) = (a3 >> 32) | (a4 << 16); /* 0xa4|a4|a4|a4|a4|a4|a3|a3 */
700 }
701}
702
703#endif /* !(__APPLE__ || HAVE_32B_LINUX) */
704
713static void vc_copylineRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift, int gshift, int bshift)
714{
715 register unsigned int r, g, b;
716 union {
717 unsigned int out;
718 unsigned char c[4];
719 } u;
720
721 if (rshift == 0 && gshift == 8 && bshift == 16) {
722 memcpy(dst, src, dst_len);
723 } else {
724 OPTIMIZED_FOR (int x = 0; x <= dst_len - 3; x += 3) {
725 r = *src++;
726 g = *src++;
727 b = *src++;
728 u.out = (r << rshift) | (g << gshift) | (b << bshift);
729 *dst++ = u.c[0];
730 *dst++ = u.c[1];
731 *dst++ = u.c[2];
732 }
733 }
734}
735
750static void vc_copylineRGBAtoRGBwithShift(unsigned char * __restrict dst2, const unsigned char * __restrict src2, int dst_len, int rshift, int gshift, int bshift)
751{
752 register const uint32_t * src = (const uint32_t *)(const void *) src2;
753 register uint32_t * dst = (uint32_t *)(void *) dst2;
754 int x;
755 OPTIMIZED_FOR (x = 0; x <= dst_len - 12; x += 12) {
756 register uint32_t in1 = *src++;
757 register uint32_t in2 = *src++;
758 register uint32_t in3 = *src++;
759 register uint32_t in4 = *src++;
760
761 *dst++ = ((in2 >> rshift)) << 24 |
762 ((in1 >> bshift) & 0xff) << 16 |
763 ((in1 >> gshift) & 0xff) << 8 |
764 ((in1 >> rshift) & 0xff);
765 *dst++ = ((in3 >> gshift)) << 24 |
766 ((in3 >> rshift) & 0xff) << 16 |
767 ((in2 >> bshift) & 0xff) << 8 |
768 ((in2 >> gshift) & 0xff);
769 *dst++ = ((in4 >> bshift)) << 24 |
770 ((in4 >> gshift) & 0xff) << 16 |
771 ((in4 >> rshift) & 0xff) << 8 |
772 ((in3 >> bshift) & 0xff);
773 }
774
775 uint8_t *dst_c = (uint8_t *) dst;
776 for (; x <= dst_len - 3; x += 3) {
777 register uint32_t in = *src++;
778 *dst_c++ = (in >> rshift) & 0xff;
779 *dst_c++ = (in >> gshift) & 0xff;
780 *dst_c++ = (in >> bshift) & 0xff;
781 }
782}
783
790void vc_copylineABGRtoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift, int gshift, int bshift)
791{
792 UNUSED(rshift);
793 UNUSED(gshift);
794 UNUSED(bshift);
795 enum {
796 SRC_RSHIFT = 24,
797 SRC_GSHIFT = 16,
798 SRC_BSHIFT = 8,
799 };
800#ifdef __SSSE3__
801 __m128i shuf = _mm_setr_epi8(3, 2, 1, 7, 6, 5, 11, 10, 9, 15, 14, 13, 0xff, 0xff, 0xff, 0xff);
802 __m128i loaded;
803 int x;
804 for (x = 0; x <= dst_len - 24; x += 12) {
805 loaded = _mm_lddqu_si128((const __m128i_u *) src);
806 loaded = _mm_shuffle_epi8(loaded, shuf);
807 _mm_storeu_si128((__m128i_u *)dst, loaded);
808
809 src += 16;
810 dst += 12;
811 }
812
813 uint8_t *dst_c = (uint8_t *) dst;
814 for (; x <= dst_len - 3; x += 3) {
815 register uint32_t in = *(const uint32_t *) (const void *) src;
816 *dst_c++ = (in >> SRC_RSHIFT) & 0xff;
817 *dst_c++ = (in >> SRC_GSHIFT) & 0xff;
818 *dst_c++ = (in >> SRC_BSHIFT) & 0xff;
819 }
820#else
821 vc_copylineRGBAtoRGBwithShift(dst, src, dst_len, SRC_RSHIFT, SRC_GSHIFT,
822 SRC_BSHIFT);
823#endif
824}
825
826void
827vc_copylineBGRAtoRGB(unsigned char *__restrict dst,
828 const unsigned char *__restrict src2, int dst_len,
829 int rshift, int gshift, int bshift)
830{
831 UNUSED(rshift);
832 UNUSED(gshift);
833 UNUSED(bshift);
834 enum {
835 SRC_RSHIFT = 16,
836 SRC_GSHIFT = 8,
837 SRC_BSHIFT = 0,
838 };
839 vc_copylineRGBAtoRGBwithShift(dst, src2, dst_len, SRC_RSHIFT, SRC_GSHIFT,
840 SRC_BSHIFT);
841}
842
847static void vc_copylineRGBAtoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift, int gshift, int bshift)
848{
849 UNUSED(rshift);
850 UNUSED(gshift);
851 UNUSED(bshift);
852 enum {
853 SRC_RSHIFT = 0,
854 SRC_GSHIFT = 8,
855 SRC_BSHIFT = 16,
856 };
857#ifdef __SSSE3__
858 __m128i shuf = _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0xff, 0xff, 0xff, 0xff);
859 __m128i loaded;
860 int x;
861 for (x = 0; x <= dst_len - 24; x += 12) {
862 loaded = _mm_lddqu_si128((const __m128i_u *) src);
863 loaded = _mm_shuffle_epi8(loaded, shuf);
864 _mm_storeu_si128((__m128i_u *)dst, loaded);
865
866 src += 16;
867 dst += 12;
868 }
869
870 uint8_t *dst_c = (uint8_t *) dst;
871 for (; x <= dst_len - 3; x += 3) {
872 register uint32_t in = *(const uint32_t *) (const void *) src;
873 *dst_c++ = (in >> SRC_RSHIFT) & 0xff;
874 *dst_c++ = (in >> SRC_GSHIFT) & 0xff;
875 *dst_c++ = (in >> SRC_BSHIFT) & 0xff;
876 }
877#else
878 vc_copylineRGBAtoRGBwithShift(dst, src, dst_len, SRC_RSHIFT, SRC_GSHIFT,
879 SRC_BSHIFT);
880#endif
881}
882
888void vc_copylineToRGBA_inplace(unsigned char *dst, const unsigned char *src, int dst_len,
889 int src_rshift, int src_gshift, int src_bshift)
890{
891 register const uint32_t * in = (const uint32_t *)(const void *) src;
892 register uint32_t * out = (uint32_t *)(void *) dst;
893 while (dst_len >= 4) {
894 register uint32_t in_val = *in++;
895
896 *out++ = ((in_val >> src_rshift) & 0xff) |
897 ((in_val >> src_gshift) & 0xff) << 8 |
898 ((in_val >> src_bshift) & 0xff) << 16;
899
900 dst_len -= 4;
901 }
902}
903
908void vc_copylineUYVYtoGrayscale(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
909 int gshift, int bshift) {
910 UNUSED(rshift);
911 UNUSED(gshift);
912 UNUSED(bshift);
913 OPTIMIZED_FOR (int x = 0; x <= dst_len - 2; x += 2) {
914 src++; // U
915 *dst++ = *src++; // Y
916 src++; // V
917 *dst++ = *src++; // Y
918 }
919}
920
925void vc_copylineRGBtoRGBA(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift, int gshift, int bshift)
926{
927
928 int x = 0;
929
930
931#ifdef __SSSE3__
932 __m128i alpha_mask_sse = _mm_set1_epi32(0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift));
933 __m128i shuf;
934
935 // common shifts are 0 8 16 (RGB) or 16 8 0 (BGR)
936 // generalized solution would be too complex and not faster
937 __m128i loaded;
938 bool is_simd_compat = false;
939
940 if (rshift == 0 && gshift == 8 && bshift == 16) {
941 is_simd_compat = true;
942 shuf = _mm_setr_epi8(0, 1, 2, 0xff, 3, 4, 5, 0xff, 6, 7, 8, 0xff, 9, 10, 11, 0xff);
943 } else if (rshift == 16 && gshift == 8 && bshift == 0) {
944 is_simd_compat = true;
945 shuf = _mm_setr_epi8(2, 1, 0, 0xff, 5, 4, 3, 0xff, 8, 7, 6, 0xff, 11, 10, 9, 0xff);
946 }
947
948 if (is_simd_compat) {
949 for (x = 0; x <= dst_len - 32; x += 16) {
950 loaded = _mm_lddqu_si128((const __m128i_u *) src);
951 loaded = _mm_shuffle_epi8(loaded, shuf);
952 loaded = _mm_or_si128(loaded, alpha_mask_sse);
953 _mm_storeu_si128((__m128i_u *)dst, loaded);
954 src += 12;
955 dst += 16;
956 }
957 }
958#endif
959
960 uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
961 register unsigned int r, g, b;
962 register uint32_t *d = (uint32_t *)(void *) dst;
963
964 OPTIMIZED_FOR (; x <= dst_len - 4; x += 4) {
965 r = *src++;
966 g = *src++;
967 b = *src++;
968
969 *d++ = alpha_mask | (r << rshift) | (g << gshift) | (b << bshift);
970 }
971}
972
982#if defined __GNUC__
983static inline void vc_copylineToUYVY(unsigned char *__restrict dst,
984 const unsigned char *__restrict src,
985 int dst_len, int roff, int goff, int boff,
986 int pix_size)
987 __attribute__((always_inline));
988#endif
989static inline void
990vc_copylineToUYVY(unsigned char *__restrict dst,
991 const unsigned char *__restrict src, int dst_len, int roff,
992 int goff, int boff, int pix_size)
993{
994 enum {
995 UYVY_BPP = 4,
996 LOOP_ITEMS = 4,
997 };
998 const struct color_coeffs *cfs = get_color_coeffs(DEPTH8);
999 register uint32_t *d = (uint32_t *) (void *) dst;
1000 int r, g, b;
1001 int y1, y2, u ,v;
1002#define loop_body \
1003 r = src[roff];\
1004 g = src[goff];\
1005 b = src[boff];\
1006 src += pix_size;\
1007 y1 = (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) + 16;\
1008 u = RGB_TO_CB(cfs, r, g, b);\
1009 v = RGB_TO_CR(cfs, r, g, b);\
1010 r = src[roff];\
1011 g = src[goff];\
1012 b = src[boff];\
1013 src += pix_size;\
1014 y2 = (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) + 16;\
1015 u += RGB_TO_CB(cfs, r, g, b);\
1016 v += RGB_TO_CR(cfs, r, g, b);\
1017 u = ((u / 2) >> COMP_BASE) + 128;\
1018 v = ((v / 2) >> COMP_BASE) + 128;\
1019\
1020 *d++ = ((y2 & 0xFF) << 24) | ((v & 0xFF) << 16) | \
1021 ((y1 & 0xFF) << 8) | (u & 0xFF);
1022
1023 const int count = (dst_len + 3) / UYVY_BPP;
1024 int x = 0;
1025 for (; x < count / LOOP_ITEMS; x++) {
1026 loop_body
1027 loop_body
1028 loop_body
1029 loop_body
1030 }
1031 x *= LOOP_ITEMS;
1032 for (; x < count; x++) {
1033 loop_body
1034 }
1035#undef loop_body
1036}
1037
1048#define copylineYUVtoRGB(dst, src, dst_len, y1_off, y2_off, u_off, v_off, rgb16) {\
1049 enum { DEPTH = DEPTH8 };\
1050 const struct color_coeffs *cfs = get_color_coeffs(DEPTH);\
1051 OPTIMIZED_FOR (int x = 0; x <= (dst_len) - 6 * (1 + (rgb16)); x += 6 * (1 + (rgb16))) {\
1052 register int y1 = Y_SCALE(8) * ((src)[y1_off] - 16);\
1053 register int y2 = Y_SCALE(8) * ((src)[y2_off] - 16);\
1054 register int u = (src)[u_off] - 128;\
1055 register int v = (src)[v_off] - 128;\
1056 int val;\
1057 src += 4;\
1058 if (rgb16) *(dst)++ = 0;\
1059 val = YCBCR_TO_R(cfs, y1, u, v) >> COMP_BASE;\
1060 *(dst)++ = CLAMP(val, 0, 255);\
1061 if (rgb16) *(dst)++ = 0;\
1062 val = YCBCR_TO_G(cfs, y1, u, v) >> COMP_BASE;\
1063 *(dst)++ = CLAMP(val, 0, 255);\
1064 if (rgb16) *(dst)++ = 0;\
1065 val = YCBCR_TO_B(cfs, y1, u, v) >> COMP_BASE;\
1066 *(dst)++ = CLAMP(val, 0, 255);\
1067 if (rgb16) *(dst)++ = 0;\
1068 val = YCBCR_TO_R(cfs, y2, u, v) >> COMP_BASE;\
1069 *(dst)++ = CLAMP(val, 0, 255);\
1070 if (rgb16) *(dst)++ = 0;\
1071 val = YCBCR_TO_G(cfs, y2, u, v) >> COMP_BASE;\
1072 *(dst)++ = CLAMP(val, 0, 255);\
1073 if (rgb16) *(dst)++ = 0;\
1074 val = YCBCR_TO_B(cfs, y2, u, v) >> COMP_BASE;\
1075 *(dst)++ = CLAMP(val, 0, 255);\
1076 }\
1077}
1078
1085static void vc_copylineUYVYtoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1086 int gshift, int bshift) {
1087 UNUSED(rshift);
1088 UNUSED(gshift);
1089 UNUSED(bshift);
1090 copylineYUVtoRGB(dst, src, dst_len, 1, 3, 0, 2, 0);
1091}
1092
1099static void vc_copylineYUYVtoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1100 int gshift, int bshift) {
1101 UNUSED(rshift);
1102 UNUSED(gshift);
1103 UNUSED(bshift);
1104 copylineYUVtoRGB(dst, src, dst_len, 0, 2, 1, 3, 0);
1105}
1106
1107static void vc_copylineUYVYtoRG48(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1108 int gshift, int bshift) {
1109 UNUSED(rshift);
1110 UNUSED(gshift);
1111 UNUSED(bshift);
1112 copylineYUVtoRGB(dst, src, dst_len, 1, 3, 0, 2, 1);
1113}
1114
1120static void vc_copylineUYVYtoRGBA(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1121 int gshift, int bshift) {
1122 assert((uintptr_t) dst % sizeof(uint32_t) == 0);
1123 uint32_t *dst32 = (uint32_t *)(void *) dst;
1124 uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
1125 OPTIMIZED_FOR (int x = 0; x <= dst_len - 8; x += 8) {
1126 register int y1, y2, u ,v;
1127 u = *src++;
1128 y1 = *src++;
1129 v = *src++;
1130 y2 = *src++;
1131 int r = 1.164 * (y1 - 16) + 1.793 * (v - 128);
1132 int g = 1.164 * (y1 - 16) - 0.534 * (v - 128) - 0.213 * (u - 128);
1133 int b = 1.164 * (y1 - 16) + 2.115 * (u - 128);
1134 r = CLAMP(r, 0, 255);
1135 g = CLAMP(g, 0, 255);
1136 b = CLAMP(b, 0, 255);
1137 *dst32++ = alpha_mask | r << rshift | g << gshift | b << bshift;
1138 r = 1.164 * (y2 - 16) + 1.793 * (v - 128);
1139 g = 1.164 * (y2 - 16) - 0.534 * (v - 128) - 0.213 * (u - 128);
1140 b = 1.164 * (y2 - 16) + 2.115 * (u - 128);
1141 r = CLAMP(r, 0, 255);
1142 g = CLAMP(g, 0, 255);
1143 b = CLAMP(b, 0, 255);
1144 *dst32++ = alpha_mask | r << rshift | g << gshift | b << bshift;
1145 }
1146}
1147
1155void vc_copylineUYVYtoRGB_SSE(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1156 int gshift, int bshift) {
1157#ifdef __SSSE3__
1158 __m128i yfactor = _mm_set1_epi16(74); //1.164 << 6
1159 __m128i rvfactor = _mm_set1_epi16(115); //1.793 << 6
1160 __m128i gvfactor = _mm_set1_epi16(34); //0.534 << 6
1161 __m128i gufactor = _mm_set1_epi16(14); //0.213 << 6
1162 __m128i bufactor = _mm_set1_epi16(135); //2.115 << 6
1163
1164 __m128i ysub = _mm_set1_epi16(16);
1165 __m128i uvsub = _mm_set1_epi16(128);
1166
1167 __m128i zero128 = _mm_set1_epi32(0);
1168 __m128i max = _mm_set1_epi16(255);
1169 //YYVVYYUU
1170 __m128i ymask = _mm_set1_epi32(0x00FF00FF);
1171 __m128i umask = _mm_set1_epi32(0x000000FF);
1172
1173 __m128i rgbshuffle = _mm_setr_epi8(0, 2, 1, 4, 6, 5, 8, 10, 9, 12, 14, 13, 15, 11, 7, 3);
1174
1175 __m128i yuv;
1176 __m128i rgb;
1177
1178 __m128i y;
1179 __m128i u;
1180 __m128i v;
1181 __m128i r;
1182 __m128i g;
1183 __m128i b;
1184
1185 while(dst_len >= 28){
1186 yuv = _mm_lddqu_si128((__m128i const*)(const void *) src);
1187 src += 16;
1188
1189 u = _mm_and_si128(yuv, umask);
1190 u = _mm_or_si128(u, _mm_bslli_si128(u, 2));
1191
1192 yuv = _mm_bsrli_si128(yuv, 1);
1193 y = _mm_and_si128(yuv, ymask);
1194
1195 yuv = _mm_bsrli_si128(yuv, 1);
1196 v = _mm_and_si128(yuv, umask);
1197 v = _mm_or_si128(v, _mm_bslli_si128(v, 2));
1198
1199 y = _mm_subs_epi16(y, ysub);
1200 y = _mm_mullo_epi16(y, yfactor);
1201
1202 u = _mm_subs_epi16(u, uvsub);
1203 v = _mm_subs_epi16(v, uvsub);
1204
1205 r = _mm_adds_epi16(y, _mm_mullo_epi16(v, rvfactor));
1206 g = _mm_subs_epi16(y, _mm_mullo_epi16(v, gvfactor));
1207 g = _mm_subs_epi16(g, _mm_mullo_epi16(u, gufactor));
1208 b = _mm_adds_epi16(y, _mm_mullo_epi16(u, bufactor));
1209
1210 //Make sure that the result is in the interval 0..255
1211 r = _mm_max_epi16(zero128, r);
1212 g = _mm_max_epi16(zero128, g);
1213 b = _mm_max_epi16(zero128, b);
1214
1215 r = _mm_srli_epi16(r, 6);
1216 g = _mm_srli_epi16(g, 6);
1217 b = _mm_srli_epi16(b, 6);
1218
1219 r = _mm_min_epi16(max, r);
1220 g = _mm_min_epi16(max, g);
1221 b = _mm_min_epi16(max, b);
1222
1223 rgb = _mm_or_si128(_mm_bslli_si128(g, 1), r);
1224 rgb = _mm_unpacklo_epi8(rgb, b);
1225 rgb = _mm_shuffle_epi8(rgb, rgbshuffle);
1226 _mm_storeu_si128((__m128i *)(void *) dst, rgb);
1227 dst += 12;
1228
1229 rgb = _mm_or_si128(_mm_bslli_si128(g, 1), r);
1230 rgb = _mm_unpackhi_epi8(rgb, b);
1231 rgb = _mm_shuffle_epi8(rgb, rgbshuffle);
1232 _mm_storeu_si128((__m128i *)(void *) dst, rgb);
1233 dst += 12;
1234
1235 dst_len -= 24;
1236 }
1237#endif
1238 //copy last few pixels
1239 vc_copylineUYVYtoRGB(dst, src, dst_len, rshift, gshift, bshift);
1240}
1241
1242#if defined __GNUC__
1243static inline void vc_copylineRGB_AtoR12L(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int pix_pad)
1244 __attribute__((always_inline));
1245#endif
1246static inline void vc_copylineRGB_AtoR12L(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int pix_pad) {
1247#define FETCH_DATA \
1248 r = *src++; \
1249 g = *src++; \
1250 b = *src++; \
1251 src += pix_pad;
1252 OPTIMIZED_FOR (int x = 0; x <= dst_len - 36; x += 36) {
1253 unsigned r, g, b;
1255 dst[BYTE_SWAP(0)] = r << 4;
1256 dst[BYTE_SWAP(1)] = r >> 4;
1257 dst[BYTE_SWAP(2)] = g;
1258 dst[BYTE_SWAP(3)] = b << 4;
1259 dst[4 + BYTE_SWAP(0)] = b >> 4;
1261 dst[4 + BYTE_SWAP(1)] = r;
1262 dst[4 + BYTE_SWAP(2)] = g << 4;
1263 dst[4 + BYTE_SWAP(3)] = g >> 4;
1264 dst[8 + BYTE_SWAP(0)] = b;
1266 dst[8 + BYTE_SWAP(1)] = r << 4;
1267 dst[8 + BYTE_SWAP(2)] = r >> 4;
1268 dst[8 + BYTE_SWAP(3)] = g;
1269 dst[12 + BYTE_SWAP(0)] = b << 4;
1270 dst[12 + BYTE_SWAP(1)] = b >> 4;
1272 dst[12 + BYTE_SWAP(2)] = r;
1273 dst[12 + BYTE_SWAP(3)] = g << 4;
1274 dst[16 + BYTE_SWAP(0)] = g >> 4;
1275 dst[16 + BYTE_SWAP(1)] = b;
1277 dst[16 + BYTE_SWAP(2)] = r << 4;
1278 dst[16 + BYTE_SWAP(3)] = r >> 4;
1279 dst[20 + BYTE_SWAP(0)] = g;
1280 dst[20 + BYTE_SWAP(1)] = b << 4;
1281 dst[20 + BYTE_SWAP(2)] = b >> 4;
1283 dst[20 + BYTE_SWAP(3)] = r;
1284 dst[24 + BYTE_SWAP(0)] = g << 4;
1285 dst[24 + BYTE_SWAP(1)] = g >> 4;
1286 dst[24 + BYTE_SWAP(2)] = b;
1288 dst[24 + BYTE_SWAP(3)] = r << 4;
1289 dst[28 + BYTE_SWAP(0)] = r >> 4;
1290 dst[28 + BYTE_SWAP(1)] = g;
1291 dst[28 + BYTE_SWAP(2)] = b << 4;
1292 dst[28 + BYTE_SWAP(3)] = b >> 4;
1294 dst[32 + BYTE_SWAP(0)] = r;
1295 dst[32 + BYTE_SWAP(1)] = g << 4;
1296 dst[32 + BYTE_SWAP(2)] = g >> 4;
1297 dst[32 + BYTE_SWAP(3)] = b;
1298 dst += 36;
1299 }
1300#undef FETCH_DATA
1301}
1302
1307static void vc_copylineRGBtoR12L(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len,
1308 int rshift, int gshift, int bshift) {
1309 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1310 vc_copylineRGB_AtoR12L(dst, src, dst_len, 0);
1311}
1312
1313static void vc_copylineRGBAtoR12L(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len,
1314 int rshift, int gshift, int bshift) {
1315 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1316 vc_copylineRGB_AtoR12L(dst, src, dst_len, 1);
1317}
1318
1319static void vc_copylineRGBAtoRG48(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len,
1320 int rshift, int gshift, int bshift) {
1321 UNUSED(rshift);
1322 UNUSED(gshift);
1323 UNUSED(bshift);
1324
1325 OPTIMIZED_FOR (int x = 0; x <= dst_len - 6; x += 6) {
1326 *dst++ = 0;
1327 *dst++ = *src++;
1328 *dst++ = 0;
1329 *dst++ = *src++;
1330 *dst++ = 0;
1331 *dst++ = *src++;
1332 src++;
1333 }
1334}
1335
1336static void vc_copylineRGBtoRG48(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len,
1337 int rshift, int gshift, int bshift) {
1338 UNUSED(rshift);
1339 UNUSED(gshift);
1340 UNUSED(bshift);
1341
1342 OPTIMIZED_FOR (int x = 0; x <= dst_len - 2; x += 2) {
1343 *dst++ = 0;
1344 *dst++ = *src++;
1345 }
1346}
1347
1354static void vc_copylineR12LtoRG48(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1355 int gshift, int bshift)
1356{
1357 enum {
1358 PIX_COUNT = 8,
1359 RG48_BPP = 6,
1360 OUT_BL_SZ = PIX_COUNT * RG48_BPP,
1361 };
1362 UNUSED(rshift);
1363 UNUSED(gshift);
1364 UNUSED(bshift);
1365 int x = 0;
1366 OPTIMIZED_FOR(; x < dst_len - OUT_BL_SZ + 1; x += OUT_BL_SZ)
1367 {
1368 //0
1369 //R
1370 *dst++ = src[BYTE_SWAP(0)] << 4;
1371 *dst++ = (src[BYTE_SWAP(1)] << 4) | (src[BYTE_SWAP(0)] >> 4);
1372 //G
1373 *dst++ = src[BYTE_SWAP(1)] & 0xF0;
1374 *dst++ = src[BYTE_SWAP(2)];
1375 //B
1376 *dst++ = src[BYTE_SWAP(3)] << 4;
1377 *dst++ = (src[4 + BYTE_SWAP(0)] << 4) | (src[BYTE_SWAP(3)] >> 4);
1378
1379 //1
1380 *dst++ = src[4 + BYTE_SWAP(0)] & 0xF0;
1381 *dst++ = src[4 + BYTE_SWAP(1)];
1382
1383 *dst++ = src[4 + BYTE_SWAP(2)] << 4;
1384 *dst++ = (src[4 + BYTE_SWAP(3)] << 4) | (src[4 + BYTE_SWAP(2)] >> 4);
1385
1386 *dst++ = src[4 + BYTE_SWAP(3)] & 0xF0;
1387 *dst++ = src[8 + BYTE_SWAP(0)];
1388
1389 //2
1390 *dst++ = src[8 + BYTE_SWAP(1)] << 4;
1391 *dst++ = (src[8 + BYTE_SWAP(2)] << 4) | (src[8 + BYTE_SWAP(1)] >> 4);
1392
1393 *dst++ = src[8 + BYTE_SWAP(2)] & 0xF0;
1394 *dst++ = src[8 + BYTE_SWAP(3)];
1395
1396 *dst++ = src[12 + BYTE_SWAP(0)] << 4;
1397 *dst++ = (src[12 + BYTE_SWAP(1)] << 4) | (src[12 + BYTE_SWAP(0)] >> 4);
1398
1399 //3
1400 *dst++ = src[12 + BYTE_SWAP(1)] & 0xF0;
1401 *dst++ = src[12 + BYTE_SWAP(2)];
1402
1403 *dst++ = src[12 + BYTE_SWAP(3)] << 4;
1404 *dst++ = (src[16 + BYTE_SWAP(0)] << 4) | (src[12 + BYTE_SWAP(3)] >> 4);
1405
1406 *dst++ = src[16 + BYTE_SWAP(0)] & 0xF0;
1407 *dst++ = src[16 + BYTE_SWAP(1)];
1408
1409 //4
1410 *dst++ = src[16 + BYTE_SWAP(2)] << 4;
1411 *dst++ = (src[16 + BYTE_SWAP(3)] << 4) | (src[16 + BYTE_SWAP(2)] >> 4);
1412
1413 *dst++ = src[16 + BYTE_SWAP(3)] & 0xF0;
1414 *dst++ = src[20 + BYTE_SWAP(0)];
1415
1416 *dst++ = src[20 + BYTE_SWAP(1)] << 4;
1417 *dst++ = (src[20 + BYTE_SWAP(2)] << 4) | (src[20 + BYTE_SWAP(1)] >> 4);
1418
1419 //5
1420 *dst++ = src[20 + BYTE_SWAP(2)] & 0xF0;
1421 *dst++ = src[20 + BYTE_SWAP(3)];
1422
1423 *dst++ = src[24 + BYTE_SWAP(0)] << 4;
1424 *dst++ = (src[24 + BYTE_SWAP(1)] << 4) | (src[24 + BYTE_SWAP(0)] >> 4);
1425
1426 *dst++ = src[24 + BYTE_SWAP(1)] & 0xF0;
1427 *dst++ = src[24 + BYTE_SWAP(2)];
1428
1429 //6
1430 *dst++ = src[24 + BYTE_SWAP(3)] << 4;
1431 *dst++ = (src[28 + BYTE_SWAP(0)] << 4) | (src[24 + BYTE_SWAP(3)] >> 4);
1432
1433 *dst++ = src[28 + BYTE_SWAP(0)] & 0xF0;
1434 *dst++ = src[28 + BYTE_SWAP(1)];
1435
1436 *dst++ = src[28 + BYTE_SWAP(2)] << 4;
1437 *dst++ = (src[28 + BYTE_SWAP(3)] << 4) | (src[28 + BYTE_SWAP(2)] >> 4);
1438
1439 //7
1440 *dst++ = src[28 + BYTE_SWAP(3)] & 0xF0;
1441 *dst++ = src[32 + BYTE_SWAP(0)];
1442
1443 *dst++ = src[32 + BYTE_SWAP(1)] << 4;
1444 *dst++ = (src[32 + BYTE_SWAP(2)] << 4) | (src[32 + BYTE_SWAP(1)] >> 4);
1445
1446 *dst++ = src[32 + BYTE_SWAP(2)] & 0xF0;
1447 *dst++ = src[32 + BYTE_SWAP(3)];
1448
1449 src += 36;
1450 }
1451 if (x == dst_len) {
1452 return;
1453 }
1454 // compute last incomplete block if dst_len % OUT_BL_SZ != 0, not
1455 // writting past the requested dst_len
1456 unsigned char tmp_buf[OUT_BL_SZ];
1457 vc_copylineR12LtoRG48(tmp_buf, src, OUT_BL_SZ, rshift, gshift, bshift);
1458 memcpy(dst, tmp_buf, dst_len - x);
1459}
1460
1461static void vc_copylineR12LtoY416(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1462 int gshift, int bshift)
1463{
1464 enum {
1465 D_DEPTH = 16,
1466 };
1467 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1468 assert((uintptr_t) dst % sizeof(uint16_t) == 0);
1469 const struct color_coeffs *cfs = get_color_coeffs(D_DEPTH);
1470 uint16_t *d = (void *) dst;
1471
1472#define WRITE_RES \
1473 u = (RGB_TO_CB(cfs, r, g, b) >> COMP_BASE) + \
1474 (1 << (D_DEPTH - 1)); \
1475 *d++ = CLAMP_LIMITED_CBCR(u, D_DEPTH); \
1476 y = (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) + \
1477 (1 << (D_DEPTH - 4)); \
1478 *d++ = CLAMP_LIMITED_Y(y, D_DEPTH); \
1479 v = (RGB_TO_CR(cfs, r, g, b) >> COMP_BASE) + \
1480 (1 << (D_DEPTH - 1)); \
1481 *d++ = CLAMP_LIMITED_CBCR(v, D_DEPTH); \
1482 *d++ = 0xFFFFU;
1483
1484 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 64) {
1485 comp_type_t r, g, b;
1486 comp_type_t y, u, v;
1487
1488 r = (src[BYTE_SWAP(1)] & 0xFU) << 12U | src[BYTE_SWAP(0)] << 4U; //0
1489 g = src[BYTE_SWAP(2)] << 8U | (src[BYTE_SWAP(1)] & 0xF0U);
1490 b = (src[4 + BYTE_SWAP(0)] & 0xFU) << 12U | src[BYTE_SWAP(3)] << 4U;
1491 WRITE_RES
1492 r = src[4 + BYTE_SWAP(1)] << 8U | (src[4 + BYTE_SWAP(0)] & 0xF0U); //1
1493 g = (src[4 + BYTE_SWAP(3)] & 0xFU) << 12U | (src[4 + BYTE_SWAP(2)]) << 4U;
1494 b = src[8 + BYTE_SWAP(0)] << 8U | (src[4 + BYTE_SWAP(3)] & 0xF0U);
1495 WRITE_RES
1496 r = (src[8 + BYTE_SWAP(2)] & 0xFU) << 12U |src[8 + BYTE_SWAP(1)] << 4U; //2
1497 g = src[8 + BYTE_SWAP(3)] << 8U | (src[8 + BYTE_SWAP(2)] & 0xF0U);
1498 b = (src[12 + BYTE_SWAP(1)] & 0xFU) << 12U | src[12 + BYTE_SWAP(0)] << 4U;
1499 WRITE_RES
1500 r = src[12 + BYTE_SWAP(2)] << 8U | (src[12 + BYTE_SWAP(1)] & 0xF0U); //3
1501 g = (src[16 + BYTE_SWAP(0)] & 0xFU) << 12U | src[12 + BYTE_SWAP(3)] << 4U;
1502 b = src[16 + BYTE_SWAP(1)] << 8U | (src[16 + BYTE_SWAP(0)] & 0xF0U);
1503 WRITE_RES
1504 r = (src[16 + BYTE_SWAP(3)] & 0xFU) << 12U | src[16 + BYTE_SWAP(2)] << 4U; //4
1505 g = src[20 + BYTE_SWAP(0)] << 8U | (src[16 + BYTE_SWAP(3)] & 0xF0U);
1506 b = (src[20 + BYTE_SWAP(2)] & 0xFU) << 12U | src[20 + BYTE_SWAP(1)] << 4U;
1507 WRITE_RES
1508 r = src[20 + BYTE_SWAP(3)] << 8U | (src[20 + BYTE_SWAP(2)] & 0xF0U); //5
1509 g = (src[24 + BYTE_SWAP(1)] & 0xFU) << 12U | src[24 + BYTE_SWAP(0)] << 4U;
1510 b = src[24 + BYTE_SWAP(2)] << 8U | (src[24 + BYTE_SWAP(1)] & 0xF0U);
1511 WRITE_RES
1512 r = (src[28 + BYTE_SWAP(0)] & 0xFU) << 12U | src[24 + BYTE_SWAP(3)] << 4U; //6
1513 g = src[28 + BYTE_SWAP(1)] << 8U | (src[28 + BYTE_SWAP(0)] & 0xF0U);
1514 b = (src[28 + BYTE_SWAP(3)] & 0xFU) << 12U | src[28 + BYTE_SWAP(2)] << 4U;
1515 WRITE_RES
1516 r = src[32 + BYTE_SWAP(0)] << 8U | (src[28 + BYTE_SWAP(3)] & 0xF0U); //7
1517 g = (src[32 + BYTE_SWAP(2)] & 0xFU) << 12U | src[32 + BYTE_SWAP(1)] << 4U;
1518 b = src[32 + BYTE_SWAP(3)] << 8U | (src[32 + BYTE_SWAP(2)] & 0xF0U);
1519 WRITE_RES
1520
1521 src += 36;
1522 }
1523#undef WRITE_RES
1524}
1525
1526static void
1527vc_copylineR12LtoUYVY(unsigned char *__restrict dst,
1528 const unsigned char *__restrict src, int dst_len,
1529 int rshift, int gshift, int bshift)
1530{
1531 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1532 enum {
1533 D_DPTH = 8,
1534 YOFF = 1 << (D_DPTH - 4),
1535 COFF = 1 << (D_DPTH - 1),
1536 PX_PER_BLK_IN = 8,
1537 UYVY_BPP = 2,
1538 DST_BYTE_SZ = PX_PER_BLK_IN * UYVY_BPP,
1539 };
1540 const struct color_coeffs *cfs = get_color_coeffs(D_DPTH);
1541 uint8_t *d = (void *) dst;
1542#define WRITE_RES \
1543 { \
1544 comp_type_t u = ((RGB_TO_CB(cfs, r1, g1, b1) + \
1545 RGB_TO_CB(cfs, r2, g2, b2)) >> \
1546 (COMP_BASE + D_DPTH + 1)) + \
1547 COFF; \
1548 *d++ = CLAMP_LIMITED_CBCR(u, D_DPTH); \
1549 comp_type_t y = (RGB_TO_Y(cfs, r1, g1, b1) >> \
1550 (COMP_BASE + D_DPTH)) + \
1551 YOFF; \
1552 *d++ = CLAMP_LIMITED_Y(y, D_DPTH); \
1553 comp_type_t v = ((RGB_TO_CR(cfs, r1, g1, b1) + \
1554 RGB_TO_CR(cfs, r2, g2, b2)) >> \
1555 (COMP_BASE + D_DPTH + 1)) + \
1556 COFF; \
1557 *d++ = CLAMP_LIMITED_CBCR(v, D_DPTH); \
1558 y = (RGB_TO_Y(cfs, r2, g2, b2) >> \
1559 (COMP_BASE + D_DPTH)) + \
1560 YOFF; \
1561 *d++ = CLAMP_LIMITED_Y(y, D_DPTH); \
1562 }
1563 OPTIMIZED_FOR(int x = 0; x < dst_len; x += DST_BYTE_SZ)
1564 {
1565 comp_type_t r1 = (src[BYTE_SWAP(1)] & 0xFU) << 12U |
1566 src[BYTE_SWAP(0)] << 4U; // 0
1567 comp_type_t g1 =
1568 src[BYTE_SWAP(2)] << 8U | (src[BYTE_SWAP(1)] & 0xF0U);
1569 comp_type_t b1 = (src[4 + BYTE_SWAP(0)] & 0xFU) << 12U |
1570 src[BYTE_SWAP(3)] << 4U;
1571 comp_type_t r2 = src[4 + BYTE_SWAP(1)] << 8U |
1572 (src[4 + BYTE_SWAP(0)] & 0xF0U); // 1
1573 comp_type_t g2 = (src[4 + BYTE_SWAP(3)] & 0xFU) << 12U |
1574 (src[4 + BYTE_SWAP(2)]) << 4U;
1575 comp_type_t b2 = src[8 + BYTE_SWAP(0)] << 8U |
1576 (src[4 + BYTE_SWAP(3)] & 0xF0U);
1577 WRITE_RES
1578 r1 = (src[8 + BYTE_SWAP(2)] & 0xFU) << 12U |
1579 src[8 + BYTE_SWAP(1)] << 4U; // 2
1580 g1 = src[8 + BYTE_SWAP(3)] << 8U |
1581 (src[8 + BYTE_SWAP(2)] & 0xF0U);
1582 b1 = (src[12 + BYTE_SWAP(1)] & 0xFU) << 12U |
1583 src[12 + BYTE_SWAP(0)] << 4U;
1584 r2 = src[12 + BYTE_SWAP(2)] << 8U |
1585 (src[12 + BYTE_SWAP(1)] & 0xF0U); // 3
1586 g2 = (src[16 + BYTE_SWAP(0)] & 0xFU) << 12U |
1587 src[12 + BYTE_SWAP(3)] << 4U;
1588 b2 = src[16 + BYTE_SWAP(1)] << 8U |
1589 (src[16 + BYTE_SWAP(0)] & 0xF0U);
1590 WRITE_RES
1591 r1 = (src[16 + BYTE_SWAP(3)] & 0xFU) << 12U |
1592 src[16 + BYTE_SWAP(2)] << 4U; // 4
1593 g1 = src[20 + BYTE_SWAP(0)] << 8U |
1594 (src[16 + BYTE_SWAP(3)] & 0xF0U);
1595 b1 = (src[20 + BYTE_SWAP(2)] & 0xFU) << 12U |
1596 src[20 + BYTE_SWAP(1)] << 4U;
1597 r2 = src[20 + BYTE_SWAP(3)] << 8U |
1598 (src[20 + BYTE_SWAP(2)] & 0xF0U); // 5
1599 g2 = (src[24 + BYTE_SWAP(1)] & 0xFU) << 12U |
1600 src[24 + BYTE_SWAP(0)] << 4U;
1601 b2 = src[24 + BYTE_SWAP(2)] << 8U |
1602 (src[24 + BYTE_SWAP(1)] & 0xF0U);
1603 WRITE_RES
1604 r1 = (src[28 + BYTE_SWAP(0)] & 0xFU) << 12U |
1605 src[24 + BYTE_SWAP(3)] << 4U; // 6
1606 g1 = src[28 + BYTE_SWAP(1)] << 8U |
1607 (src[28 + BYTE_SWAP(0)] & 0xF0U);
1608 b1 = (src[28 + BYTE_SWAP(3)] & 0xFU) << 12U |
1609 src[28 + BYTE_SWAP(2)] << 4U;
1610 r2 = src[32 + BYTE_SWAP(0)] << 8U |
1611 (src[28 + BYTE_SWAP(3)] & 0xF0U); // 7
1612 g2 = (src[32 + BYTE_SWAP(2)] & 0xFU) << 12U |
1613 src[32 + BYTE_SWAP(1)] << 4U;
1614 b2 = src[32 + BYTE_SWAP(3)] << 8U |
1615 (src[32 + BYTE_SWAP(2)] & 0xF0U);
1616 WRITE_RES
1617
1618 src += 36;
1619 }
1620#undef WRITE_RES
1621}
1622
1623static void vc_copylineR12LtoR10k(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1624 int gshift, int bshift)
1625{
1626 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1627 OPTIMIZED_FOR (int x = 0; x <= dst_len - 32; x += 32) {
1628 //0
1629 // Rh8 (pattern repeating in each group)
1630 *dst++ = (src[BYTE_SWAP(1)] << 4) | (src[BYTE_SWAP(0)] >> 4);
1631 // Rl2 + Gh6
1632 *dst++ = (src[BYTE_SWAP(0)] & 0xC) << 4 | src[BYTE_SWAP(2)] >> 2;
1633 // Gl4 + Bh4
1634 *dst++ = src[BYTE_SWAP(2)] << 6 | (src[BYTE_SWAP(1)] & 0xC0) >> 2 | // G
1635 (src[4 + BYTE_SWAP(0)] & 0xF);
1636 // Blo6
1637 *dst++ = src[BYTE_SWAP(3)];
1638 // 1
1639 *dst++ = src[4 + BYTE_SWAP(1)];
1640 *dst++ = (src[4 + BYTE_SWAP(0)] & 0xC0) | (src[4 + BYTE_SWAP(3)] & 0xF) << 2 | src[4 + BYTE_SWAP(2)] >> 6;
1641 *dst++ = (src[4 + BYTE_SWAP(2)] & 0x3C) << 2 | src[8 + BYTE_SWAP(0)] >> 4;
1642 *dst++ = src[8 + BYTE_SWAP(0)] << 4 | (src[4 + BYTE_SWAP(0)] & 0xF0) >> 4;
1643 // 2
1644 *dst++ = (src[8 + BYTE_SWAP(2)] << 4) | (src[8 + BYTE_SWAP(1)] >> 4);
1645 *dst++ = (src[8 + BYTE_SWAP(1)] & 0xC) << 4 | src[8 + BYTE_SWAP(3)] >> 2; // Rl2 + Gh6
1646 *dst++ = src[8 + BYTE_SWAP(3)] << 6 | (src[8 + BYTE_SWAP(2)] & 0xC0) >> 2 | (src[12 + BYTE_SWAP(1)] & 0xF); // Gl4+Bh4
1647 *dst++ = src[12 + BYTE_SWAP(0)];
1648 // 3
1649 *dst++ = src[12 + BYTE_SWAP(2)]; // Rh8
1650 *dst++ = (src[12 + BYTE_SWAP(1)] & 0xC0) | ((src[16 + BYTE_SWAP(0)] & 0xF) << 2) | src[12 + BYTE_SWAP(3)] >> 6; // Rl2 + Gh6
1651 *dst++ = (src[12 + BYTE_SWAP(3)] & 0x3C) << 2 | src[16 + BYTE_SWAP(1)] >> 4; // Gl4 + Bh4
1652 *dst++ = src[16 + BYTE_SWAP(1)] << 4 | (src[16 + BYTE_SWAP(0)] & 0xF0) >> 4;
1653 // 4
1654 *dst++ = (src[16 + BYTE_SWAP(3)] << 4) | (src[16 + BYTE_SWAP(2)] >> 4);
1655 *dst++ = (src[16 + BYTE_SWAP(2)] & 0xC) << 4 | src[20 + BYTE_SWAP(0)] >> 2;
1656 *dst++ = src[20 + BYTE_SWAP(0)] << 6 | (src[16 + BYTE_SWAP(3)] & 0xC0) >> 2 | (src[20 + BYTE_SWAP(2)] & 0xF);
1657 *dst++ = src[20 + BYTE_SWAP(1)];
1658 // 5
1659 *dst++ = src[20 + BYTE_SWAP(3)];
1660 *dst++ = (src[20 + BYTE_SWAP(2)] & 0xC0) | (src[24 + BYTE_SWAP(1)] & 0xF) << 2 | src[24 + BYTE_SWAP(0)] >> 6;
1661 *dst++ = (src[24 + BYTE_SWAP(0)] & 0x3C) << 2 | src[24 + BYTE_SWAP(2)] >> 4;
1662 *dst++ = src[24 + BYTE_SWAP(2)] << 4 | src[24 + BYTE_SWAP(1)] >> 4;
1663 // 6
1664 *dst++ = (src[28 + BYTE_SWAP(0)] << 4) | (src[24 + BYTE_SWAP(3)] >> 4);
1665 *dst++ = (src[24 + BYTE_SWAP(3)] & 0xC) << 4 | src[28 + BYTE_SWAP(1)] >> 2;
1666 *dst++ = src[28 + BYTE_SWAP(1)] << 6 | (src[28 + BYTE_SWAP(0)] & 0xC0) >> 2 | (src[28 + BYTE_SWAP(3)] & 0xF);
1667 *dst++ = src[28 + BYTE_SWAP(2)];
1668 // 7
1669 *dst++ = src[32 + BYTE_SWAP(0)];
1670 *dst++ = (src[28 + BYTE_SWAP(3)] & 0xC0) | (src[32 + BYTE_SWAP(2)] & 0xF) << 2 | (src[32 + BYTE_SWAP(1)] >> 6);
1671 *dst++ = (src[32 + BYTE_SWAP(1)] & 0x3C) << 2 | src[32 + BYTE_SWAP(3)] >> 4;
1672 *dst++ = src[32 + BYTE_SWAP(3)] << 4 | src[32 + BYTE_SWAP(2)] >> 4;
1673
1674 src += 36;
1675 }
1676}
1677
1684static void vc_copylineRG48toR12L(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1685 int gshift, int bshift)
1686{
1687 UNUSED(rshift);
1688 UNUSED(gshift);
1689 UNUSED(bshift);
1690 OPTIMIZED_FOR (int x = 0; x <= dst_len - 36; x += 36) {
1691 //0
1692 dst[BYTE_SWAP(0)] = src[0] >> 4;
1693 dst[BYTE_SWAP(0)] |= src[1] << 4;
1694 dst[BYTE_SWAP(1)] = src[1] >> 4;
1695 src += 2;
1696
1697 dst[BYTE_SWAP(1)] |= src[0] & 0xF0;
1698 dst[BYTE_SWAP(2)] = src[1];
1699 src += 2;
1700
1701 dst[BYTE_SWAP(3)] = src[0] >> 4;
1702 dst[BYTE_SWAP(3)] |= src[1] << 4;
1703 dst[4 + BYTE_SWAP(0)] = src[1] >> 4;
1704 src += 2;
1705
1706 //1
1707 dst[4 + BYTE_SWAP(0)] |= src[0] & 0xF0;
1708 dst[4 + BYTE_SWAP(1)] = src[1];
1709 src += 2;
1710
1711 dst[4 + BYTE_SWAP(2)] = src[0] >> 4;
1712 dst[4 + BYTE_SWAP(2)] |= src[1] << 4;
1713 dst[4 + BYTE_SWAP(3)] = src[1] >> 4;
1714 src += 2;
1715
1716 dst[4 + BYTE_SWAP(3)] |= src[0] & 0xF0;
1717 dst[8 + BYTE_SWAP(0)] = src[1];
1718 src += 2;
1719
1720 //2
1721 dst[8 + BYTE_SWAP(1)] = src[0] >> 4;
1722 dst[8 + BYTE_SWAP(1)] |= src[1] << 4;
1723 dst[8 + BYTE_SWAP(2)] = src[1] >> 4;
1724 src += 2;
1725
1726 dst[8 + BYTE_SWAP(2)] |= src[0] & 0xF0;
1727 dst[8 + BYTE_SWAP(3)] = src[1];
1728 src += 2;
1729
1730 dst[12 + BYTE_SWAP(0)] = src[0] >> 4;
1731 dst[12 + BYTE_SWAP(0)] |= src[1] << 4;
1732 dst[12 + BYTE_SWAP(1)] = src[1] >> 4;
1733 src += 2;
1734
1735 //3
1736 dst[12 + BYTE_SWAP(1)] |= src[0] & 0xF0;
1737 dst[12 + BYTE_SWAP(2)] = src[1];
1738 src += 2;
1739
1740 dst[12 + BYTE_SWAP(3)] = src[0] >> 4;
1741 dst[12 + BYTE_SWAP(3)] |= src[1] << 4;
1742 dst[16 + BYTE_SWAP(0)] = src[1] >> 4;
1743 src += 2;
1744
1745 dst[16 + BYTE_SWAP(0)] |= src[0] & 0xF0;
1746 dst[16 + BYTE_SWAP(1)] = src[1];
1747 src += 2;
1748
1749 //4
1750 dst[16 + BYTE_SWAP(2)] = src[0] >> 4;
1751 dst[16 + BYTE_SWAP(2)] |= src[1] << 4;
1752 dst[16 + BYTE_SWAP(3)] = src[1] >> 4;
1753 src += 2;
1754
1755 dst[16 + BYTE_SWAP(3)] |= src[0] & 0xF0;
1756 dst[20 + BYTE_SWAP(0)] = src[1];
1757 src += 2;
1758
1759 dst[20 + BYTE_SWAP(1)] = src[0] >> 4;
1760 dst[20 + BYTE_SWAP(1)] |= src[1] << 4;
1761 dst[20 + BYTE_SWAP(2)] = src[1] >> 4;
1762 src += 2;
1763
1764 //5
1765 dst[20 + BYTE_SWAP(2)] |= src[0] & 0xF0;
1766 dst[20 + BYTE_SWAP(3)] = src[1];
1767 src += 2;
1768
1769 dst[24 + BYTE_SWAP(0)] = src[0] >> 4;
1770 dst[24 + BYTE_SWAP(0)] |= src[1] << 4;
1771 dst[24 + BYTE_SWAP(1)] = src[1] >> 4;
1772 src += 2;
1773
1774 dst[24 + BYTE_SWAP(1)] |= src[0] & 0xF0;
1775 dst[24 + BYTE_SWAP(2)] = src[1];
1776 src += 2;
1777
1778 //6
1779 dst[24 + BYTE_SWAP(3)] = src[0] >> 4;
1780 dst[24 + BYTE_SWAP(3)] |= src[1] << 4;
1781 dst[28 + BYTE_SWAP(0)] = src[1] >> 4;
1782 src += 2;
1783
1784 dst[28 + BYTE_SWAP(0)] |= src[0] & 0xF0;
1785 dst[28 + BYTE_SWAP(1)] = src[1];
1786 src += 2;
1787
1788 dst[28 + BYTE_SWAP(2)] = src[0] >> 4;
1789 dst[28 + BYTE_SWAP(2)] |= src[1] << 4;
1790 dst[28 + BYTE_SWAP(3)] = src[1] >> 4;
1791 src += 2;
1792
1793 //7
1794 dst[28 + BYTE_SWAP(3)] |= src[0] & 0xF0;
1795 dst[32 + BYTE_SWAP(0)] = src[1];
1796 src += 2;
1797
1798 dst[32 + BYTE_SWAP(1)] = src[0] >> 4;
1799 dst[32 + BYTE_SWAP(1)] |= src[1] << 4;
1800 dst[32 + BYTE_SWAP(2)] = src[1] >> 4;
1801 src += 2;
1802
1803 dst[32 + BYTE_SWAP(2)] |= src[0] & 0xF0;
1804 dst[32 + BYTE_SWAP(3)] = src[1];
1805 src += 2;
1806
1807 dst += 36;
1808 }
1809}
1810
1811static void vc_copylineY416toR12L(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1812 int gshift, int bshift)
1813{
1814 enum {
1815 S_DEPTH = 16,
1816 D_DEPTH = 12,
1817 };
1818 const struct color_coeffs *cfs = get_color_coeffs(S_DEPTH);
1819#define GET_NEXT \
1820 u = *in++ - (1 << (S_DEPTH - 1)); \
1821 y = Y_SCALE(S_DEPTH) * (*in++ - (1 << (S_DEPTH - 4))); \
1822 v = *in++ - (1 << (S_DEPTH - 1)); \
1823 in++; \
1824 r = YCBCR_TO_R(cfs, y, u, v) >> (COMP_BASE + 4U); \
1825 g = YCBCR_TO_G(cfs, y, u, v) >> (COMP_BASE + 4U); \
1826 b = YCBCR_TO_B(cfs, y, u, v) >> (COMP_BASE + 4U); \
1827 r = CLAMP_FULL(r, D_DEPTH); \
1828 g = CLAMP_FULL(g, D_DEPTH); \
1829 b = CLAMP_FULL(b, D_DEPTH);
1830
1831 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1832 assert((uintptr_t) src % 2 == 0);
1833 const uint16_t *in = (const void *) src;
1834 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 36) {
1835 comp_type_t y, u, v, r, g, b;
1836 comp_type_t tmp;
1837
1838 GET_NEXT // 0
1839 dst[BYTE_SWAP(0)] = r & 0xFFU;
1840 dst[BYTE_SWAP(1)] = (g & 0xFU) << 4U | r >> 8U;
1841 dst[BYTE_SWAP(2)] = g >> 4U;
1842 dst[BYTE_SWAP(3)] = b & 0xFFU;
1843 tmp = b >> 8U;
1844
1845 GET_NEXT // 1
1846 dst[4 + BYTE_SWAP(0)] = (r & 0xFU) << 4U | tmp;
1847 dst[4 + BYTE_SWAP(1)] = r >> 4U;
1848 dst[4 + BYTE_SWAP(2)] = g & 0xFFU;
1849 dst[4 + BYTE_SWAP(3)] = (b & 0xFU) << 4U | g >> 8U;
1850
1851 dst[8 + BYTE_SWAP(0)] = b >> 4U;
1852 GET_NEXT // 2
1853 dst[8 + BYTE_SWAP(1)] = r & 0xFFu;
1854 dst[8 + BYTE_SWAP(2)] = (g & 0xFU) << 4U | r >> 8U;
1855 dst[8 + BYTE_SWAP(3)] = g >> 4U;
1856
1857 dst[12 + BYTE_SWAP(0)] = b & 0xFFU;
1858 tmp = b >> 8U;
1859 GET_NEXT // 3
1860 dst[12 + BYTE_SWAP(1)] = (r & 0xFU) << 4U | tmp;
1861 dst[12 + BYTE_SWAP(2)] = r >> 4U;
1862 dst[12 + BYTE_SWAP(3)] = g & 0xFFU;
1863
1864 dst[16 + BYTE_SWAP(0)] = (b & 0xFU) << 4U | g >> 8U;
1865 dst[16 + BYTE_SWAP(1)] = b >> 4U;
1866 GET_NEXT // 4
1867 dst[16 + BYTE_SWAP(2)] = r & 0xFFU;
1868 dst[16 + BYTE_SWAP(3)] = (g & 0xFU) << 4U | r >> 8U;
1869
1870 dst[20 + BYTE_SWAP(0)] = g >> 4U;
1871 dst[20 + BYTE_SWAP(1)] = b & 0xFFU;
1872 tmp = b >> 8U;
1873 GET_NEXT // 5
1874 dst[20 + BYTE_SWAP(2)] = (r & 0xFU) << 4U | tmp;
1875 dst[20 + BYTE_SWAP(3)] = r >> 4U;
1876
1877 dst[24 + BYTE_SWAP(0)] = g & 0xFFU;
1878 dst[24 + BYTE_SWAP(1)] = (b & 0xFU) << 4U | g >> 8U;
1879 dst[24 + BYTE_SWAP(2)] = b >> 4U;
1880 GET_NEXT // 6
1881 dst[24 + BYTE_SWAP(3)] = r & 0xFFU;
1882
1883 dst[28 + BYTE_SWAP(0)] = (g & 0xFU) << 4U | r >> 8U;
1884 dst[28 + BYTE_SWAP(1)] = g >> 4U;
1885 dst[28 + BYTE_SWAP(2)] = b & 0xFFU;
1886 tmp = b >> 8U;
1887 GET_NEXT // 7
1888 dst[28 + BYTE_SWAP(3)] = (r & 0xFU) << 4U | tmp;
1889
1890 dst[32 + BYTE_SWAP(0)] = r >> 4U;
1891 dst[32 + BYTE_SWAP(1)] = g & 0xFFU;
1892 dst[32 + BYTE_SWAP(2)] = (b & 0xFU) << 4U | g >> 8U;
1893 dst[32 + BYTE_SWAP(3)] = b >> 4U;
1894
1895 dst += 36;
1896 }
1897#undef GET_NEXT
1898}
1899
1900static void vc_copylineY416toR10k(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1901 int gshift, int bshift)
1902{
1903 enum {
1904 S_DEPTH = 16,
1905 };
1906 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1907 assert((uintptr_t) src % 2 == 0);
1908 const struct color_coeffs *cfs = get_color_coeffs(S_DEPTH);
1909 const uint16_t *in = (const void *) src;
1910 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 4) {
1911 comp_type_t y, u, v, r, g, b;
1912
1913 u = *in++ - (1 << (S_DEPTH - 1));
1914 y = Y_SCALE(S_DEPTH) * (*in++ - (1 << (S_DEPTH - 4)));
1915 v = *in++ - (1 << (S_DEPTH - 1));
1916 in++;
1917 r = YCBCR_TO_R(cfs, y, u, v) >> (COMP_BASE + 6U);
1918 g = YCBCR_TO_G(cfs, y, u, v) >> (COMP_BASE + 6U);
1919 b = YCBCR_TO_B(cfs, y, u, v) >> (COMP_BASE + 6U);
1920 r = CLAMP_FULL(r, 10);
1921 g = CLAMP_FULL(g, 10);
1922 b = CLAMP_FULL(b, 10);
1923
1924 *dst++ = r >> 2U;
1925 *dst++ = (r & 0x3U) << 6U | g >> 4U;
1926 *dst++ = (g & 0xFU) << 4U | b >> 6U;
1927 *dst++ = (b & 0x3FU) << 2U;
1928 }
1929}
1930
1931static void vc_copylineY416toRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1932 int gshift, int bshift)
1933{
1934 enum {
1935 S_DEPTH = 16,
1936 };
1937 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
1938 assert((uintptr_t) src % 2 == 0);
1939 const struct color_coeffs *cfs = get_color_coeffs(S_DEPTH);
1940 const uint16_t *in = (const void *) src;
1941 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 3) {
1942 comp_type_t y, u, v, r, g, b;
1943
1944 u = *in++ - (1 << (S_DEPTH - 1));
1945 y = Y_SCALE(S_DEPTH) * (*in++ - (1 << (S_DEPTH - 4)));
1946 v = *in++ - (1 << (S_DEPTH - 1));
1947 in++;
1948 r = YCBCR_TO_R(cfs, y, u, v) >> (COMP_BASE + 8U);
1949 g = YCBCR_TO_G(cfs, y, u, v) >> (COMP_BASE + 8U);
1950 b = YCBCR_TO_B(cfs, y, u, v) >> (COMP_BASE + 8U);
1951 r = CLAMP_FULL(r, 8);
1952 g = CLAMP_FULL(g, 8);
1953 b = CLAMP_FULL(b, 8);
1954
1955 *dst++ = r;
1956 *dst++ = g;
1957 *dst++ = b;
1958 }
1959}
1960
1961static void vc_copylineY416toRGBA(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1962 int gshift, int bshift)
1963{
1964 enum {
1965 S_DEPTH = 16,
1966 };
1967 assert((uintptr_t) src % 2 == 0);
1968 assert((uintptr_t) dst % 4 == 0);
1969 const struct color_coeffs *cfs = get_color_coeffs(S_DEPTH);
1970 const uint16_t *in = (const void *) src;
1971 uint32_t *out = (void *) dst;
1972 const uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
1973 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 4) {
1974 comp_type_t y, u, v, r, g, b;
1975
1976 u = *in++ - (1 << (S_DEPTH - 1));
1977 y = Y_SCALE(S_DEPTH) * (*in++ - (1 << (S_DEPTH - 4)));
1978 v = *in++ - (1 << (S_DEPTH - 1));
1979 in++;
1980 r = YCBCR_TO_R(cfs, y, u, v) >> (COMP_BASE + 8U);
1981 g = YCBCR_TO_G(cfs, y, u, v) >> (COMP_BASE + 8U);
1982 b = YCBCR_TO_B(cfs, y, u, v) >> (COMP_BASE + 8U);
1983 r = CLAMP_FULL(r, 8);
1984 g = CLAMP_FULL(g, 8);
1985 b = CLAMP_FULL(b, 8);
1986
1987 *out++ = alpha_mask | r << rshift | g << gshift | b << bshift;
1988 }
1989}
1990
1991static void vc_copylineRG48toR10k(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
1992 int gshift, int bshift)
1993{
1994 UNUSED(rshift);
1995 UNUSED(gshift);
1996 UNUSED(bshift);
1997 assert((uintptr_t) src % sizeof(uint16_t) == 0);
1998 assert((uintptr_t) dst % sizeof(uint32_t) == 0);
1999 const uint16_t *in = (const uint16_t *)(const void *) src;
2000 uint32_t *out = (uint32_t *)(void *) dst;
2001 OPTIMIZED_FOR (int x = 0; x <= dst_len - 4; x += 4) {
2002#ifdef WORDS_BIGENDIAN
2003 *out++ = r << 22U | g << 12U | b << 2U | 0x3FU;
2004#else
2005 unsigned r = *in++ >> 6;
2006 unsigned g = *in++ >> 6;
2007 unsigned b = *in++ >> 6;
2008 // B5-B0 XX | G3-G0 B9-B6 | R1-R0 G9-G4 | R9-R2
2009 *out++ = (b & 0x3FU) << 26U | 0x3000000U | (g & 0xFU) << 20U | (b >> 6U) << 16U | (r & 0x3U) << 14U | (g >> 4U) << 8U | r >> 2U;
2010#endif
2011 }
2012}
2013
2014static void vc_copylineRG48toRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2015 int gshift, int bshift)
2016{
2017 UNUSED(rshift);
2018 UNUSED(gshift);
2019 UNUSED(bshift);
2020 OPTIMIZED_FOR (int x = 0; x <= dst_len - 3; x += 3) {
2021 *dst++ = src[1];
2022 *dst++ = src[3];
2023 *dst++ = src[5];
2024 src += 6;
2025 }
2026}
2027
2028static void vc_copylineRG48toRGBA(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2029 int gshift, int bshift)
2030{
2031 assert((uintptr_t) dst % sizeof(uint32_t) == 0);
2032 uint32_t *dst32 = (uint32_t *)(void *) dst;
2033 uint32_t alpha_mask = 0xFFFFFFFFU ^ (0xFFU << rshift) ^ (0xFFU << gshift) ^ (0xFFU << bshift);
2034 OPTIMIZED_FOR (int x = 0; x <= dst_len - 4; x += 4) {
2035 *dst32++ = alpha_mask | src[1] << rshift | src[3] << gshift | src[5] << bshift;
2036 src += 6;
2037 }
2038}
2039
2044static void vc_copylineRGBtoUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2045 int gshift, int bshift)
2046{
2047 UNUSED(rshift);
2048 UNUSED(gshift);
2049 UNUSED(bshift);
2050 vc_copylineToUYVY(dst, src, dst_len, 0, 1, 2, 3);
2051}
2052
2059void vc_copylineRGBtoUYVY_SSE(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2060 int gshift, int bshift) {
2061#ifdef __SSSE3__
2062 __m128i rgb;
2063 __m128i yuv;
2064
2065 __m128i r;
2066 __m128i g;
2067 __m128i b;
2068
2069 __m128i y;
2070 __m128i u;
2071 __m128i v;
2072
2073 //BB BB BB BB GR GR GR GR
2074 __m128i shuffle = _mm_setr_epi8(0, 1, 3, 4, 6, 7, 9, 10, 2, 2, 5, 5, 8, 8, 11, 11);
2075 __m128i mask = _mm_setr_epi16(0x00FF, 0x00FF, 0x00FF, 0x00FF, 0, 0, 0, 0);
2076 __m128i lowmask = _mm_setr_epi16(0, 0, 0, 0, 0x00FF, 0x00FF, 0x00FF, 0x00FF);
2077 __m128i zero = _mm_set1_epi16(0);
2078
2079 __m128i yrf = _mm_set1_epi16(23);
2080 __m128i ygf = _mm_set1_epi16(79);
2081 __m128i ybf = _mm_set1_epi16(8);
2082
2083 __m128i urf = _mm_set1_epi16(13);
2084 __m128i ugf = _mm_set1_epi16(43);
2085 __m128i ubf = _mm_set1_epi16(56);
2086
2087 __m128i vrf = _mm_set1_epi16(56);
2088 __m128i vgf = _mm_set1_epi16(51);
2089 __m128i vbf = _mm_set1_epi16(5);
2090
2091 __m128i yadd = _mm_set1_epi16(2048);
2092 __m128i uvadd = _mm_set1_epi16(16384);
2093
2094 while(dst_len >= 20){
2095 //Load first 4 pixels
2096 rgb = _mm_lddqu_si128((__m128i const*)(const void *) src);
2097
2098 src += 12;
2099 rgb = _mm_shuffle_epi8(rgb, shuffle);
2100
2101 r = _mm_and_si128(rgb, mask);
2102 rgb = _mm_bsrli_si128(rgb, 1);
2103 //0B BB BB BB BG RG RG RG
2104 g = _mm_and_si128(rgb, mask);
2105 rgb = _mm_bsrli_si128(rgb, 7);
2106 //00 00 00 00 BB BB BB BB
2107 b = _mm_and_si128(rgb, mask);
2108
2109 //Load next 4 pixels
2110 rgb = _mm_lddqu_si128((__m128i const*)(const void *) src);
2111 src += 12;
2112 rgb = _mm_shuffle_epi8(rgb, shuffle);
2113 b = _mm_or_si128(b, _mm_and_si128(rgb, lowmask));
2114 rgb = _mm_bslli_si128(rgb, 7);
2115 g = _mm_or_si128(g, _mm_and_si128(rgb, lowmask));
2116 //0B BB BB BB BG RG RG RG
2117 rgb = _mm_bslli_si128(rgb, 1);
2118 r = _mm_or_si128(r, _mm_and_si128(rgb, lowmask));
2119 //00 00 00 00 BB BB BB BB
2120
2121 //Compute YUV values
2122 y = _mm_adds_epi16(yadd, _mm_mullo_epi16(r, yrf));
2123 y = _mm_adds_epi16(y, _mm_mullo_epi16(g, ygf));
2124 y = _mm_adds_epi16(y, _mm_mullo_epi16(b, ybf));
2125
2126 u = _mm_subs_epi16(uvadd, _mm_mullo_epi16(r, urf));
2127 u = _mm_subs_epi16(u, _mm_mullo_epi16(g, ugf));
2128 u = _mm_adds_epi16(u, _mm_mullo_epi16(b, ubf));
2129
2130 v = _mm_adds_epi16(uvadd, _mm_mullo_epi16(r, vrf));
2131 v = _mm_subs_epi16(v, _mm_mullo_epi16(g, vgf));
2132 v = _mm_subs_epi16(v, _mm_mullo_epi16(b, vbf));
2133
2134 y = _mm_srli_epi16(y, 7);
2135 u = _mm_srli_epi16(u, 7);
2136 v = _mm_srli_epi16(v, 7);
2137
2138 u = _mm_hadd_epi16(u, v);
2139 u = _mm_srli_epi16(u, 1);
2140
2141 v = _mm_unpackhi_epi16(zero, u);
2142 u = _mm_unpacklo_epi16(u, zero);
2143
2144 y = _mm_bslli_si128(y, 1);
2145 yuv = _mm_or_si128(y, u);
2146 yuv = _mm_or_si128(yuv, v);
2147
2148 _mm_storeu_si128((__m128i *)(void *) dst, yuv);
2149 dst += 16;
2150 dst_len -= 16;
2151 }
2152#endif
2153 //copy last few pixels
2154 vc_copylineRGBtoUYVY(dst, src, dst_len, rshift, gshift, bshift);
2155}
2156
2162void vc_copylineRGBtoGrayscale_SSE(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2163 int gshift, int bshift) {
2164 UNUSED(rshift);
2165 UNUSED(gshift);
2166 UNUSED(bshift);
2167#ifdef __SSSE3__
2168 __m128i rgb;
2169
2170 __m128i r;
2171 __m128i g;
2172 __m128i b;
2173
2174 __m128i y;
2175
2176 //BB BB BB BB GR GR GR GR
2177 __m128i inshuffle = _mm_setr_epi8(0, 1, 3, 4, 6, 7, 9, 10, 2, 2, 5, 5, 8, 8, 11, 11);
2178 __m128i outshuffle = _mm_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, 1, 1, 1, 1, 1, 1, 1, 1);
2179 __m128i mask = _mm_setr_epi16(0x00FF, 0x00FF, 0x00FF, 0x00FF, 0, 0, 0, 0);
2180 __m128i lowmask = _mm_setr_epi16(0, 0, 0, 0, 0x00FF, 0x00FF, 0x00FF, 0x00FF);
2181
2182 __m128i yrf = _mm_set1_epi16(23);
2183 __m128i ygf = _mm_set1_epi16(79);
2184 __m128i ybf = _mm_set1_epi16(8);
2185
2186 __m128i yadd = _mm_set1_epi16(2048);
2187
2188 while(dst_len >= 16){
2189 //Load first 4 pixels
2190 rgb = _mm_lddqu_si128((__m128i const*)(const void *) src);
2191
2192 src += 12;
2193 rgb = _mm_shuffle_epi8(rgb, inshuffle);
2194
2195 //BB BB BB BB GR GR GR GR
2196 r = _mm_and_si128(rgb, mask);
2197 rgb = _mm_bsrli_si128(rgb, 1);
2198 //0B BB BB BB BG RG RG RG
2199 g = _mm_and_si128(rgb, mask);
2200 rgb = _mm_bsrli_si128(rgb, 7);
2201 //00 00 00 00 BB BB BB BB
2202 b = _mm_and_si128(rgb, mask);
2203
2204 //Load next 4 pixels
2205 rgb = _mm_lddqu_si128((__m128i const*)(const void *) src);
2206 src += 12;
2207 rgb = _mm_shuffle_epi8(rgb, inshuffle);
2208 //BB BB BB BB GR GR GR GR
2209 b = _mm_or_si128(b, _mm_and_si128(rgb, lowmask));
2210 rgb = _mm_bslli_si128(rgb, 7);
2211 //BG RG RG RG R0 00 00 00
2212 g = _mm_or_si128(g, _mm_and_si128(rgb, lowmask));
2213 rgb = _mm_bslli_si128(rgb, 1);
2214 //GR GR GR GR 00 00 00 00
2215 r = _mm_or_si128(r, _mm_and_si128(rgb, lowmask));
2216
2217 //Compute Y values
2218 y = _mm_adds_epi16(yadd, _mm_mullo_epi16(r, yrf));
2219 y = _mm_adds_epi16(y, _mm_mullo_epi16(g, ygf));
2220 y = _mm_adds_epi16(y, _mm_mullo_epi16(b, ybf));
2221
2222 y = _mm_srli_epi16(y, 7);
2223
2224 y = _mm_shuffle_epi8(y, outshuffle);
2225
2226 _mm_storeu_si128((__m128i *)(void *) dst, y);
2227 dst += 8;
2228 dst_len -= 8;
2229 }
2230#endif
2231 //copy last few pixels
2232 register int ri, gi, bi;
2233 register int y1, y2;
2234 register uint16_t *d = (uint16_t *)(void *) dst;
2235 OPTIMIZED_FOR (int x = 0; x <= dst_len - 2; x += 2) {
2236 ri = *(src++);
2237 gi = *(src++);
2238 bi = *(src++);
2239 y1 = 11993 * ri + 40239 * gi + 4063 * bi + (1<<20);
2240 ri = *(src++);
2241 gi = *(src++);
2242 bi = *(src++);
2243 y2 = 11993 * ri + 40239 * gi + 4063 * bi + (1<<20);
2244
2245 *d++ = (CLAMP(y2, 0, (1<<24)-1) >> 16) << 8 |
2246 (CLAMP(y1, 0, (1<<24)-1) >> 16);
2247 }
2248}
2249
2254static void vc_copylineBGRtoUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2255 int gshift, int bshift)
2256{
2257 UNUSED(rshift);
2258 UNUSED(gshift);
2259 UNUSED(bshift);
2260 vc_copylineToUYVY(dst, src, dst_len, 2, 1, 0, 3);
2261}
2262
2270static void vc_copylineRGBAtoUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2271 int gshift, int bshift)
2272{
2273 UNUSED(rshift);
2274 UNUSED(gshift);
2275 UNUSED(bshift);
2276 vc_copylineToUYVY(dst, src, dst_len, 0, 1, 2, 4);
2277}
2278
2279static void vc_copylineR10ktoUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2280 int gshift, int bshift)
2281{
2282 UNUSED(rshift);
2283 UNUSED(gshift);
2284 UNUSED(bshift);
2285 const unsigned char *const end = dst + dst_len;
2286 while (dst < end) {
2287 unsigned char rgb[6];
2288 rgb[0] = src[0]; // R
2289 rgb[1] = src[1] << 2 | src[2] >> 6; // G
2290 rgb[2] = src[2] << 4 | src[3] >> 4; // B
2291 src += 4;
2292 rgb[3] = src[0]; // R
2293 rgb[4] = src[1] << 2 | src[2] >> 6; // G
2294 rgb[5] = src[2] << 4 | src[3] >> 4; // B
2295 src += 4;
2297 dst += 4;
2298 }
2299}
2300
2301static void vc_copylineRG48toUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2302 int gshift, int bshift)
2303{
2304 UNUSED(rshift);
2305 UNUSED(gshift);
2306 UNUSED(bshift);
2307 vc_copylineToUYVY(dst, src, dst_len, 1, 3, 5, 6);
2308}
2309
2313static void vc_copylineRG48toV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2314 int gshift, int bshift) {
2315 enum {
2316 D_DEPTH = 10,
2317 };
2318 const struct color_coeffs *cfs = get_color_coeffs(D_DEPTH);
2319#define COMP_OFF (COMP_BASE+(16-10))
2320#define FETCH_BLOCK \
2321 r = *in++; \
2322 g = *in++; \
2323 b = *in++; \
2324 y1 = (RGB_TO_Y(cfs, r, g, b) >> COMP_OFF) + (1<<6); \
2325 u = RGB_TO_CB(cfs, r, g, b) >> COMP_OFF; \
2326 v = RGB_TO_CR(cfs, r, g, b) >> COMP_OFF; \
2327 r = *in++; \
2328 g = *in++; \
2329 b = *in++; \
2330 y2 = (RGB_TO_Y(cfs, r, g, b) >> COMP_OFF) + (1<<6); \
2331 u += RGB_TO_CB(cfs, r, g, b) >> COMP_OFF; \
2332 v += RGB_TO_CR(cfs, r, g, b) >> COMP_OFF; \
2333 y1 = CLAMP_LIMITED_Y(y1, 10); \
2334 y2 = CLAMP_LIMITED_Y(y2, 10); \
2335 u = u / 2 + (1<<9); \
2336 v = v / 2 + (1<<9); \
2337 u = CLAMP_LIMITED_CBCR(u, 10); \
2338 v = CLAMP_LIMITED_CBCR(v, 10);
2339
2340 UNUSED(rshift);
2341 UNUSED(gshift);
2342 UNUSED(bshift);
2343 assert((uintptr_t) src % 2 == 0);
2344 assert((uintptr_t) dst % 4 == 0);
2345 const uint16_t *in = (const uint16_t *)(const void *) src;
2346 uint32_t *d = (uint32_t *)(void *) dst;
2347 OPTIMIZED_FOR (int x = 0; x <= (dst_len) - 16; x += 16) {
2348 comp_type_t y1, y2, u ,v;
2349 comp_type_t r, g, b;
2350
2352 *d++ = u | y1 << 10 | v << 20;
2353 *d = y2;
2354
2356 *d |= u << 10 | y1 << 20;
2357 *++d = v | y2 << 10;
2358
2360 *d |= u << 20;
2361 *++d = y1 | v << 10 | y2 << 20;
2362 d++;
2363 }
2364#undef COMP_OFF
2365#undef FETCH_BLOCK
2366}
2367
2368static void vc_copylineRG48toY216(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2369 int gshift, int bshift) {
2370 enum {
2371 D_DEPTH = 16,
2372 };
2373 UNUSED(rshift);
2374 UNUSED(gshift);
2375 UNUSED(bshift);
2376 assert((uintptr_t) src % 2 == 0);
2377 assert((uintptr_t) dst % 2 == 0);
2378 const struct color_coeffs *cfs = get_color_coeffs(D_DEPTH);
2379 const uint16_t *in = (const void *) src;
2380 uint16_t *d = (void *) dst;
2381 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 8) {
2382 comp_type_t r, g, b;
2383 comp_type_t y, u, v;
2384 r = *in++;
2385 g = *in++;
2386 b = *in++;
2387 y = (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) +
2388 (1 << (D_DEPTH - 4));
2389 *d++ = CLAMP_LIMITED_Y(y, 16);
2390 u = (RGB_TO_CB(cfs, r, g, b) >> COMP_BASE);
2391 v = (RGB_TO_CR(cfs, r, g, b) >> COMP_BASE);
2392 r = *in++;
2393 g = *in++;
2394 b = *in++;
2395 u = (u + (RGB_TO_CB(cfs, r, g, b) >> COMP_BASE) /
2396 2) +
2397 (1 << 15);
2398 *d++ = CLAMP_LIMITED_CBCR(u, 16);
2399 y = (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) +
2400 (1 << 12);
2401 *d++ = CLAMP_LIMITED_Y(y, 16);
2402 v = (v + (RGB_TO_CR(cfs, r, g, b) >> COMP_BASE) /
2403 2) +
2404 (1 << 15);
2405 *d++ = CLAMP_LIMITED_CBCR(v, 16);
2406 }
2407}
2408
2409static void vc_copylineRG48toY416(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2410 int gshift, int bshift) {
2411 enum {
2412 D_DEPTH = 16,
2413 };
2414 UNUSED(rshift);
2415 UNUSED(gshift);
2416 UNUSED(bshift);
2417 assert((uintptr_t) src % 2 == 0);
2418 assert((uintptr_t) dst % 2 == 0);
2419 const struct color_coeffs *cfs = get_color_coeffs(D_DEPTH);
2420 const uint16_t *in = (const void *) src;
2421 uint16_t *d = (void *) dst;
2422 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 8) {
2423 comp_type_t r, g, b;
2424 r = *in++;
2425 g = *in++;
2426 b = *in++;
2427 comp_type_t u =
2428 (RGB_TO_CB(cfs, r, g, b) >> COMP_BASE) +
2429 (1 << (D_DEPTH - 1));
2430 *d++ = CLAMP_LIMITED_CBCR(u, D_DEPTH);
2431 comp_type_t y =
2432 (RGB_TO_Y(cfs, r, g, b) >> COMP_BASE) +
2433 (1 << (D_DEPTH - 4));
2434 *d++ = CLAMP_LIMITED_Y(y, D_DEPTH);
2435 comp_type_t v =
2436 (RGB_TO_CR(cfs, r, g, b) >> COMP_BASE) +
2437 (1 << (D_DEPTH - 1));
2438 *d++ = CLAMP_LIMITED_CBCR(v, D_DEPTH);
2439 *d++ = 0xFFFFU;
2440 }
2441}
2442
2443static void vc_copylineY416toRG48(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2444 int gshift, int bshift) {
2445 enum {
2446 S_DEPTH = 16,
2447 };
2448 UNUSED(rshift);
2449 UNUSED(gshift);
2450 UNUSED(bshift);
2451 assert((uintptr_t) src % 2 == 0);
2452 assert((uintptr_t) dst % 2 == 0);
2453 const struct color_coeffs *cfs = get_color_coeffs(S_DEPTH);
2454 const uint16_t *in = (const void *) src;
2455 uint16_t *d = (void *) dst;
2456 OPTIMIZED_FOR (int x = 0; x < dst_len; x += 6) {
2457 comp_type_t u = *in++ - (1 << (S_DEPTH - 1));
2458 comp_type_t y =
2459 Y_SCALE(S_DEPTH) * (*in++ - (1 << (S_DEPTH - 4)));
2460 comp_type_t v = *in++ - (1 << (S_DEPTH - 1));
2461 in++;
2462 comp_type_t r =
2463 YCBCR_TO_R(cfs, y, u, v) >> COMP_BASE;
2464 comp_type_t g =
2465 YCBCR_TO_G(cfs, y, u, v) >> COMP_BASE;
2466 comp_type_t b =
2467 YCBCR_TO_B(cfs, y, u, v) >> COMP_BASE;
2468 *d++ = CLAMP_FULL(r, 16);
2469 *d++ = CLAMP_FULL(g, 16);
2470 *d++ = CLAMP_FULL(b, 16);
2471 }
2472}
2473
2478static void vc_copylineBGRtoRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift, int gshift, int bshift)
2479{
2480 UNUSED(rshift);
2481 UNUSED(gshift);
2482 UNUSED(bshift);
2483
2484 vc_copylineRGB(dst, src, dst_len, 16, 8, 0);
2485}
2486
2487void vc_memcpy(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift, int gshift, int bshift)
2488{
2489 UNUSED(rshift);
2490 UNUSED(gshift);
2491 UNUSED(bshift);
2492
2493 memcpy(dst, src, dst_len);
2494}
2495
2496static void vc_copylineRGBAtoR10k(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2497 int gshift, int bshift)
2498{
2499 UNUSED(rshift);
2500 UNUSED(gshift);
2501 UNUSED(bshift);
2502 struct {
2503 unsigned r:8;
2504
2505 unsigned gh:6;
2506 unsigned p1:2;
2507
2508 unsigned bh:4;
2509 unsigned p2:2;
2510 unsigned gl:2;
2511
2512 unsigned p3:2;
2513 unsigned p4:2;
2514 unsigned bl:4;
2515 } *d = (void *) dst;
2516
2517 while (dst_len >= 4) {
2518 unsigned int r = *(src++);
2519 unsigned int g = *(src++);
2520 unsigned int b = *(src++);
2521 src++;
2522
2523 d->r = r;
2524 d->gh = g >> 2U;
2525 d->gl = g & 0x3U;
2526 d->bh = b >> 4U;
2527 d->bl = b & 0xFU;
2528
2529 d->p1 = 0;
2530 d->p2 = 0;
2531 d->p3 = 0x3U;
2532 d->p4 = 0;
2533
2534 d++;
2535 dst_len -= 4;
2536 }
2537}
2538
2539static void vc_copylineUYVYtoV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2540 int gshift, int bshift)
2541{
2542 UNUSED(rshift);
2543 UNUSED(gshift);
2544 UNUSED(bshift);
2545 struct {
2546 unsigned a:10;
2547 unsigned b:10;
2548 unsigned c:10;
2549 unsigned p1:2;
2550 } *p = (void *)dst;
2551 while (dst_len >= 4) {
2552 unsigned int u = *(src++);
2553 unsigned int y = *(src++);
2554 unsigned int v = *(src++);
2555
2556 p->a = u << 2U;
2557 p->b = y << 2U;
2558 p->c = v << 2U;
2559 p->p1 = 0;
2560
2561 p++;
2562
2563 dst_len -= 4;
2564 }
2565}
2566
2567static void vc_copylineUYVYtoY216(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2568 int gshift, int bshift)
2569{
2570 UNUSED(rshift);
2571 UNUSED(gshift);
2572 UNUSED(bshift);
2573 while (dst_len >= 8) {
2574 *dst++ = 0;
2575 *dst++ = src[1]; // Y0
2576 *dst++ = 0;
2577 *dst++ = src[0]; // U
2578 *dst++ = 0;
2579 *dst++ = src[3]; // Y1
2580 *dst++ = 0;
2581 *dst++ = src[2]; // V
2582 src += 4;
2583 dst_len -= 8;
2584 }
2585}
2586
2587static void vc_copylineUYVYtoY416(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2588 int gshift, int bshift)
2589{
2590 UNUSED(rshift);
2591 UNUSED(gshift);
2592 UNUSED(bshift);
2593 while (dst_len >= 12) {
2594 *dst++ = 0;
2595 *dst++ = src[0]; // U
2596 *dst++ = 0;
2597 *dst++ = src[1]; // Y0
2598 *dst++ = 0;
2599 *dst++ = src[2]; // V
2600 *dst++ = 0xFFU;
2601 *dst++ = 0xFFU; // A
2602 *dst++ = 0;
2603 *dst++ = src[0]; // U
2604 *dst++ = 0;
2605 *dst++ = src[3]; // Y1
2606 *dst++ = 0;
2607 *dst++ = src[2]; // V
2608 *dst++ = 0xFFU;
2609 *dst++ = 0xFFU; // A
2610 src += 4;
2611 dst_len -= 16;
2612 }
2613 if (dst_len >= 8) {
2614 *dst++ = 0;
2615 *dst++ = src[0]; // U
2616 *dst++ = 0;
2617 *dst++ = src[1]; // Y0
2618 *dst++ = 0;
2619 *dst++ = src[2]; // V
2620 *dst++ = 0xFFU;
2621 *dst++ = 0xFFU; // A
2622 }
2623}
2624
2625static void vc_copylineY216toUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2626 int gshift, int bshift)
2627{
2628 UNUSED(rshift);
2629 UNUSED(gshift);
2630 UNUSED(bshift);
2631 while (dst_len >= 4) {
2632 *dst++ = src[3];
2633 *dst++ = src[1];
2634 *dst++ = src[7];
2635 *dst++ = src[5];
2636 src += 8;
2637 dst_len -= 4;
2638 }
2639}
2640
2641static void vc_copylineY416toUYVY(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2642 int gshift, int bshift)
2643{
2644 UNUSED(rshift);
2645 UNUSED(gshift);
2646 UNUSED(bshift);
2647 while (dst_len >= 4) {
2648 *dst++ = (src[1] + src[9]) / 2; // U
2649 *dst++ = src[3]; // Y0
2650 *dst++ = (src[5] + src[13]) / 2; // V
2651 *dst++ = src[11]; // Y1
2652 src += 16;
2653 dst_len -= 4;
2654 }
2655}
2656
2657static void vc_copylineY216toV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2658 int gshift, int bshift)
2659{
2660 UNUSED(rshift);
2661 UNUSED(gshift);
2662 UNUSED(bshift);
2663 assert((uintptr_t) src % 2 == 0);
2664 assert((uintptr_t) dst % 4 == 0);
2665 OPTIMIZED_FOR (int x = 0; x < (dst_len + 15) / 16; ++x) {
2666 const uint16_t *s = (const uint16_t *)(const void *) (src + x * 24);
2667 uint32_t *d = (uint32_t *)(void *) (dst + x * 16);
2668 uint16_t y1, u, y2, v;
2669 y1 = s[0];
2670 u = s[1];
2671 y2 = s[2];
2672 v = s[3];
2673 d[0] = u >> 6U | y1 >> 6U << 10U | v >> 6U << 20U;
2674 y1 = s[4];
2675 u = s[5];
2676 d[1] = y2 >> 6U | u >> 6U << 10U | y1 >> 6U << 20U;
2677 y2 = s[6];
2678 v = s[7];
2679 y1 = s[8];
2680 u = s[9];
2681 d[2] = v >> 6U | y2 >> 6U << 10U | u >> 6U << 20U;
2682 y2 = s[10];
2683 v = s[11];
2684 d[3] = y1 >> 6U | v >> 6U << 10U | y2 >> 6U << 20U;
2685 }
2686}
2687
2688static void vc_copylineV210toY216(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2689 int gshift, int bshift)
2690{
2691 UNUSED(rshift);
2692 UNUSED(gshift);
2693 UNUSED(bshift);
2694 assert((uintptr_t) dst % 2 == 0);
2695 assert((uintptr_t) src % 4 == 0);
2696 OPTIMIZED_FOR (int x = 0; x < dst_len / 24; ++x) {
2697 const uint32_t *s = (const void *) (src + x * 16);
2698 uint16_t *d = (void *) (dst + x * 24);
2699 uint32_t tmp = *s++;
2700 unsigned u = (tmp & 0x3FFU) << 6U;
2701 unsigned y0 = ((tmp >> 10U) & 0x3FFU) << 6U;
2702 unsigned v = ((tmp >> 20U) & 0x3FFU) << 6U;
2703 tmp = *s++;
2704 unsigned y1 = (tmp & 0x3FFU) << 6U;
2705 *d++ = y0;
2706 *d++ = u;
2707 *d++ = y1;
2708 *d++ = v;
2709 u = ((tmp >> 10U) & 0x3FFU) << 6U;
2710 y0 = ((tmp >> 20U) & 0x3FFU) << 6U;
2711 tmp = *s++;
2712 v = (tmp & 0x3FFU) << 6U;
2713 y1 = ((tmp >> 10U) & 0x3FFU) << 6U;
2714 *d++ = y0;
2715 *d++ = u;
2716 *d++ = y1;
2717 *d++ = v;
2718 u = ((tmp >> 20U) & 0x3FFU) << 6U;
2719 tmp = *s++;
2720 y0 = (tmp & 0x3FFU) << 6U;
2721 v = ((tmp >> 10U) & 0x3FFU) << 6U;
2722 y1 = ((tmp >> 20U) & 0x3FFU) << 6U;
2723 *d++ = y0;
2724 *d++ = u;
2725 *d++ = y1;
2726 *d++ = v;
2727 }
2728}
2729
2730static void vc_copylineV210toY416(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2731 int gshift, int bshift)
2732{
2733 UNUSED(rshift);
2734 UNUSED(gshift);
2735 UNUSED(bshift);
2736 assert((uintptr_t) dst % 2 == 0);
2737 assert((uintptr_t) src % 4 == 0);
2738 OPTIMIZED_FOR (int x = 0; x < dst_len / 48; ++x) {
2739 const uint32_t *s = (const void *) (src + x * 16);
2740 uint16_t *d = (void *) (dst + x * 48);
2741 uint16_t u, v;
2742 uint32_t tmp;
2743 tmp = *s++;
2744 u = (tmp & 0x3FFU) << 6U;
2745 *d++ = u; // 1 U
2746 *d++ = ((tmp >> 10U) & 0x3FFU) << 6U; // Y
2747 v = ((tmp >> 20U) & 0x3FFU) << 6U;
2748 *d++ = v; // V
2749 *d++ = 0xFFFFU; // A
2750 *d++ = u; // 2 U
2751 tmp = *s++;
2752 *d++ = (tmp & 0x3FFU) << 6U; // Y
2753 *d++ = v; // V
2754 *d++ = 0xFFFFU; // A
2755 u = ((tmp >> 10U) & 0x3FFU) << 6U;
2756 *d++ = u; // 3 U
2757 *d++ = ((tmp >> 20U) & 0x3FFU) << 6U; // Y
2758 tmp = *s++;
2759 v = (tmp & 0x3FFU) << 6U;
2760 *d++ = v; // V
2761 *d++ = 0xFFFFU; // A
2762 *d++ = u; // 4 U
2763 *d++ = ((tmp >> 10U) & 0x3FFU) << 6U; // Y
2764 *d++ = v; // V
2765 *d++ = 0xFFFFU; // A
2766 u = ((tmp >> 20U) & 0x3FFU) << 6U;
2767 *d++ = u; // 5 U
2768 tmp = *s++;
2769 *d++ = (tmp & 0x3FFU) << 6U; // Y
2770 v = ((tmp >> 10U) & 0x3FFU) << 6U;
2771 *d++ = v; // V
2772 *d++ = 0xFFFFU; // A
2773 *d++ = u; // 6 U
2774 *d++ = ((tmp >> 20U) & 0x3FFU) << 6U; // Y
2775 *d++ = v; // V
2776 *d++ = 0xFFFFU; // A
2777 }
2778}
2779
2780static void vc_copylineV210toRGB(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2781 int gshift, int bshift)
2782{
2783 enum {
2784 IDEPTH = 8, // 10, but cherry-picking 8 bits
2785 Y_SHIFT = 1 << (IDEPTH - 4),
2786 C_SHIFT = 1 << (IDEPTH - 1),
2787 ODEPTH = 8,
2788 PIX_COUNT = 6,
2789 RGB_BPP = 3,
2790 OUT_BL_SZ = PIX_COUNT * RGB_BPP,
2791 };
2792 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
2793 const struct color_coeffs *cfs = get_color_coeffs(IDEPTH);
2794#define WRITE_YUV_AS_RGB(y, u, v) \
2795 (y) = Y_SCALE(IDEPTH) * ((y) - Y_SHIFT); \
2796 val = (YCBCR_TO_R(cfs, (y), (u), (v)) >> (COMP_BASE)); \
2797 *(dst++) = CLAMP_FULL(val, ODEPTH); \
2798 val = (YCBCR_TO_G(cfs, (y), (u), (v)) >> (COMP_BASE)); \
2799 *(dst++) = CLAMP_FULL(val, ODEPTH); \
2800 val = (YCBCR_TO_B(cfs, (y), (u), (v)) >> (COMP_BASE)); \
2801 *(dst++) = CLAMP_FULL(val, ODEPTH);
2802
2803 // read 8 bits from v210 directly
2804#define DECLARE_LOAD_V210_COMPONENTS(a, b, c) \
2805 comp_type_t a = (src[1] & 0x3) << 6 | src[0] >> 2;\
2806 comp_type_t b = (src[2] & 0xF) << 4 | src[1] >> 4;\
2807 comp_type_t c = (src[3] & 0x3F) << 2 | src[2] >> 6;\
2808
2809 OPTIMIZED_FOR (int x = 0; x < dst_len; x += OUT_BL_SZ){
2810 DECLARE_LOAD_V210_COMPONENTS(u01, y0, v01);
2811 src += 4;
2812 DECLARE_LOAD_V210_COMPONENTS(y1, u23, y2);
2813 src += 4;
2814 DECLARE_LOAD_V210_COMPONENTS(v23, y3, u45);
2815 src += 4;
2816 DECLARE_LOAD_V210_COMPONENTS(y4, v45, y5);
2817 src += 4;
2818
2819 comp_type_t val = 0;
2820
2821 u01 -= C_SHIFT;
2822 v01 -= C_SHIFT;
2823 u23 -= C_SHIFT;
2824 v23 -= C_SHIFT;
2825 u45 -= C_SHIFT;
2826 v45 -= C_SHIFT;
2827 WRITE_YUV_AS_RGB(y0, u01, v01);
2828 WRITE_YUV_AS_RGB(y1, u01, v01);
2829 WRITE_YUV_AS_RGB(y2, u23, v23);
2830 WRITE_YUV_AS_RGB(y3, u23, v23);
2831 WRITE_YUV_AS_RGB(y4, u45, v45);
2832 WRITE_YUV_AS_RGB(y5, u45, v45);
2833 }
2834#undef WRITE_YUV_AS_RGB
2835#undef DECLARE_LOAD_V210_COMPONENTS
2836}
2837
2838static void
2839vc_copylineV210toRG48(unsigned char *__restrict d,
2840 const unsigned char *__restrict src, int dst_len,
2841 int rshift, int gshift, int bshift)
2842{
2843 uint16_t *dst = (void *) d;
2844 enum {
2845 IDEPTH = 10,
2846 Y_SHIFT = 1 << (IDEPTH - 4),
2847 C_SHIFT = 1 << (IDEPTH - 1),
2848 ODEPTH = 16,
2849 DIFF_BPP = ODEPTH - IDEPTH,
2850 PIX_COUNT = 6,
2851 RG48_BPP = 6,
2852 OUT_BL_SZ = PIX_COUNT * RG48_BPP,
2853 };
2854 UNUSED(rshift), UNUSED(gshift), UNUSED(bshift);
2855 const struct color_coeffs *cfs = get_color_coeffs(IDEPTH);
2856#define WRITE_YUV_AS_RGB(y, u, v) \
2857 (y) = Y_SCALE(IDEPTH) * ((y) - Y_SHIFT); \
2858 val = (YCBCR_TO_R(cfs, (y), (u), (v)) >> (COMP_BASE - DIFF_BPP)); \
2859 *(dst++) = CLAMP_FULL(val, ODEPTH); \
2860 val = (YCBCR_TO_G(cfs, (y), (u), (v)) >> (COMP_BASE - DIFF_BPP)); \
2861 *(dst++) = CLAMP_FULL(val, ODEPTH); \
2862 val = (YCBCR_TO_B(cfs, (y), (u), (v)) >> (COMP_BASE - DIFF_BPP)); \
2863 *(dst++) = CLAMP_FULL(val, ODEPTH);
2864
2865 // read 8 bits from v210 directly
2866#define DECLARE_LOAD_V210_COMPONENTS(a, b, c) \
2867 comp_type_t a = (src[1] & 0x3) << 8 | src[0];\
2868 comp_type_t b = (src[2] & 0xF) << 6 | src[1] >> 2;\
2869 comp_type_t c = (src[3] & 0x3F) << 4 | src[2] >> 4;\
2870
2871 OPTIMIZED_FOR (int x = 0; x < dst_len; x += OUT_BL_SZ){
2872 DECLARE_LOAD_V210_COMPONENTS(u01, y0, v01);
2873 src += 4;
2874 DECLARE_LOAD_V210_COMPONENTS(y1, u23, y2);
2875 src += 4;
2876 DECLARE_LOAD_V210_COMPONENTS(v23, y3, u45);
2877 src += 4;
2878 DECLARE_LOAD_V210_COMPONENTS(y4, v45, y5);
2879 src += 4;
2880
2881 comp_type_t val = 0;
2882
2883 u01 -= C_SHIFT;
2884 v01 -= C_SHIFT;
2885 u23 -= C_SHIFT;
2886 v23 -= C_SHIFT;
2887 u45 -= C_SHIFT;
2888 v45 -= C_SHIFT;
2889 WRITE_YUV_AS_RGB(y0, u01, v01);
2890 WRITE_YUV_AS_RGB(y1, u01, v01);
2891 WRITE_YUV_AS_RGB(y2, u23, v23);
2892 WRITE_YUV_AS_RGB(y3, u23, v23);
2893 WRITE_YUV_AS_RGB(y4, u45, v45);
2894 WRITE_YUV_AS_RGB(y5, u45, v45);
2895 }
2896#undef WRITE_YUV_AS_RGB
2897#undef DECLARE_LOAD_V210_COMPONENTS
2898}
2899
2900static void vc_copylineY416toV210(unsigned char * __restrict dst, const unsigned char * __restrict src, int dst_len, int rshift,
2901 int gshift, int bshift)
2902{
2903 UNUSED(rshift);
2904 UNUSED(gshift);
2905 UNUSED(bshift);
2906 assert((uintptr_t) src % 2 == 0);
2907 assert((uintptr_t) dst % 4 == 0);
2908 OPTIMIZED_FOR (int x = 0; x < dst_len / 16; ++x) {
2909 const uint16_t *s = (const uint16_t *)(const void *) (src + x * 48);
2910 uint32_t *d = (uint32_t *)(void *) (dst + x * 16);
2911 uint16_t y1, u, y2, v;
2912 u = (s[0] + s[4]) / 2;
2913 y1 = s[1];
2914 v = (s[2] + s[6]) / 2;
2915 y2 = s[5];
2916 d[0] = u >> 6U | y1 >> 6U << 10U | v >> 6U << 20U;
2917 y1 = s[9];
2918 u = (s[8] + s[12]) / 2;
2919 d[1] = y2 >> 6U | u >> 6U << 10U | y1 >> 6U << 20U;
2920 y2 = s[13];
2921 v = (s[10] + s[14]) / 2;
2922 y1 = s[17];
2923 u = (s[16] + s[20]) / 2;
2924 d[2] = v >> 6U | y2 >> 6U << 10U | u >> 6U << 20U;
2925 y2 = s[21];
2926 v = (s[18] + s[22]) / 2;
2927 d[3] = y1 >> 6U | v >> 6U << 10U | y2 >> 6U << 20U;
2928 }
2929}
2930
2936
2937static const struct decoder_item decoders[] = {
2978 { vc_copylineRGB, RGB, RGB },
2995};
2996
3003 if (in == out &&
3004 (out != RGBA && out != RGB)) { // vc_copylineRGB[A] may change shift
3005 return vc_memcpy;
3006 }
3007
3008 for (unsigned int i = 0; i < sizeof(decoders)/sizeof(struct decoder_item); ++i) {
3009 if (decoders[i].in == in && decoders[i].out == out) {
3010 return decoders[i].decoder;
3011 }
3012 }
3013
3014 return NULL;
3015}
3016
3017// less is better
3018static QSORT_S_COMP_DEFINE(best_decoder_cmp, a, b, desc_src) {
3019 codec_t codec_a = *(const codec_t *) a;
3020 codec_t codec_b = *(const codec_t *) b;
3021 struct pixfmt_desc *src_desc = desc_src;
3022 struct pixfmt_desc desc_a = get_pixfmt_desc(codec_a);
3023 struct pixfmt_desc desc_b = get_pixfmt_desc(codec_b);
3024
3025 int ret = compare_pixdesc(&desc_a, &desc_b, src_desc);
3026 if (ret != 0) {
3027 return ret;
3028 }
3029
3030 return (int) codec_a - (int) codec_b;
3031}
3032
3039{
3040 if (codec_is_in_set(in, out_candidates) && (in != RGBA && in != RGB)) { // vc_copylineRGB[A] may change shift
3041 *out = in;
3042 return vc_memcpy;
3043 }
3044
3045 codec_t candidates[VIDEO_CODEC_END];
3046 const codec_t *it = out_candidates;
3047 size_t count = 0;
3048 while (*it != VIDEO_CODEC_NONE) {
3049 if (get_decoder_from_to(in, *it)) {
3050 assert(count < VIDEO_CODEC_END && "Too much codecs, some used multiple times!");
3051 candidates[count++] = *it;
3052 }
3053 it++;
3054 }
3055 if (count == 0) {
3056 return NULL;
3057 }
3058 struct pixfmt_desc src_desc = get_pixfmt_desc(in);
3059 qsort_s(candidates, count, sizeof(codec_t), best_decoder_cmp, &src_desc);
3060 *out = candidates[0];
3061 return get_decoder_from_to(in, *out);
3062}
3063
3064/* vim: set expandtab sw=8: */
#define UNUSED(x)
int void * val
int void size_t * len
const struct color_coeffs * get_color_coeffs(int ycbcr_bit_depth)
Definition color.c:58
#define RGB_TO_CB(t, r, g, b)
Definition color.h:176
#define CLAMP_LIMITED_CBCR(val, depth)
Definition color.h:137
#define RGB_TO_Y(t, r, g, b)
Definition color.h:175
#define Y_SCALE(in_depth)
Definition color.h:151
int32_t comp_type_t
Definition color.h:65
#define RGB_TO_CR(t, r, g, b)
Definition color.h:178
#define CLAMP_LIMITED_Y(val, depth)
Definition color.h:136
#define COMP_BASE
Definition color.h:66
#define YCBCR_TO_B(t, y_scaled, cb, cr)
Definition color.h:184
#define YCBCR_TO_G(t, y_scaled, cb, cr)
Definition color.h:182
#define YCBCR_TO_R(t, y_scaled, cb, cr)
Definition color.h:181
#define CLAMP_FULL(val, depth)
Definition color.h:163
int count
Definition hd-rum.c:44
#define CLAMP(x, low, high)
Definition macros.h:67
#define OPTIMIZED_FOR
Definition macros.h:127
static void vc_copylineRGBtoR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Changes color order of an RGB.
#define loop_body
static void vc_copylineRGBAtoR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineY416toRGBA(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGBtoUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts RGB to UYVY.
static void vc_copylineY216toV210(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineV210toY216(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static const struct decoder_item decoders[]
#define DECLARE_LOAD_V210_COMPONENTS(a, b, c)
static void vc_copyliner10k(unsigned char *__restrict dst, const unsigned char *__restrict src, int len, int rshift, int gshift, int bshift)
Converts from R10k to RGBA.
static void vc_copylineY416toRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGBAtoRGBwithShift(unsigned char *__restrict dst2, const unsigned char *__restrict src2, int dst_len, int rshift, int gshift, int bshift)
Converts from RGBA to RGB. Channels in RGBA can be differently ordered.
static void vc_copylineRG48toV210(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineY216toUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineUYVYtoRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts UYVY to RGB.
static void vc_copyliner10ktoRG48(unsigned char *__restrict dst, const unsigned char *__restrict src, int dstlen, int rshift, int gshift, int bshift)
static void vc_copylineUYVYtoRG48(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineYUYVtoRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts YUYV to RGB.
static void vc_copylineRG48toY416(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineToUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int roff, int goff, int boff, int pix_size)
Converts RGB(A) into UYVY.
static void vc_copylineDVS10(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts from DVS10 to UYVY.
static void vc_copylineUYVYtoY216(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGBAtoR10k(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRG48toUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineUYVYtoY416(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineR12LtoR10k(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRG48toRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineV210toRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineR12LtoUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineBGRtoUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts BGR to UYVY.
static void vc_copylineV210toY416(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGBAtoUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts RGBA to UYVY.
#define BYTE_SWAP(x)
Definition pixfmt_conv.c:77
static void vc_copylineDVS10toV210(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts from DVS10 to v210.
static void vc_copylineY416toUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
#define copylineYUVtoRGB(dst, src, dst_len, y1_off, y2_off, u_off, v_off, rgb16)
Converts 8-bit YCbCr (packed 4:2:2 in 32-bit) word to RGB.
static void vc_copylineY416toR10k(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
#define GET_NEXT
static void vc_copylineUYVYtoRGBA(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts UYVY to RGBA.
decoder_t get_decoder_from_to(codec_t in, codec_t out)
static void vc_copylineR12L(unsigned char *dst, const unsigned char *src, int dstlen, int rshift, int gshift, int bshift)
Converts from R12L to RGBA.
#define WRITE_YUV_AS_RGB(y, u, v)
static void vc_copylineR12LtoY416(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRG48toY216(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineY416toRG48(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGBAtoRG48(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineR12LtoRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dstlen, int rshift, int gshift, int bshift)
Converts from R12L to RGB.
static void vc_copylineRG48toR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts RG48 to R12L. Converts 16-bit RGB to 12-bit packed RGB in full range (compatible with SMPTE ...
static void vc_copylineYUYV(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts from YUYV to UYVY.
static void vc_copylineRGB_AtoR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int pix_pad)
static void vc_copylineR12LtoRG48(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts R12L to RG48. Converts 12-bit packed RGB in full range (compatible with SMPTE 268M DPX versi...
static void vc_copylineUYVYtoV210(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRG48toRGBA(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineR10ktoUYVY(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
#define FETCH_BLOCK
static void vc_copylineRGBtoRG48(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineRGBAtoRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts from RGBA to RGB.
static void vc_copylineBGRtoRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
static void vc_copylineV210toRG48(unsigned char *__restrict d, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
decoder_t get_best_decoder_from(codec_t in, const codec_t *out_candidates, codec_t *out)
static void vc_copylineRG48toR10k(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
#define WRITE_RES
static void vc_copylinev210(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts v210 to UYVY.
Definition pixfmt_conv.c:87
static void vc_copyliner10ktoY416(unsigned char *__restrict dst, const unsigned char *__restrict src, int dstlen, int rshift, int gshift, int bshift)
static void vc_copyliner10ktoRGB(unsigned char *__restrict dst, const unsigned char *__restrict src, int dstlen, int rshift, int gshift, int bshift)
static void vc_copylineY416toV210(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
#define FETCH_DATA
static void vc_copylineY416toR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
decoder_func_t vc_copylineRGBA
#define DEFAULT_B_SHIFT
Definition pixfmt_conv.h:72
decoder_func_t vc_copylineABGRtoRGB
decoder_func_t vc_copylineToRGBA_inplace
decoder_func_t vc_copylineRGBtoRGBA
decoder_func_t vc_copylineUYVYtoGrayscale
decoder_func_t vc_copylineRGBtoUYVY_SSE
#define DEFAULT_R_SHIFT
Definition pixfmt_conv.h:70
decoder_func_t * decoder_t
Definition pixfmt_conv.h:96
decoder_func_t vc_memcpy
dummy conversion - ptr to it returned if no conversion needed
#define DEFAULT_G_SHIFT
Definition pixfmt_conv.h:71
decoder_func_t vc_copylineBGRAtoRGB
decoder_func_t vc_copylineRGBtoGrayscale_SSE
decoder_func_t vc_copylineUYVYtoRGB_SSE
#define qsort_s
Definition qsort_s.h:63
#define QSORT_S_COMP_DEFINE(name, a, b, context)
Definition qsort_s.h:71
struct __attribute__((packed))
Definition rtp.h:88
decoder_t decoder
@ DEPTH8
Definition types.h:126
codec_t
Definition types.h:65
@ YUYV
YCbCr 422 8-bit - Y0 Cb Y1 Cr.
Definition types.h:72
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
Definition types.h:73
@ RGB
RGB 8-bit (packed into 24-bit word)
Definition types.h:80
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ BGR
8-bit BGR
Definition types.h:88
@ RG48
16-bit RGB little-endian (RlRhGl...)
Definition types.h:95
@ Y416
interleaved little-endian YCbCr 4444 16-bit - UYVA
Definition types.h:99
@ VIDEO_CODEC_END
Definition types.h:111
@ Y216
YCbCr 422 16-bit little-endian - Y0 Cb Y1 Cr.
Definition types.h:98
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
@ DVS10
DVS 10-bit format.
Definition types.h:76
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75
bool codec_is_in_set(codec_t codec, const codec_t *set)
struct pixfmt_desc get_pixfmt_desc(codec_t pixfmt)
int compare_pixdesc(const struct pixfmt_desc *desc_a, const struct pixfmt_desc *desc_b, const struct pixfmt_desc *src_desc)