Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImageConvert_yuv.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Convert image types.
32 */
33
38
39
40#include <visp3/core/vpConfig.h>
41#include <visp3/core/vpImageConvert.h>
42
43namespace
44{
45void vpSAT(int &c)
46{
47 const int val_255 = 255;
48 if (c < 0) {
49 c = 0;
50 }
51 else if (c > val_255) {
52
53 c = val_255;
54 }
55}
56}
57
72void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
73{
74 unsigned char *s;
75 unsigned char *d;
76 int w, h;
77 int r, g, b, cr, cg, cb, y1, y2;
78 const int val_2 = 2;
79 const int val_88 = 88;
80 const int val_128 = 128;
81 const int val_183 = 183;
82 const int val_256 = 256;
83 const int val_359 = 359;
84 const int val_454 = 454;
85
86 h = static_cast<int>(height);
87 w = static_cast<int>(width);
88 s = yuyv;
89 d = rgba;
90 while (h--) {
91 int c = w / val_2;
92 while (c--) {
93 y1 = *s;
94 ++s;
95 cb = ((*s - val_128) * val_454) / val_256;
96 cg = (*s - val_128) * val_88;
97 ++s;
98 y2 = *s;
99 ++s;
100 cr = ((*s - val_128) * val_359) / val_256;
101 cg = (cg + ((*s - val_128) * val_183)) / val_256;
102 ++s;
103
104 r = y1 + cr;
105 b = y1 + cb;
106 g = y1 - cg;
107 vpSAT(r);
108 vpSAT(g);
109 vpSAT(b);
110
111 *d++ = static_cast<unsigned char>(r);
112 *d++ = static_cast<unsigned char>(g);
113 *d++ = static_cast<unsigned char>(b);
115
116 r = y2 + cr;
117 b = y2 + cb;
118 g = y2 - cg;
119 vpSAT(r);
120 vpSAT(g);
121 vpSAT(b);
122
123 *d++ = static_cast<unsigned char>(r);
124 *d++ = static_cast<unsigned char>(g);
125 *d++ = static_cast<unsigned char>(b);
127 }
128 }
129}
130
142void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
143{
144 unsigned char *s;
145 unsigned char *d;
146 int h, w;
147 int r, g, b, cr, cg, cb, y1, y2;
148 const int val_2 = 2;
149 const int val_88 = 88;
150 const int val_128 = 128;
151 const int val_183 = 183;
152 const int val_256 = 256;
153 const int val_359 = 359;
154 const int val_454 = 454;
155
156 h = static_cast<int>(height);
157 w = static_cast<int>(width);
158 s = yuyv;
159 d = rgb;
160 while (h--) {
161 int c = w / val_2;
162 while (c--) {
163 y1 = *s;
164 ++s;
165 cb = ((*s - val_128) * val_454) / val_256;
166 cg = (*s - val_128) * val_88;
167 ++s;
168 y2 = *s;
169 ++s;
170 cr = ((*s - val_128) * val_359) / val_256;
171 cg = (cg + ((*s - val_128) * val_183)) / val_256;
172 ++s;
173
174 r = y1 + cr;
175 b = y1 + cb;
176 g = y1 - cg;
177 vpSAT(r);
178 vpSAT(g);
179 vpSAT(b);
180
181 *d++ = static_cast<unsigned char>(r);
182 *d++ = static_cast<unsigned char>(g);
183 *d++ = static_cast<unsigned char>(b);
184
185 r = y2 + cr;
186 b = y2 + cb;
187 g = y2 - cg;
188 vpSAT(r);
189 vpSAT(g);
190 vpSAT(b);
191
192 *d++ = static_cast<unsigned char>(r);
193 *d++ = static_cast<unsigned char>(g);
194 *d++ = static_cast<unsigned char>(b);
195 }
196 }
197}
198
209void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
210{
211 const unsigned int val_2 = 2;
212 const unsigned int val_4 = 4;
213 unsigned int i = 0, j = 0;
214 const unsigned int doubleSize = size * 2;
215 while (j < doubleSize) {
216 grey[i++] = yuyv[j];
217 grey[i++] = yuyv[j + val_2];
218 j += val_4;
219 }
220}
221
231void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
232{
233 const unsigned int val_128 = 128;
234 for (unsigned int i = size / 4; i; --i) {
235 int U = static_cast<int>((*yuv - val_128) * 0.354);
236 ++yuv;
237 int U5 = 5 * U;
238 int Y0 = *yuv;
239 ++yuv;
240 int Y1 = *yuv;
241 ++yuv;
242 int V = static_cast<int>((*yuv - val_128) * 0.707);
243 ++yuv;
244 int V2 = 2 * V;
245 int Y2 = *yuv;
246 ++yuv;
247 int Y3 = *yuv;
248 ++yuv;
249 int UV = -U - V;
250
251 // Original equations
252 // R = Y + 1.402 V
253 // G = Y - 0.344 U - 0.714 V
254 // B = Y + 1.772 U
255 int R = Y0 + V2;
256 vpSAT(R);
257
258 int G = Y0 + UV;
259 vpSAT(G);
260
261 int B = Y0 + U5;
262 vpSAT(B);
263
264 *rgba++ = static_cast<unsigned char>(R);
265 *rgba++ = static_cast<unsigned char>(G);
266 *rgba++ = static_cast<unsigned char>(B);
267 *rgba++ = vpRGBa::alpha_default;
268
269 //---
270 R = Y1 + V2;
271 vpSAT(R);
272
273 G = Y1 + UV;
274 vpSAT(G);
275
276 B = Y1 + U5;
277 vpSAT(B);
278
279 *rgba++ = static_cast<unsigned char>(R);
280 *rgba++ = static_cast<unsigned char>(G);
281 *rgba++ = static_cast<unsigned char>(B);
282 *rgba++ = vpRGBa::alpha_default;
283
284 //---
285 R = Y2 + V2;
286 vpSAT(R);
287
288 G = Y2 + UV;
289 vpSAT(G);
290
291 B = Y2 + U5;
292 vpSAT(B);
293
294 *rgba++ = static_cast<unsigned char>(R);
295 *rgba++ = static_cast<unsigned char>(G);
296 *rgba++ = static_cast<unsigned char>(B);
297 *rgba++ = vpRGBa::alpha_default;
298
299 //---
300 R = Y3 + V2;
301 vpSAT(R);
302
303 G = Y3 + UV;
304 vpSAT(G);
305
306 B = Y3 + U5;
307 vpSAT(B);
308
309 *rgba++ = static_cast<unsigned char>(R);
310 *rgba++ = static_cast<unsigned char>(G);
311 *rgba++ = static_cast<unsigned char>(B);
312 *rgba++ = vpRGBa::alpha_default;
313 }
314}
315
328void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
329{
330 const unsigned int val_2 = 2;
331 const unsigned int val_128 = 128;
332 for (unsigned int i = size / val_2; i; --i) {
333 int U = static_cast<int>((*yuv - val_128) * 0.354);
334 ++yuv;
335 int U5 = 5 * U;
336 int Y0 = *yuv;
337 ++yuv;
338 int V = static_cast<int>((*yuv - val_128) * 0.707);
339 ++yuv;
340 int V2 = 2 * V;
341 int Y1 = *yuv;
342 ++yuv;
343 int UV = -U - V;
344
345 //---
346 int R = Y0 + V2;
347 vpSAT(R);
348
349 int G = Y0 + UV;
350 vpSAT(G);
351
352 int B = Y0 + U5;
353 vpSAT(B);
354
355 *rgba++ = static_cast<unsigned char>(R);
356 *rgba++ = static_cast<unsigned char>(G);
357 *rgba++ = static_cast<unsigned char>(B);
358 *rgba++ = vpRGBa::alpha_default;
359
360 //---
361 R = Y1 + V2;
362 vpSAT(R);
363
364 G = Y1 + UV;
365 vpSAT(G);
366
367 B = Y1 + U5;
368 vpSAT(B);
369
370 *rgba++ = static_cast<unsigned char>(R);
371 *rgba++ = static_cast<unsigned char>(G);
372 *rgba++ = static_cast<unsigned char>(B);
373 *rgba++ = vpRGBa::alpha_default;
374 }
375}
376
385void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
386{
387 unsigned int i = 0, j = 0;
388 const unsigned int val_2 = 2;
389 const unsigned int val_3 = 3;
390 const unsigned int val_4 = 4;
391 const unsigned int val_5 = 5;
392 const unsigned int val_6 = 6;
393 const unsigned int iterLimit = (size * val_3) / val_2;
394 while (j < iterLimit) {
395 grey[i] = yuv[j + 1];
396 grey[i + 1] = yuv[j + val_2];
397 grey[i + val_2] = yuv[j + val_4];
398 grey[i + val_3] = yuv[j + val_5];
399
400 i += val_4;
401
402 j += val_6;
403 }
404}
405
416void vpImageConvert::YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
417{
418 const unsigned int val_2 = 2;
419 const unsigned int val_128 = 128;
420 for (unsigned int i = size / val_2; i; --i) {
421 int U = static_cast<int>((*yuv - val_128) * 0.354);
422 ++yuv;
423 int U5 = 5 * U;
424 int Y0 = *yuv;
425 ++yuv;
426 int V = static_cast<int>((*yuv - val_128) * 0.707);
427 ++yuv;
428 int V2 = 2 * V;
429 int Y1 = *yuv;
430 ++yuv;
431 int UV = -U - V;
432
433 //---
434 int R = Y0 + V2;
435 vpSAT(R);
436
437 int G = Y0 + UV;
438 vpSAT(G);
439
440 int B = Y0 + U5;
441 vpSAT(B);
442
443 *rgb++ = static_cast<unsigned char>(R);
444 *rgb++ = static_cast<unsigned char>(G);
445 *rgb++ = static_cast<unsigned char>(B);
446
447 //---
448 R = Y1 + V2;
449 vpSAT(R);
450
451 G = Y1 + UV;
452 vpSAT(G);
453
454 B = Y1 + U5;
455 vpSAT(B);
456
457 *rgb++ = static_cast<unsigned char>(R);
458 *rgb++ = static_cast<unsigned char>(G);
459 *rgb++ = static_cast<unsigned char>(B);
460 }
461}
462
473void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
474{
475 const unsigned int val_3 = 3;
476 const unsigned int val_4 = 4;
477 unsigned int i = 0, j = 0;
478 const unsigned int doubleSize = size * 2;
479
480 while (j < doubleSize) {
481 grey[i++] = yuv[j + 1];
482 grey[i++] = yuv[j + val_3];
483 j += val_4;
484 }
485}
486
495void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
496{
497 const unsigned int val_128 = 128;
498 for (unsigned int i = size / 4; i; --i) {
499 int U = static_cast<int>((*yuv - val_128) * 0.354);
500 ++yuv;
501 int U5 = 5 * U;
502 int Y0 = *yuv;
503 ++yuv;
504 int Y1 = *yuv;
505 ++yuv;
506 int V = static_cast<int>((*yuv - val_128) * 0.707);
507 ++yuv;
508 int V2 = 2 * V;
509 int Y2 = *yuv;
510 ++yuv;
511 int Y3 = *yuv;
512 ++yuv;
513 int UV = -U - V;
514
515 // Original equations
516 // R = Y + 1.402 V
517 // G = Y - 0.344 U - 0.714 V
518 // B = Y + 1.772 U
519 int R = Y0 + V2;
520 vpSAT(R);
521
522 int G = Y0 + UV;
523 vpSAT(G);
524
525 int B = Y0 + U5;
526 vpSAT(B);
527
528 *rgb++ = static_cast<unsigned char>(R);
529 *rgb++ = static_cast<unsigned char>(G);
530 *rgb++ = static_cast<unsigned char>(B);
531
532 //---
533 R = Y1 + V2;
534 vpSAT(R);
535
536 G = Y1 + UV;
537 vpSAT(G);
538
539 B = Y1 + U5;
540 vpSAT(B);
541
542 *rgb++ = static_cast<unsigned char>(R);
543 *rgb++ = static_cast<unsigned char>(G);
544 *rgb++ = static_cast<unsigned char>(B);
545
546 //---
547 R = Y2 + V2;
548 vpSAT(R);
549
550 G = Y2 + UV;
551 vpSAT(G);
552
553 B = Y2 + U5;
554 vpSAT(B);
555
556 *rgb++ = static_cast<unsigned char>(R);
557 *rgb++ = static_cast<unsigned char>(G);
558 *rgb++ = static_cast<unsigned char>(B);
559
560 //---
561 R = Y3 + V2;
562 vpSAT(R);
563
564 G = Y3 + UV;
565 vpSAT(G);
566
567 B = Y3 + U5;
568 vpSAT(B);
569
570 *rgb++ = static_cast<unsigned char>(R);
571 *rgb++ = static_cast<unsigned char>(G);
572 *rgb++ = static_cast<unsigned char>(B);
573 }
574}
575
587void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
588{
589 int U, V, R, G, B, V2, U5, UV;
590 int Y0, Y1, Y2, Y3;
591 const int val_2 = 2;
592 const int val_4 = 4;
593 const int val_5 = 5;
594 const int val_7 = 7;
595 unsigned int size = width * height;
596 unsigned char *iU = yuv + size;
597 unsigned char *iV = yuv + ((val_5 * size) / val_4);
598 const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
599 const unsigned int val_128 = 128;
600 for (unsigned int i = 0; i < halfHeight; ++i) {
601 for (unsigned int j = 0; j < halfWidth; ++j) {
602 U = static_cast<int>(((*iU) - val_128) * 0.354);
603 ++iU;
604 U5 = val_5 * U;
605 V = static_cast<int>(((*iV) - val_128) * 0.707);
606 ++iV;
607 V2 = val_2 * V;
608 UV = -U - V;
609 Y0 = *yuv;
610 ++yuv;
611 Y1 = *yuv;
612 yuv = yuv + (width - 1);
613 Y2 = *yuv;
614 ++yuv;
615 Y3 = *yuv;
616 yuv = (yuv - width) + 1;
617
618 // Original equations
619 // R = Y + 1.402 V
620 // G = Y - 0.344 U - 0.714 V
621 // B = Y + 1.772 U
622 R = Y0 + V2;
623 vpSAT(R);
624
625 G = Y0 + UV;
626 vpSAT(G);
627
628 B = Y0 + U5;
629 vpSAT(B);
630
631 *rgba++ = static_cast<unsigned char>(R);
632 *rgba++ = static_cast<unsigned char>(G);
633 *rgba++ = static_cast<unsigned char>(B);
634 *rgba++ = vpRGBa::alpha_default;
635
636 //---
637 R = Y1 + V2;
638 vpSAT(R);
639
640 G = Y1 + UV;
641 vpSAT(G);
642
643 B = Y1 + U5;
644 vpSAT(B);
645
646 *rgba++ = static_cast<unsigned char>(R);
647 *rgba++ = static_cast<unsigned char>(G);
648 *rgba++ = static_cast<unsigned char>(B);
649 *rgba = vpRGBa::alpha_default;
650 rgba = (rgba + (val_4 * width)) - val_7;
651
652 //---
653 R = Y2 + V2;
654 vpSAT(R);
655
656 G = Y2 + UV;
657 vpSAT(G);
658
659 B = Y2 + U5;
660 vpSAT(B);
661
662 *rgba++ = static_cast<unsigned char>(R);
663 *rgba++ = static_cast<unsigned char>(G);
664 *rgba++ = static_cast<unsigned char>(B);
665 *rgba++ = vpRGBa::alpha_default;
666
667 //---
668 R = Y3 + V2;
669 vpSAT(R);
670
671 G = Y3 + UV;
672 vpSAT(G);
673
674 B = Y3 + U5;
675 vpSAT(B);
676
677 *rgba++ = static_cast<unsigned char>(R);
678 *rgba++ = static_cast<unsigned char>(G);
679 *rgba++ = static_cast<unsigned char>(B);
680 *rgba = vpRGBa::alpha_default;
681 rgba = (rgba - (val_4 * width)) + 1;
682 }
683 yuv += width;
684 rgba += val_4 * width;
685 }
686}
687
697void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
698{
699 int U, V, R, G, B, V2, U5, UV;
700 int Y0, Y1, Y2, Y3;
701 const unsigned int val_2 = 2;
702 const unsigned int val_3 = 3;
703 const unsigned int val_4 = 4;
704 const unsigned int val_5 = 5;
705 unsigned int size = width * height;
706 unsigned char *iU = yuv + size;
707 unsigned char *iV = yuv + ((val_5 * size) / val_4);
708 const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
709 const unsigned int val_128 = 128;
710 for (unsigned int i = 0; i < halfHeight; ++i) {
711 for (unsigned int j = 0; j < halfWidth; ++j) {
712 U = static_cast<int>(((*iU) - val_128) * 0.354);
713 ++iU;
714 U5 = val_5 * U;
715 V = static_cast<int>(((*iV) - val_128) * 0.707);
716 ++iV;
717 V2 = val_2 * V;
718 UV = -U - V;
719 Y0 = *yuv;
720 ++yuv;
721 Y1 = *yuv;
722 yuv = yuv + (width - 1);
723 Y2 = *yuv;
724 ++yuv;
725 Y3 = *yuv;
726 yuv = (yuv - width) + 1;
727
728 // Original equations
729 // R = Y + 1.402 V
730 // G = Y - 0.344 U - 0.714 V
731 // B = Y + 1.772 U
732 R = Y0 + V2;
733 vpSAT(R);
734
735 G = Y0 + UV;
736 vpSAT(G);
737
738 B = Y0 + U5;
739 vpSAT(B);
740
741 *rgb++ = static_cast<unsigned char>(R);
742 *rgb++ = static_cast<unsigned char>(G);
743 *rgb++ = static_cast<unsigned char>(B);
744
745 //---
746 R = Y1 + V2;
747 vpSAT(R);
748
749 G = Y1 + UV;
750 vpSAT(G);
751
752 B = Y1 + U5;
753 vpSAT(B);
754
755 *rgb++ = static_cast<unsigned char>(R);
756 *rgb++ = static_cast<unsigned char>(G);
757 *rgb = static_cast<unsigned char>(B);
758 rgb = rgb + ((val_3 * width) - val_5);
759
760 //---
761 R = Y2 + V2;
762 vpSAT(R);
763
764 G = Y2 + UV;
765 vpSAT(G);
766
767 B = Y2 + U5;
768 vpSAT(B);
769
770 *rgb++ = static_cast<unsigned char>(R);
771 *rgb++ = static_cast<unsigned char>(G);
772 *rgb++ = static_cast<unsigned char>(B);
773
774 //---
775 R = Y3 + V2;
776 vpSAT(R);
777
778 G = Y3 + UV;
779 vpSAT(G);
780
781 B = Y3 + U5;
782 vpSAT(B);
783
784 *rgb++ = static_cast<unsigned char>(R);
785 *rgb++ = static_cast<unsigned char>(G);
786 *rgb = static_cast<unsigned char>(B);
787 rgb = (rgb - (val_3 * width)) + 1;
788 }
789 yuv += width;
790 rgb += val_3 * width;
791 }
792}
793
801void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
802{
803 memcpy(grey, yuv, size);
804}
805
815void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
816{
817 const unsigned int val_128 = 128;
818 for (unsigned int i = 0; i < size; ++i) {
819 int U = static_cast<int>((*yuv - val_128) * 0.354);
820 ++yuv;
821 int U5 = 5 * U;
822 int Y = *yuv;
823 ++yuv;
824 int V = static_cast<int>((*yuv - val_128) * 0.707);
825 ++yuv;
826 int V2 = 2 * V;
827 int UV = -U - V;
828
829 // Original equations
830 // R = Y + 1.402 V
831 // G = Y - 0.344 U - 0.714 V
832 // B = Y + 1.772 U
833 int R = Y + V2;
834 vpSAT(R);
835
836 int G = Y + UV;
837 vpSAT(G);
838
839 int B = Y + U5;
840 vpSAT(B);
841
842 *rgba++ = static_cast<unsigned char>(R);
843 *rgba++ = static_cast<unsigned char>(G);
844 *rgba++ = static_cast<unsigned char>(B);
845 *rgba++ = vpRGBa::alpha_default;
846 }
847}
848
856void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
857{
858 const unsigned int val_128 = 128;
859 for (unsigned int i = 0; i < size; ++i) {
860 int U = static_cast<int>((*yuv - val_128) * 0.354);
861 ++yuv;
862 int U5 = 5 * U;
863 int Y = *yuv;
864 ++yuv;
865 int V = static_cast<int>((*yuv - val_128) * 0.707);
866 ++yuv;
867 int V2 = 2 * V;
868 int UV = -U - V;
869
870 // Original equations
871 // R = Y + 1.402 V
872 // G = Y - 0.344 U - 0.714 V
873 // B = Y + 1.772 U
874 int R = Y + V2;
875 vpSAT(R);
876
877 int G = Y + UV;
878 vpSAT(G);
879
880 int B = Y + U5;
881 vpSAT(B);
882
883 *rgb++ = static_cast<unsigned char>(R);
884 *rgb++ = static_cast<unsigned char>(G);
885 *rgb++ = static_cast<unsigned char>(B);
886 }
887}
888
896void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
897{
898 const unsigned int val_3 = 3;
899 ++yuv;
900 for (unsigned int i = 0; i < size; ++i) {
901 *grey++ = *yuv;
902 yuv = yuv + val_3;
903 }
904}
905
917void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
918{
919 int U, V, R, G, B, V2, U5, UV;
920 int Y0, Y1, Y2, Y3;
921 const unsigned int val_2 = 2;
922 const unsigned int val_4 = 4;
923 const unsigned int val_5 = 5;
924 const unsigned int val_7 = 7;
925 unsigned int size = width * height;
926 unsigned char *iV = yuv + size;
927 unsigned char *iU = yuv + ((val_5 * size) / val_4);
928 const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
929 const unsigned int val_128 = 128;
930 for (unsigned int i = 0; i < halfHeight; ++i) {
931 for (unsigned int j = 0; j < halfWidth; ++j) {
932 U = static_cast<int>(((*iU) - val_128) * 0.354);
933 ++iU;
934 U5 = val_5 * U;
935 V = static_cast<int>(((*iV) - val_128) * 0.707);
936 ++iV;
937 V2 = val_2 * V;
938 UV = -U - V;
939 Y0 = *yuv;
940 ++yuv;
941 Y1 = *yuv;
942 yuv = yuv + (width - 1);
943 Y2 = *yuv;
944 ++yuv;
945 Y3 = *yuv;
946 yuv = (yuv - width) + 1;
947
948 // Original equations
949 // R = Y + 1.402 V
950 // G = Y - 0.344 U - 0.714 V
951 // B = Y + 1.772 U
952 R = Y0 + V2;
953 vpSAT(R);
954
955 G = Y0 + UV;
956 vpSAT(G);
957
958 B = Y0 + U5;
959 vpSAT(B);
960
961 *rgba++ = static_cast<unsigned char>(R);
962 *rgba++ = static_cast<unsigned char>(G);
963 *rgba++ = static_cast<unsigned char>(B);
964 *rgba++ = vpRGBa::alpha_default;
965
966 //---
967 R = Y1 + V2;
968 vpSAT(R);
969
970 G = Y1 + UV;
971 vpSAT(G);
972
973 B = Y1 + U5;
974 vpSAT(B);
975
976 *rgba++ = static_cast<unsigned char>(R);
977 *rgba++ = static_cast<unsigned char>(G);
978 *rgba++ = static_cast<unsigned char>(B);
979 *rgba = 0;
980 rgba = rgba + ((val_4 * width) - val_7);
981
982 //---
983 R = Y2 + V2;
984 vpSAT(R);
985
986 G = Y2 + UV;
987 vpSAT(G);
988
989 B = Y2 + U5;
990 vpSAT(B);
991
992 *rgba++ = static_cast<unsigned char>(R);
993 *rgba++ = static_cast<unsigned char>(G);
994 *rgba++ = static_cast<unsigned char>(B);
995 *rgba++ = vpRGBa::alpha_default;
996
997 //---
998 R = Y3 + V2;
999 vpSAT(R);
1000
1001 G = Y3 + UV;
1002 vpSAT(G);
1003
1004 B = Y3 + U5;
1005 vpSAT(B);
1006
1007 *rgba++ = static_cast<unsigned char>(R);
1008 *rgba++ = static_cast<unsigned char>(G);
1009 *rgba++ = static_cast<unsigned char>(B);
1010 *rgba = vpRGBa::alpha_default;
1011 rgba = (rgba - (val_4 * width)) + 1;
1012 }
1013 yuv += width;
1014 rgba += val_4 * width;
1015 }
1016}
1017
1027void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
1028{
1029 int U, V, R, G, B, V2, U5, UV;
1030 int Y0, Y1, Y2, Y3;
1031 const unsigned int val_2 = 2;
1032 const unsigned int val_3 = 3;
1033 const unsigned int val_4 = 4;
1034 const unsigned int val_5 = 5;
1035 unsigned int size = width * height;
1036 unsigned char *iV = yuv + size;
1037 unsigned char *iU = yuv + ((val_5 * size) / val_4);
1038 const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
1039 const unsigned int val_128 = 128;
1040 for (unsigned int i = 0; i < halfHeight; ++i) {
1041 for (unsigned int j = 0; j < halfWidth; ++j) {
1042 U = static_cast<int>(((*iU) - val_128) * 0.354);
1043 ++iU;
1044 U5 = val_5 * U;
1045 V = static_cast<int>(((*iV) - val_128) * 0.707);
1046 ++iV;
1047 V2 = val_2 * V;
1048 UV = -U - V;
1049 Y0 = *yuv;
1050 ++yuv;
1051 Y1 = *yuv;
1052 yuv = yuv + (width - 1);
1053 Y2 = *yuv;
1054 ++yuv;
1055 Y3 = *yuv;
1056 yuv = (yuv - width) + 1;
1057
1058 // Original equations
1059 // R = Y + 1.402 V
1060 // G = Y - 0.344 U - 0.714 V
1061 // B = Y + 1.772 U
1062 R = Y0 + V2;
1063 vpSAT(R);
1064
1065 G = Y0 + UV;
1066 vpSAT(G);
1067
1068 B = Y0 + U5;
1069 vpSAT(B);
1070
1071 *rgb++ = static_cast<unsigned char>(R);
1072 *rgb++ = static_cast<unsigned char>(G);
1073 *rgb++ = static_cast<unsigned char>(B);
1074
1075 //---
1076 R = Y1 + V2;
1077 vpSAT(R);
1078
1079 G = Y1 + UV;
1080 vpSAT(G);
1081
1082 B = Y1 + U5;
1083 vpSAT(B);
1084
1085 *rgb++ = static_cast<unsigned char>(R);
1086 *rgb++ = static_cast<unsigned char>(G);
1087 *rgb = static_cast<unsigned char>(B);
1088 rgb = rgb + ((val_3 * width) - val_5);
1089
1090 //---
1091 R = Y2 + V2;
1092 vpSAT(R);
1093
1094 G = Y2 + UV;
1095 vpSAT(G);
1096
1097 B = Y2 + U5;
1098 vpSAT(B);
1099
1100 *rgb++ = static_cast<unsigned char>(R);
1101 *rgb++ = static_cast<unsigned char>(G);
1102 *rgb++ = static_cast<unsigned char>(B);
1103
1104 //---
1105 R = Y3 + V2;
1106 vpSAT(R);
1107
1108 G = Y3 + UV;
1109 vpSAT(G);
1110
1111 B = Y3 + U5;
1112 vpSAT(B);
1113
1114 *rgb++ = static_cast<unsigned char>(R);
1115 *rgb++ = static_cast<unsigned char>(G);
1116 *rgb = static_cast<unsigned char>(B);
1117 rgb = (rgb - (val_3 * width)) + 1;
1118 }
1119 yuv += width;
1120 rgb += val_3 * width;
1121 }
1122}
1123
1124namespace
1125{
1136void YVU9ToRGBasubroutine(unsigned char *rgba, int R, int G, int B, int a)
1137{
1138 vpSAT(R);
1139 vpSAT(G);
1140 vpSAT(B);
1141 *rgba++ = static_cast<unsigned char>(R);
1142 *rgba++ = static_cast<unsigned char>(G);
1143 *rgba++ = static_cast<unsigned char>(B);
1144 *rgba++ = a;
1145}
1146}
1158void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1159{
1160 int U, V, R, G, B, V2, U5, UV;
1161 int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
1162 const unsigned int val_2 = 2;
1163 const unsigned int val_3 = 3;
1164 const unsigned int val_4 = 4;
1165 const unsigned int val_5 = 5;
1166 const unsigned int val_12 = 12;
1167 const unsigned int val_15 = 15;
1168 const unsigned int val_16 = 16;
1169 const unsigned int val_17 = 17;
1170 unsigned int size = width * height;
1171 unsigned char *iV = yuv + size;
1172 unsigned char *iU = yuv + ((val_17 * size) / val_16);
1173 const unsigned int quarterHeight = height / val_4, quarterWidth = width / val_4;
1174 const unsigned int val_128 = 128;
1175 for (unsigned int i = 0; i < quarterHeight; ++i) {
1176 for (unsigned int j = 0; j < quarterWidth; ++j) {
1177 U = static_cast<int>(((*iU) - val_128) * 0.354);
1178 ++iU;
1179 U5 = val_5 * U;
1180 V = static_cast<int>(((*iV) - val_128) * 0.707);
1181 ++iV;
1182 V2 = val_2 * V;
1183 UV = -U - V;
1184 Y0 = *yuv;
1185 ++yuv;
1186 Y1 = *yuv;
1187 ++yuv;
1188 Y2 = *yuv;
1189 ++yuv;
1190 Y3 = *yuv;
1191 yuv = yuv + (width - val_3);
1192 Y4 = *yuv;
1193 ++yuv;
1194 Y5 = *yuv;
1195 ++yuv;
1196 Y6 = *yuv;
1197 ++yuv;
1198 Y7 = *yuv;
1199 yuv = yuv + (width - val_3);
1200 Y8 = *yuv;
1201 ++yuv;
1202 Y9 = *yuv;
1203 ++yuv;
1204 Y10 = *yuv;
1205 ++yuv;
1206 Y11 = *yuv;
1207 yuv = yuv + (width - val_3);
1208 Y12 = *yuv;
1209 ++yuv;
1210 Y13 = *yuv;
1211 ++yuv;
1212 Y14 = *yuv;
1213 ++yuv;
1214 Y15 = *yuv;
1215 yuv = (yuv - (val_3 * width)) + 1;
1216
1217 // Original equations
1218 // R = Y + 1.402 V
1219 // G = Y - 0.344 U - 0.714 V
1220 // B = Y + 1.772 U
1221 R = Y0 + V2;
1222 G = Y0 + UV;
1223 B = Y0 + U5;
1224 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1225
1226 //---
1227 R = Y1 + V2;
1228 G = Y1 + UV;
1229 B = Y1 + U5;
1230 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1231
1232 //---
1233 R = Y2 + V2;
1234 G = Y2 + UV;
1235 B = Y2 + U5;
1236 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1237
1238 //---
1239 R = Y3 + V2;
1240 G = Y3 + UV;
1241 B = Y3 + U5;
1242 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1243 rgba = rgba + ((val_4 * width) - val_15);
1244
1245 R = Y4 + V2;
1246 G = Y4 + UV;
1247 B = Y4 + U5;
1248 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1249
1250 //---
1251 R = Y5 + V2;
1252 G = Y5 + UV;
1253 B = Y5 + U5;
1254 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1255
1256 //---
1257 R = Y6 + V2;
1258 G = Y6 + UV;
1259 B = Y6 + U5;
1260 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1261
1262 //---
1263 R = Y7 + V2;
1264 G = Y7 + UV;
1265 B = Y7 + U5;
1266 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1267 rgba = rgba + ((val_4 * width) - val_15);
1268
1269 R = Y8 + V2;
1270 G = Y8 + UV;
1271 B = Y8 + U5;
1272 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1273
1274 //---
1275 R = Y9 + V2;
1276 G = Y9 + UV;
1277 B = Y9 + U5;
1278 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1279
1280 //---
1281 R = Y10 + V2;
1282 G = Y10 + UV;
1283 B = Y10 + U5;
1284 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1285
1286 //---
1287 R = Y11 + V2;
1288 G = Y11 + UV;
1289 B = Y11 + U5;
1290 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1291 rgba = rgba + ((val_4 * width) - val_15);
1292
1293 R = Y12 + V2;
1294 G = Y12 + UV;
1295 B = Y12 + U5;
1296 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1297
1298 //---
1299 R = Y13 + V2;
1300 G = Y13 + UV;
1301 B = Y13 + U5;
1302 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1303
1304 //---
1305 R = Y14 + V2;
1306 G = Y14 + UV;
1307 B = Y14 + U5;
1308 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1309
1310 //---
1311 R = Y15 + V2;
1312 G = Y15 + UV;
1313 B = Y15 + U5;
1314 YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1315 rgba = (rgba - (val_12 * width)) + 1;
1316 }
1317 yuv += val_3 * width;
1318 rgba += val_12 * width;
1319 }
1320}
1321
1322namespace
1323{
1333void YVU9ToRGBsubroutine(unsigned char *rgb, int R, int G, int B)
1334{
1335 vpSAT(R);
1336 vpSAT(G);
1337 vpSAT(B);
1338 *rgb++ = static_cast<unsigned char>(R);
1339 *rgb++ = static_cast<unsigned char>(G);
1340 *rgb++ = static_cast<unsigned char>(B);
1341}
1342}
1343
1352void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
1353{
1354 int U, V, R, G, B, V2, U5, UV;
1355 int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
1356 const unsigned int val_2 = 2;
1357 const unsigned int val_3 = 3;
1358 const unsigned int val_4 = 4;
1359 const unsigned int val_5 = 5;
1360 const unsigned int val_9 = 9;
1361 const unsigned int val_11 = 11;
1362 const unsigned int val_16 = 16;
1363 const unsigned int val_17 = 17;
1364 unsigned int size = width * height;
1365 unsigned char *iV = yuv + size;
1366 unsigned char *iU = yuv + ((val_17 * size) / val_16);
1367 const unsigned int quarterHeight = height / val_4, quarterWidth = width / val_4;
1368 const unsigned int val_128 = 128;
1369 for (unsigned int i = 0; i < quarterHeight; ++i) {
1370 for (unsigned int j = 0; j < quarterWidth; ++j) {
1371 U = static_cast<int>((*iU - val_128) * 0.354);
1372 ++iU;
1373 U5 = val_5 * U;
1374 V = static_cast<int>((*iV - val_128) * 0.707);
1375 ++iV;
1376 V2 = val_2 * V;
1377 UV = -U - V;
1378 Y0 = *yuv;
1379 ++yuv;
1380 Y1 = *yuv;
1381 ++yuv;
1382 Y2 = *yuv;
1383 ++yuv;
1384 Y3 = *yuv;
1385 yuv = yuv + (width - val_3);
1386 Y4 = *yuv;
1387 ++yuv;
1388 Y5 = *yuv;
1389 ++yuv;
1390 Y6 = *yuv;
1391 ++yuv;
1392 Y7 = *yuv;
1393 yuv = yuv + (width - val_3);
1394 Y8 = *yuv;
1395 ++yuv;
1396 Y9 = *yuv;
1397 ++yuv;
1398 Y10 = *yuv;
1399 ++yuv;
1400 Y11 = *yuv;
1401 yuv = yuv + (width - val_3);
1402 Y12 = *yuv;
1403 ++yuv;
1404 Y13 = *yuv;
1405 ++yuv;
1406 Y14 = *yuv;
1407 ++yuv;
1408 Y15 = *yuv;
1409 yuv = (yuv - (val_3 * width)) + 1;
1410
1411 // Original equations
1412 // R = Y + 1.402 V
1413 // G = Y - 0.344 U - 0.714 V
1414 // B = Y + 1.772 U
1415 R = Y0 + V2;
1416 G = Y0 + UV;
1417 B = Y0 + U5;
1418 YVU9ToRGBsubroutine(rgb, R, G, B);
1419
1420 //---
1421 R = Y1 + V2;
1422 G = Y1 + UV;
1423 B = Y1 + U5;
1424 YVU9ToRGBsubroutine(rgb, R, G, B);
1425
1426 //---
1427 R = Y2 + V2;
1428 G = Y2 + UV;
1429 B = Y2 + U5;
1430 YVU9ToRGBsubroutine(rgb, R, G, B);
1431
1432 //---
1433 R = Y3 + V2;
1434 G = Y3 + UV;
1435 B = Y3 + U5;
1436 YVU9ToRGBsubroutine(rgb, R, G, B);
1437 rgb = rgb + ((val_3 * width) - val_11);
1438
1439 R = Y4 + V2;
1440 G = Y4 + UV;
1441 B = Y4 + U5;
1442 YVU9ToRGBsubroutine(rgb, R, G, B);
1443
1444 //---
1445 R = Y5 + V2;
1446 G = Y5 + UV;
1447 B = Y5 + U5;
1448 YVU9ToRGBsubroutine(rgb, R, G, B);
1449
1450 //---
1451 R = Y6 + V2;
1452 G = Y6 + UV;
1453 B = Y6 + U5;
1454 YVU9ToRGBsubroutine(rgb, R, G, B);
1455
1456 //---
1457 R = Y7 + V2;
1458 G = Y7 + UV;
1459 B = Y7 + U5;
1460 YVU9ToRGBsubroutine(rgb, R, G, B);
1461 rgb = rgb + ((val_3 * width) - val_11);
1462
1463 R = Y8 + V2;
1464 G = Y8 + UV;
1465 B = Y8 + U5;
1466 YVU9ToRGBsubroutine(rgb, R, G, B);
1467
1468 //---
1469 R = Y9 + V2;
1470 G = Y9 + UV;
1471 B = Y9 + U5;
1472 YVU9ToRGBsubroutine(rgb, R, G, B);
1473
1474 //---
1475 R = Y10 + V2;
1476 G = Y10 + UV;
1477 B = Y10 + U5;
1478 YVU9ToRGBsubroutine(rgb, R, G, B);
1479
1480 //---
1481 R = Y11 + V2;
1482 G = Y11 + UV;
1483 B = Y11 + U5;
1484 YVU9ToRGBsubroutine(rgb, R, G, B);
1485 rgb = (rgb + (val_3 * width)) - val_11;
1486
1487 R = Y12 + V2;
1488 G = Y12 + UV;
1489 B = Y12 + U5;
1490 YVU9ToRGBsubroutine(rgb, R, G, B);
1491
1492 //---
1493 R = Y13 + V2;
1494 G = Y13 + UV;
1495 B = Y13 + U5;
1496 YVU9ToRGBsubroutine(rgb, R, G, B);
1497
1498 //---
1499 R = Y14 + V2;
1500 G = Y14 + UV;
1501 B = Y14 + U5;
1502 YVU9ToRGBsubroutine(rgb, R, G, B);
1503
1504 //---
1505 R = Y15 + V2;
1506 G = Y15 + UV;
1507 B = Y15 + U5;
1508 YVU9ToRGBsubroutine(rgb, R, G, B);
1509 rgb = (rgb - (val_9 * width)) + 1;
1510 }
1511 yuv += val_3 * width;
1512 rgb += val_9 * width;
1513 }
1514}
1515END_VISP_NAMESPACE
static void YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
static void YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
@ alpha_default
Definition vpRGBa.h:76