Visual Servoing Platform  version 3.6.1 under development (2024-11-14)
vpImageConvert_yuv.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 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 
40 #include <visp3/core/vpConfig.h>
41 #include <visp3/core/vpImageConvert.h>
42 
43 namespace
44 {
45 void 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 
58 BEGIN_VISP_NAMESPACE
71 void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
72 {
73  unsigned char *s;
74  unsigned char *d;
75  int w, h;
76  int r, g, b, cr, cg, cb, y1, y2;
77  const int val_2 = 2;
78  const int val_88 = 88;
79  const int val_128 = 128;
80  const int val_183 = 183;
81  const int val_256 = 256;
82  const int val_359 = 359;
83  const int val_454 = 454;
84 
85  h = static_cast<int>(height);
86  w = static_cast<int>(width);
87  s = yuyv;
88  d = rgba;
89  while (h--) {
90  int c = w / val_2;
91  while (c--) {
92  y1 = *s;
93  ++s;
94  cb = ((*s - val_128) * val_454) / val_256;
95  cg = (*s - val_128) * val_88;
96  ++s;
97  y2 = *s;
98  ++s;
99  cr = ((*s - val_128) * val_359) / val_256;
100  cg = (cg + ((*s - val_128) * val_183)) / val_256;
101  ++s;
102 
103  r = y1 + cr;
104  b = y1 + cb;
105  g = y1 - cg;
106  vpSAT(r);
107  vpSAT(g);
108  vpSAT(b);
109 
110  *d++ = static_cast<unsigned char>(r);
111  *d++ = static_cast<unsigned char>(g);
112  *d++ = static_cast<unsigned char>(b);
113  *d++ = vpRGBa::alpha_default;
114 
115  r = y2 + cr;
116  b = y2 + cb;
117  g = y2 - cg;
118  vpSAT(r);
119  vpSAT(g);
120  vpSAT(b);
121 
122  *d++ = static_cast<unsigned char>(r);
123  *d++ = static_cast<unsigned char>(g);
124  *d++ = static_cast<unsigned char>(b);
125  *d++ = vpRGBa::alpha_default;
126  }
127  }
128 }
129 
140 void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
141 {
142  unsigned char *s;
143  unsigned char *d;
144  int h, w;
145  int r, g, b, cr, cg, cb, y1, y2;
146  const int val_2 = 2;
147  const int val_88 = 88;
148  const int val_128 = 128;
149  const int val_183 = 183;
150  const int val_256 = 256;
151  const int val_359 = 359;
152  const int val_454 = 454;
153 
154  h = static_cast<int>(height);
155  w = static_cast<int>(width);
156  s = yuyv;
157  d = rgb;
158  while (h--) {
159  int c = w / val_2;
160  while (c--) {
161  y1 = *s;
162  ++s;
163  cb = ((*s - val_128) * val_454) / val_256;
164  cg = (*s - val_128) * val_88;
165  ++s;
166  y2 = *s;
167  ++s;
168  cr = ((*s - val_128) * val_359) / val_256;
169  cg = (cg + ((*s - val_128) * val_183)) / val_256;
170  ++s;
171 
172  r = y1 + cr;
173  b = y1 + cb;
174  g = y1 - cg;
175  vpSAT(r);
176  vpSAT(g);
177  vpSAT(b);
178 
179  *d++ = static_cast<unsigned char>(r);
180  *d++ = static_cast<unsigned char>(g);
181  *d++ = static_cast<unsigned char>(b);
182 
183  r = y2 + cr;
184  b = y2 + cb;
185  g = y2 - cg;
186  vpSAT(r);
187  vpSAT(g);
188  vpSAT(b);
189 
190  *d++ = static_cast<unsigned char>(r);
191  *d++ = static_cast<unsigned char>(g);
192  *d++ = static_cast<unsigned char>(b);
193  }
194  }
195 }
196 
207 void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
208 {
209  unsigned int i = 0, j = 0;
210  const unsigned int doubleSize = size * 2;
211  while (j < doubleSize) {
212  grey[i++] = yuyv[j];
213  grey[i++] = yuyv[j + 2];
214  j += 4;
215  }
216 }
217 
227 void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
228 {
229  const unsigned int val_128 = 128;
230  for (unsigned int i = size / 4; i; --i) {
231  int U = static_cast<int>((*yuv - val_128) * 0.354);
232  ++yuv;
233  int U5 = 5 * U;
234  int Y0 = *yuv;
235  ++yuv;
236  int Y1 = *yuv;
237  ++yuv;
238  int V = static_cast<int>((*yuv - val_128) * 0.707);
239  ++yuv;
240  int V2 = 2 * V;
241  int Y2 = *yuv;
242  ++yuv;
243  int Y3 = *yuv;
244  ++yuv;
245  int UV = -U - V;
246 
247  // Original equations
248  // R = Y + 1.402 V
249  // G = Y - 0.344 U - 0.714 V
250  // B = Y + 1.772 U
251  int R = Y0 + V2;
252  vpSAT(R);
253 
254  int G = Y0 + UV;
255  vpSAT(G);
256 
257  int B = Y0 + U5;
258  vpSAT(B);
259 
260  *rgba++ = static_cast<unsigned char>(R);
261  *rgba++ = static_cast<unsigned char>(G);
262  *rgba++ = static_cast<unsigned char>(B);
263  *rgba++ = vpRGBa::alpha_default;
264 
265  //---
266  R = Y1 + V2;
267  vpSAT(R);
268 
269  G = Y1 + UV;
270  vpSAT(G);
271 
272  B = Y1 + U5;
273  vpSAT(B);
274 
275  *rgba++ = static_cast<unsigned char>(R);
276  *rgba++ = static_cast<unsigned char>(G);
277  *rgba++ = static_cast<unsigned char>(B);
278  *rgba++ = vpRGBa::alpha_default;
279 
280  //---
281  R = Y2 + V2;
282  vpSAT(R);
283 
284  G = Y2 + UV;
285  vpSAT(G);
286 
287  B = Y2 + U5;
288  vpSAT(B);
289 
290  *rgba++ = static_cast<unsigned char>(R);
291  *rgba++ = static_cast<unsigned char>(G);
292  *rgba++ = static_cast<unsigned char>(B);
293  *rgba++ = vpRGBa::alpha_default;
294 
295  //---
296  R = Y3 + V2;
297  vpSAT(R);
298 
299  G = Y3 + UV;
300  vpSAT(G);
301 
302  B = Y3 + U5;
303  vpSAT(B);
304 
305  *rgba++ = static_cast<unsigned char>(R);
306  *rgba++ = static_cast<unsigned char>(G);
307  *rgba++ = static_cast<unsigned char>(B);
308  *rgba++ = vpRGBa::alpha_default;
309  }
310 }
311 
324 void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
325 {
326  const unsigned int val_2 = 2;
327  const unsigned int val_128 = 128;
328  for (unsigned int i = size / val_2; i; --i) {
329  int U = static_cast<int>((*yuv - val_128) * 0.354);
330  ++yuv;
331  int U5 = 5 * U;
332  int Y0 = *yuv;
333  ++yuv;
334  int V = static_cast<int>((*yuv - val_128) * 0.707);
335  ++yuv;
336  int V2 = 2 * V;
337  int Y1 = *yuv;
338  ++yuv;
339  int UV = -U - V;
340 
341  //---
342  int R = Y0 + V2;
343  vpSAT(R);
344 
345  int G = Y0 + UV;
346  vpSAT(G);
347 
348  int B = Y0 + U5;
349  vpSAT(B);
350 
351  *rgba++ = static_cast<unsigned char>(R);
352  *rgba++ = static_cast<unsigned char>(G);
353  *rgba++ = static_cast<unsigned char>(B);
354  *rgba++ = vpRGBa::alpha_default;
355 
356  //---
357  R = Y1 + V2;
358  vpSAT(R);
359 
360  G = Y1 + UV;
361  vpSAT(G);
362 
363  B = Y1 + U5;
364  vpSAT(B);
365 
366  *rgba++ = static_cast<unsigned char>(R);
367  *rgba++ = static_cast<unsigned char>(G);
368  *rgba++ = static_cast<unsigned char>(B);
369  *rgba++ = vpRGBa::alpha_default;
370  }
371 }
372 
381 void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
382 {
383  unsigned int i = 0, j = 0;
384  const unsigned int val_2 = 2;
385  const unsigned int iterLimit = (size * 3) / val_2;
386  while (j < iterLimit) {
387  grey[i] = yuv[j + 1];
388  grey[i + 1] = yuv[j + 2];
389  grey[i + 2] = yuv[j + 4];
390  grey[i + 3] = yuv[j + 5];
391 
392  i += 4;
393 
394  j += 6;
395  }
396 }
397 
408 void vpImageConvert::YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
409 {
410  const unsigned int val_2 = 2;
411  const unsigned int val_128 = 128;
412  for (unsigned int i = size / val_2; i; --i) {
413  int U = static_cast<int>((*yuv - val_128) * 0.354);
414  ++yuv;
415  int U5 = 5 * U;
416  int Y0 = *yuv;
417  ++yuv;
418  int V = static_cast<int>((*yuv - val_128) * 0.707);
419  ++yuv;
420  int V2 = 2 * V;
421  int Y1 = *yuv;
422  ++yuv;
423  int UV = -U - V;
424 
425  //---
426  int R = Y0 + V2;
427  vpSAT(R);
428 
429  int G = Y0 + UV;
430  vpSAT(G);
431 
432  int B = Y0 + U5;
433  vpSAT(B);
434 
435  *rgb++ = static_cast<unsigned char>(R);
436  *rgb++ = static_cast<unsigned char>(G);
437  *rgb++ = static_cast<unsigned char>(B);
438 
439  //---
440  R = Y1 + V2;
441  vpSAT(R);
442 
443  G = Y1 + UV;
444  vpSAT(G);
445 
446  B = Y1 + U5;
447  vpSAT(B);
448 
449  *rgb++ = static_cast<unsigned char>(R);
450  *rgb++ = static_cast<unsigned char>(G);
451  *rgb++ = static_cast<unsigned char>(B);
452  }
453 }
454 
465 void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
466 {
467  unsigned int i = 0, j = 0;
468  const unsigned int doubleSize = size * 2;
469 
470  while (j < doubleSize) {
471  grey[i++] = yuv[j + 1];
472  grey[i++] = yuv[j + 3];
473  j += 4;
474  }
475 }
476 
485 void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
486 {
487  const unsigned int val_128 = 128;
488  for (unsigned int i = size / 4; i; --i) {
489  int U = static_cast<int>((*yuv - val_128) * 0.354);
490  ++yuv;
491  int U5 = 5 * U;
492  int Y0 = *yuv;
493  ++yuv;
494  int Y1 = *yuv;
495  ++yuv;
496  int V = static_cast<int>((*yuv - val_128) * 0.707);
497  ++yuv;
498  int V2 = 2 * V;
499  int Y2 = *yuv;
500  ++yuv;
501  int Y3 = *yuv;
502  ++yuv;
503  int UV = -U - V;
504 
505  // Original equations
506  // R = Y + 1.402 V
507  // G = Y - 0.344 U - 0.714 V
508  // B = Y + 1.772 U
509  int R = Y0 + V2;
510  vpSAT(R);
511 
512  int G = Y0 + UV;
513  vpSAT(G);
514 
515  int B = Y0 + U5;
516  vpSAT(B);
517 
518  *rgb++ = static_cast<unsigned char>(R);
519  *rgb++ = static_cast<unsigned char>(G);
520  *rgb++ = static_cast<unsigned char>(B);
521 
522  //---
523  R = Y1 + V2;
524  vpSAT(R);
525 
526  G = Y1 + UV;
527  vpSAT(G);
528 
529  B = Y1 + U5;
530  vpSAT(B);
531 
532  *rgb++ = static_cast<unsigned char>(R);
533  *rgb++ = static_cast<unsigned char>(G);
534  *rgb++ = static_cast<unsigned char>(B);
535 
536  //---
537  R = Y2 + V2;
538  vpSAT(R);
539 
540  G = Y2 + UV;
541  vpSAT(G);
542 
543  B = Y2 + U5;
544  vpSAT(B);
545 
546  *rgb++ = static_cast<unsigned char>(R);
547  *rgb++ = static_cast<unsigned char>(G);
548  *rgb++ = static_cast<unsigned char>(B);
549 
550  //---
551  R = Y3 + V2;
552  vpSAT(R);
553 
554  G = Y3 + UV;
555  vpSAT(G);
556 
557  B = Y3 + U5;
558  vpSAT(B);
559 
560  *rgb++ = static_cast<unsigned char>(R);
561  *rgb++ = static_cast<unsigned char>(G);
562  *rgb++ = static_cast<unsigned char>(B);
563  }
564 }
565 
576 void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
577 {
578  int U, V, R, G, B, V2, U5, UV;
579  int Y0, Y1, Y2, Y3;
580  const unsigned int val_2 = 2;
581  const unsigned int val_4 = 4;
582  const unsigned int val_5 = 5;
583  const unsigned int val_7 = 7;
584  unsigned int size = width * height;
585  unsigned char *iU = yuv + size;
586  unsigned char *iV = yuv + ((val_5 * size) / val_4);
587  const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
588  const unsigned int val_128 = 128;
589  for (unsigned int i = 0; i < halfHeight; ++i) {
590  for (unsigned int j = 0; j < halfWidth; ++j) {
591  U = static_cast<int>(((*iU) - val_128) * 0.354);
592  ++iU;
593  U5 = val_5 * U;
594  V = static_cast<int>(((*iV) - val_128) * 0.707);
595  ++iV;
596  V2 = val_2 * V;
597  UV = -U - V;
598  Y0 = *yuv;
599  ++yuv;
600  Y1 = *yuv;
601  yuv = yuv + (width - 1);
602  Y2 = *yuv;
603  ++yuv;
604  Y3 = *yuv;
605  yuv = (yuv - width) + 1;
606 
607  // Original equations
608  // R = Y + 1.402 V
609  // G = Y - 0.344 U - 0.714 V
610  // B = Y + 1.772 U
611  R = Y0 + V2;
612  vpSAT(R);
613 
614  G = Y0 + UV;
615  vpSAT(G);
616 
617  B = Y0 + U5;
618  vpSAT(B);
619 
620  *rgba++ = static_cast<unsigned char>(R);
621  *rgba++ = static_cast<unsigned char>(G);
622  *rgba++ = static_cast<unsigned char>(B);
623  *rgba++ = vpRGBa::alpha_default;
624 
625  //---
626  R = Y1 + V2;
627  vpSAT(R);
628 
629  G = Y1 + UV;
630  vpSAT(G);
631 
632  B = Y1 + U5;
633  vpSAT(B);
634 
635  *rgba++ = static_cast<unsigned char>(R);
636  *rgba++ = static_cast<unsigned char>(G);
637  *rgba++ = static_cast<unsigned char>(B);
638  *rgba = vpRGBa::alpha_default;
639  rgba = (rgba + (val_4 * width)) - val_7;
640 
641  //---
642  R = Y2 + V2;
643  vpSAT(R);
644 
645  G = Y2 + UV;
646  vpSAT(G);
647 
648  B = Y2 + U5;
649  vpSAT(B);
650 
651  *rgba++ = static_cast<unsigned char>(R);
652  *rgba++ = static_cast<unsigned char>(G);
653  *rgba++ = static_cast<unsigned char>(B);
654  *rgba++ = vpRGBa::alpha_default;
655 
656  //---
657  R = Y3 + V2;
658  vpSAT(R);
659 
660  G = Y3 + UV;
661  vpSAT(G);
662 
663  B = Y3 + U5;
664  vpSAT(B);
665 
666  *rgba++ = static_cast<unsigned char>(R);
667  *rgba++ = static_cast<unsigned char>(G);
668  *rgba++ = static_cast<unsigned char>(B);
669  *rgba = vpRGBa::alpha_default;
670  rgba = (rgba - (val_4 * width)) + 1;
671  }
672  yuv += width;
673  rgba += val_4 * width;
674  }
675 }
676 
685 void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
686 {
687  int U, V, R, G, B, V2, U5, UV;
688  int Y0, Y1, Y2, Y3;
689  const unsigned int val_2 = 2;
690  const unsigned int val_3 = 3;
691  const unsigned int val_4 = 4;
692  const unsigned int val_5 = 5;
693  unsigned int size = width * height;
694  unsigned char *iU = yuv + size;
695  unsigned char *iV = yuv + ((val_5 * size) / val_4);
696  const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
697  const unsigned int val_128 = 128;
698  for (unsigned int i = 0; i < halfHeight; ++i) {
699  for (unsigned int j = 0; j < halfWidth; ++j) {
700  U = static_cast<int>(((*iU) - val_128) * 0.354);
701  ++iU;
702  U5 = val_5 * U;
703  V = static_cast<int>(((*iV) - val_128) * 0.707);
704  ++iV;
705  V2 = val_2 * V;
706  UV = -U - V;
707  Y0 = *yuv;
708  ++yuv;
709  Y1 = *yuv;
710  yuv = yuv + (width - 1);
711  Y2 = *yuv;
712  ++yuv;
713  Y3 = *yuv;
714  yuv = (yuv - width) + 1;
715 
716  // Original equations
717  // R = Y + 1.402 V
718  // G = Y - 0.344 U - 0.714 V
719  // B = Y + 1.772 U
720  R = Y0 + V2;
721  vpSAT(R);
722 
723  G = Y0 + UV;
724  vpSAT(G);
725 
726  B = Y0 + U5;
727  vpSAT(B);
728 
729  *rgb++ = static_cast<unsigned char>(R);
730  *rgb++ = static_cast<unsigned char>(G);
731  *rgb++ = static_cast<unsigned char>(B);
732 
733  //---
734  R = Y1 + V2;
735  vpSAT(R);
736 
737  G = Y1 + UV;
738  vpSAT(G);
739 
740  B = Y1 + U5;
741  vpSAT(B);
742 
743  *rgb++ = static_cast<unsigned char>(R);
744  *rgb++ = static_cast<unsigned char>(G);
745  *rgb = static_cast<unsigned char>(B);
746  rgb = rgb + ((val_3 * width) - val_5);
747 
748  //---
749  R = Y2 + V2;
750  vpSAT(R);
751 
752  G = Y2 + UV;
753  vpSAT(G);
754 
755  B = Y2 + U5;
756  vpSAT(B);
757 
758  *rgb++ = static_cast<unsigned char>(R);
759  *rgb++ = static_cast<unsigned char>(G);
760  *rgb++ = static_cast<unsigned char>(B);
761 
762  //---
763  R = Y3 + V2;
764  vpSAT(R);
765 
766  G = Y3 + UV;
767  vpSAT(G);
768 
769  B = Y3 + U5;
770  vpSAT(B);
771 
772  *rgb++ = static_cast<unsigned char>(R);
773  *rgb++ = static_cast<unsigned char>(G);
774  *rgb = static_cast<unsigned char>(B);
775  rgb = (rgb - (val_3 * width)) + 1;
776  }
777  yuv += width;
778  rgb += 3 * width;
779  }
780 }
781 
789 void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
790 {
791  for (unsigned int i = 0; i < size; ++i) {
792  *grey++ = *yuv;
793  ++yuv;
794  }
795 }
796 
806 void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
807 {
808  const unsigned int val_128 = 128;
809  for (unsigned int i = 0; i < size; ++i) {
810  int U = static_cast<int>((*yuv - val_128) * 0.354);
811  ++yuv;
812  int U5 = 5 * U;
813  int Y = *yuv;
814  ++yuv;
815  int V = static_cast<int>((*yuv - val_128) * 0.707);
816  ++yuv;
817  int V2 = 2 * V;
818  int UV = -U - V;
819 
820  // Original equations
821  // R = Y + 1.402 V
822  // G = Y - 0.344 U - 0.714 V
823  // B = Y + 1.772 U
824  int R = Y + V2;
825  vpSAT(R);
826 
827  int G = Y + UV;
828  vpSAT(G);
829 
830  int B = Y + U5;
831  vpSAT(B);
832 
833  *rgba++ = static_cast<unsigned char>(R);
834  *rgba++ = static_cast<unsigned char>(G);
835  *rgba++ = static_cast<unsigned char>(B);
836  *rgba++ = vpRGBa::alpha_default;
837  }
838 }
839 
847 void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
848 {
849  const unsigned int val_128 = 128;
850  for (unsigned int i = 0; i < size; ++i) {
851  int U = static_cast<int>((*yuv - val_128) * 0.354);
852  ++yuv;
853  int U5 = 5 * U;
854  int Y = *yuv;
855  ++yuv;
856  int V = static_cast<int>((*yuv - val_128) * 0.707);
857  ++yuv;
858  int V2 = 2 * V;
859  int UV = -U - V;
860 
861  // Original equations
862  // R = Y + 1.402 V
863  // G = Y - 0.344 U - 0.714 V
864  // B = Y + 1.772 U
865  int R = Y + V2;
866  vpSAT(R);
867 
868  int G = Y + UV;
869  vpSAT(G);
870 
871  int B = Y + U5;
872  vpSAT(B);
873 
874  *rgb++ = static_cast<unsigned char>(R);
875  *rgb++ = static_cast<unsigned char>(G);
876  *rgb++ = static_cast<unsigned char>(B);
877  }
878 }
879 
887 void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
888 {
889  ++yuv;
890  for (unsigned int i = 0; i < size; ++i) {
891  *grey++ = *yuv;
892  yuv = yuv + 3;
893  }
894 }
895 
906 void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
907 {
908  int U, V, R, G, B, V2, U5, UV;
909  int Y0, Y1, Y2, Y3;
910  const unsigned int val_2 = 2;
911  const unsigned int val_4 = 4;
912  const unsigned int val_5 = 5;
913  const unsigned int val_7 = 7;
914  unsigned int size = width * height;
915  unsigned char *iV = yuv + size;
916  unsigned char *iU = yuv + ((val_5 * size) / val_4);
917  const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
918  const unsigned int val_128 = 128;
919  for (unsigned int i = 0; i < halfHeight; ++i) {
920  for (unsigned int j = 0; j < halfWidth; ++j) {
921  U = static_cast<int>(((*iU) - val_128) * 0.354);
922  ++iU;
923  U5 = 5 * U;
924  V = static_cast<int>(((*iV) - val_128) * 0.707);
925  ++iV;
926  V2 = 2 * V;
927  UV = -U - V;
928  Y0 = *yuv;
929  ++yuv;
930  Y1 = *yuv;
931  yuv = yuv + (width - 1);
932  Y2 = *yuv;
933  ++yuv;
934  Y3 = *yuv;
935  yuv = (yuv - width) + 1;
936 
937  // Original equations
938  // R = Y + 1.402 V
939  // G = Y - 0.344 U - 0.714 V
940  // B = Y + 1.772 U
941  R = Y0 + V2;
942  vpSAT(R);
943 
944  G = Y0 + UV;
945  vpSAT(G);
946 
947  B = Y0 + U5;
948  vpSAT(B);
949 
950  *rgba++ = static_cast<unsigned char>(R);
951  *rgba++ = static_cast<unsigned char>(G);
952  *rgba++ = static_cast<unsigned char>(B);
953  *rgba++ = vpRGBa::alpha_default;
954 
955  //---
956  R = Y1 + V2;
957  vpSAT(R);
958 
959  G = Y1 + UV;
960  vpSAT(G);
961 
962  B = Y1 + U5;
963  vpSAT(B);
964 
965  *rgba++ = static_cast<unsigned char>(R);
966  *rgba++ = static_cast<unsigned char>(G);
967  *rgba++ = static_cast<unsigned char>(B);
968  *rgba = 0;
969  rgba = rgba + ((val_4 * width) - val_7);
970 
971  //---
972  R = Y2 + V2;
973  vpSAT(R);
974 
975  G = Y2 + UV;
976  vpSAT(G);
977 
978  B = Y2 + U5;
979  vpSAT(B);
980 
981  *rgba++ = static_cast<unsigned char>(R);
982  *rgba++ = static_cast<unsigned char>(G);
983  *rgba++ = static_cast<unsigned char>(B);
984  *rgba++ = vpRGBa::alpha_default;
985 
986  //---
987  R = Y3 + V2;
988  vpSAT(R);
989 
990  G = Y3 + UV;
991  vpSAT(G);
992 
993  B = Y3 + U5;
994  vpSAT(B);
995 
996  *rgba++ = static_cast<unsigned char>(R);
997  *rgba++ = static_cast<unsigned char>(G);
998  *rgba++ = static_cast<unsigned char>(B);
999  *rgba = vpRGBa::alpha_default;
1000  rgba = (rgba - (val_4 * width)) + 1;
1001  }
1002  yuv += width;
1003  rgba += val_4 * width;
1004  }
1005 }
1006 
1015 void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
1016 {
1017  int U, V, R, G, B, V2, U5, UV;
1018  int Y0, Y1, Y2, Y3;
1019  const unsigned int val_2 = 2;
1020  const unsigned int val_3 = 3;
1021  const unsigned int val_4 = 4;
1022  const unsigned int val_5 = 5;
1023  unsigned int size = width * height;
1024  unsigned char *iV = yuv + size;
1025  unsigned char *iU = yuv + ((val_5 * size) / val_4);
1026  const unsigned int halfHeight = height / val_2, halfWidth = width / val_2;
1027  const unsigned int val_128 = 128;
1028  for (unsigned int i = 0; i < halfHeight; ++i) {
1029  for (unsigned int j = 0; j < halfWidth; ++j) {
1030  U = static_cast<int>(((*iU) - val_128) * 0.354);
1031  ++iU;
1032  U5 = val_5 * U;
1033  V = static_cast<int>(((*iV) - val_128) * 0.707);
1034  ++iV;
1035  V2 = val_2 * V;
1036  UV = -U - V;
1037  Y0 = *yuv;
1038  ++yuv;
1039  Y1 = *yuv;
1040  yuv = yuv + (width - 1);
1041  Y2 = *yuv;
1042  ++yuv;
1043  Y3 = *yuv;
1044  yuv = (yuv - width) + 1;
1045 
1046  // Original equations
1047  // R = Y + 1.402 V
1048  // G = Y - 0.344 U - 0.714 V
1049  // B = Y + 1.772 U
1050  R = Y0 + V2;
1051  vpSAT(R);
1052 
1053  G = Y0 + UV;
1054  vpSAT(G);
1055 
1056  B = Y0 + U5;
1057  vpSAT(B);
1058 
1059  *rgb++ = static_cast<unsigned char>(R);
1060  *rgb++ = static_cast<unsigned char>(G);
1061  *rgb++ = static_cast<unsigned char>(B);
1062 
1063  //---
1064  R = Y1 + V2;
1065  vpSAT(R);
1066 
1067  G = Y1 + UV;
1068  vpSAT(G);
1069 
1070  B = Y1 + U5;
1071  vpSAT(B);
1072 
1073  *rgb++ = static_cast<unsigned char>(R);
1074  *rgb++ = static_cast<unsigned char>(G);
1075  *rgb = static_cast<unsigned char>(B);
1076  rgb = rgb + ((val_3 * width) - 5);
1077 
1078  //---
1079  R = Y2 + V2;
1080  vpSAT(R);
1081 
1082  G = Y2 + UV;
1083  vpSAT(G);
1084 
1085  B = Y2 + U5;
1086  vpSAT(B);
1087 
1088  *rgb++ = static_cast<unsigned char>(R);
1089  *rgb++ = static_cast<unsigned char>(G);
1090  *rgb++ = static_cast<unsigned char>(B);
1091 
1092  //---
1093  R = Y3 + V2;
1094  vpSAT(R);
1095 
1096  G = Y3 + UV;
1097  vpSAT(G);
1098 
1099  B = Y3 + U5;
1100  vpSAT(B);
1101 
1102  *rgb++ = static_cast<unsigned char>(R);
1103  *rgb++ = static_cast<unsigned char>(G);
1104  *rgb = static_cast<unsigned char>(B);
1105  rgb = (rgb - (val_3 * width)) + 1;
1106  }
1107  yuv += width;
1108  rgb += val_3 * width;
1109  }
1110 }
1111 
1112 namespace
1113 {
1124 void YVU9ToRGBasubroutine(unsigned char *rgba, int R, int G, int B, int a)
1125 {
1126  vpSAT(R);
1127  vpSAT(G);
1128  vpSAT(B);
1129  *rgba++ = static_cast<unsigned char>(R);
1130  *rgba++ = static_cast<unsigned char>(G);
1131  *rgba++ = static_cast<unsigned char>(B);
1132  *rgba++ = a;
1133 }
1134 }
1145 void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1146 {
1147  int U, V, R, G, B, V2, U5, UV;
1148  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
1149  const unsigned int val_2 = 2;
1150  const unsigned int val_3 = 3;
1151  const unsigned int val_4 = 4;
1152  const unsigned int val_5 = 5;
1153  const unsigned int val_12 = 12;
1154  const unsigned int val_15 = 15;
1155  const unsigned int val_16 = 16;
1156  const unsigned int val_17 = 17;
1157  unsigned int size = width * height;
1158  unsigned char *iV = yuv + size;
1159  unsigned char *iU = yuv + ((val_17 * size) / val_16);
1160  const unsigned int quarterHeight = height / val_4, quarterWidth = width / val_4;
1161  const unsigned int val_128 = 128;
1162  for (unsigned int i = 0; i < quarterHeight; ++i) {
1163  for (unsigned int j = 0; j < quarterWidth; ++j) {
1164  U = static_cast<int>(((*iU) - val_128) * 0.354);
1165  ++iU;
1166  U5 = val_5 * U;
1167  V = static_cast<int>(((*iV) - val_128) * 0.707);
1168  ++iV;
1169  V2 = val_2 * V;
1170  UV = -U - V;
1171  Y0 = *yuv;
1172  ++yuv;
1173  Y1 = *yuv;
1174  ++yuv;
1175  Y2 = *yuv;
1176  ++yuv;
1177  Y3 = *yuv;
1178  yuv = yuv + (width - val_3);
1179  Y4 = *yuv;
1180  ++yuv;
1181  Y5 = *yuv;
1182  ++yuv;
1183  Y6 = *yuv;
1184  ++yuv;
1185  Y7 = *yuv;
1186  yuv = yuv + (width - val_3);
1187  Y8 = *yuv;
1188  ++yuv;
1189  Y9 = *yuv;
1190  ++yuv;
1191  Y10 = *yuv;
1192  ++yuv;
1193  Y11 = *yuv;
1194  yuv = yuv + (width - val_3);
1195  Y12 = *yuv;
1196  ++yuv;
1197  Y13 = *yuv;
1198  ++yuv;
1199  Y14 = *yuv;
1200  ++yuv;
1201  Y15 = *yuv;
1202  yuv = (yuv - (val_3 * width)) + 1;
1203 
1204  // Original equations
1205  // R = Y + 1.402 V
1206  // G = Y - 0.344 U - 0.714 V
1207  // B = Y + 1.772 U
1208  R = Y0 + V2;
1209  G = Y0 + UV;
1210  B = Y0 + U5;
1211  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1212 
1213  //---
1214  R = Y1 + V2;
1215  G = Y1 + UV;
1216  B = Y1 + U5;
1217  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1218 
1219  //---
1220  R = Y2 + V2;
1221  G = Y2 + UV;
1222  B = Y2 + U5;
1223  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1224 
1225  //---
1226  R = Y3 + V2;
1227  G = Y3 + UV;
1228  B = Y3 + U5;
1229  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1230  rgba = rgba + ((val_4 * width) - val_15);
1231 
1232  R = Y4 + V2;
1233  G = Y4 + UV;
1234  B = Y4 + U5;
1235  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1236 
1237  //---
1238  R = Y5 + V2;
1239  G = Y5 + UV;
1240  B = Y5 + U5;
1241  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1242 
1243  //---
1244  R = Y6 + V2;
1245  G = Y6 + UV;
1246  B = Y6 + U5;
1247  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1248 
1249  //---
1250  R = Y7 + V2;
1251  G = Y7 + UV;
1252  B = Y7 + U5;
1253  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1254  rgba = rgba + ((val_4 * width) - val_15);
1255 
1256  R = Y8 + V2;
1257  G = Y8 + UV;
1258  B = Y8 + U5;
1259  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1260 
1261  //---
1262  R = Y9 + V2;
1263  G = Y9 + UV;
1264  B = Y9 + U5;
1265  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1266 
1267  //---
1268  R = Y10 + V2;
1269  G = Y10 + UV;
1270  B = Y10 + U5;
1271  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1272 
1273  //---
1274  R = Y11 + V2;
1275  G = Y11 + UV;
1276  B = Y11 + U5;
1277  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1278  rgba = rgba + ((val_4 * width) - val_15);
1279 
1280  R = Y12 + V2;
1281  G = Y12 + UV;
1282  B = Y12 + U5;
1283  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1284 
1285  //---
1286  R = Y13 + V2;
1287  G = Y13 + UV;
1288  B = Y13 + U5;
1289  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1290 
1291  //---
1292  R = Y14 + V2;
1293  G = Y14 + UV;
1294  B = Y14 + U5;
1295  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1296 
1297  //---
1298  R = Y15 + V2;
1299  G = Y15 + UV;
1300  B = Y15 + U5;
1301  YVU9ToRGBasubroutine(rgba, R, G, B, vpRGBa::alpha_default);
1302  rgba = (rgba - (val_12 * width)) + 1;
1303  }
1304  yuv += val_3 * width;
1305  rgba += val_12 * width;
1306  }
1307 }
1308 
1309 namespace
1310 {
1320 void YVU9ToRGBsubroutine(unsigned char *rgb, int R, int G, int B)
1321 {
1322  vpSAT(R);
1323  vpSAT(G);
1324  vpSAT(B);
1325  *rgb++ = static_cast<unsigned char>(R);
1326  *rgb++ = static_cast<unsigned char>(G);
1327  *rgb++ = static_cast<unsigned char>(B);
1328 }
1329 }
1330 
1338 void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
1339 {
1340  int U, V, R, G, B, V2, U5, UV;
1341  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
1342  const unsigned int val_2 = 2;
1343  const unsigned int val_3 = 3;
1344  const unsigned int val_4 = 4;
1345  const unsigned int val_5 = 5;
1346  const unsigned int val_9 = 9;
1347  const unsigned int val_16 = 16;
1348  const unsigned int val_17 = 17;
1349  unsigned int size = width * height;
1350  unsigned char *iV = yuv + size;
1351  unsigned char *iU = yuv + ((val_17 * size) / val_16);
1352  const unsigned int quarterHeight = height / val_4, quarterWidth = width / val_4;
1353  const unsigned int val_128 = 128;
1354  for (unsigned int i = 0; i < quarterHeight; ++i) {
1355  for (unsigned int j = 0; j < quarterWidth; ++j) {
1356  U = static_cast<int>((*iU - val_128) * 0.354);
1357  ++iU;
1358  U5 = val_5 * U;
1359  V = static_cast<int>((*iV - val_128) * 0.707);
1360  ++iV;
1361  V2 = val_2 * V;
1362  UV = -U - V;
1363  Y0 = *yuv;
1364  ++yuv;
1365  Y1 = *yuv;
1366  ++yuv;
1367  Y2 = *yuv;
1368  ++yuv;
1369  Y3 = *yuv;
1370  yuv = yuv + (width - val_3);
1371  Y4 = *yuv;
1372  ++yuv;
1373  Y5 = *yuv;
1374  ++yuv;
1375  Y6 = *yuv;
1376  ++yuv;
1377  Y7 = *yuv;
1378  yuv = yuv + (width - val_3);
1379  Y8 = *yuv;
1380  ++yuv;
1381  Y9 = *yuv;
1382  ++yuv;
1383  Y10 = *yuv;
1384  ++yuv;
1385  Y11 = *yuv;
1386  yuv = yuv + (width - val_3);
1387  Y12 = *yuv;
1388  ++yuv;
1389  Y13 = *yuv;
1390  ++yuv;
1391  Y14 = *yuv;
1392  ++yuv;
1393  Y15 = *yuv;
1394  yuv = (yuv - (val_3 * width)) + 1;
1395 
1396  // Original equations
1397  // R = Y + 1.402 V
1398  // G = Y - 0.344 U - 0.714 V
1399  // B = Y + 1.772 U
1400  R = Y0 + V2;
1401  G = Y0 + UV;
1402  B = Y0 + U5;
1403  YVU9ToRGBsubroutine(rgb, R, G, B);
1404 
1405  //---
1406  R = Y1 + V2;
1407  G = Y1 + UV;
1408  B = Y1 + U5;
1409  YVU9ToRGBsubroutine(rgb, R, G, B);
1410 
1411  //---
1412  R = Y2 + V2;
1413  G = Y2 + UV;
1414  B = Y2 + U5;
1415  YVU9ToRGBsubroutine(rgb, R, G, B);
1416 
1417  //---
1418  R = Y3 + V2;
1419  G = Y3 + UV;
1420  B = Y3 + U5;
1421  YVU9ToRGBsubroutine(rgb, R, G, B);
1422  rgb = rgb + ((val_3 * width) - 11);
1423 
1424  R = Y4 + V2;
1425  G = Y4 + UV;
1426  B = Y4 + U5;
1427  YVU9ToRGBsubroutine(rgb, R, G, B);
1428 
1429  //---
1430  R = Y5 + V2;
1431  G = Y5 + UV;
1432  B = Y5 + U5;
1433  YVU9ToRGBsubroutine(rgb, R, G, B);
1434 
1435  //---
1436  R = Y6 + V2;
1437  G = Y6 + UV;
1438  B = Y6 + U5;
1439  YVU9ToRGBsubroutine(rgb, R, G, B);
1440 
1441  //---
1442  R = Y7 + V2;
1443  G = Y7 + UV;
1444  B = Y7 + U5;
1445  YVU9ToRGBsubroutine(rgb, R, G, B);
1446  rgb = rgb + ((val_3 * width) - 11);
1447 
1448  R = Y8 + V2;
1449  G = Y8 + UV;
1450  B = Y8 + U5;
1451  YVU9ToRGBsubroutine(rgb, R, G, B);
1452 
1453  //---
1454  R = Y9 + V2;
1455  G = Y9 + UV;
1456  B = Y9 + U5;
1457  YVU9ToRGBsubroutine(rgb, R, G, B);
1458 
1459  //---
1460  R = Y10 + V2;
1461  G = Y10 + UV;
1462  B = Y10 + U5;
1463  YVU9ToRGBsubroutine(rgb, R, G, B);
1464 
1465  //---
1466  R = Y11 + V2;
1467  G = Y11 + UV;
1468  B = Y11 + U5;
1469  YVU9ToRGBsubroutine(rgb, R, G, B);
1470  rgb = (rgb + (val_3 * width)) - 11;
1471 
1472  R = Y12 + V2;
1473  G = Y12 + UV;
1474  B = Y12 + U5;
1475  YVU9ToRGBsubroutine(rgb, R, G, B);
1476 
1477  //---
1478  R = Y13 + V2;
1479  G = Y13 + UV;
1480  B = Y13 + U5;
1481  YVU9ToRGBsubroutine(rgb, R, G, B);
1482 
1483  //---
1484  R = Y14 + V2;
1485  G = Y14 + UV;
1486  B = Y14 + U5;
1487  YVU9ToRGBsubroutine(rgb, R, G, B);
1488 
1489  //---
1490  R = Y15 + V2;
1491  G = Y15 + UV;
1492  B = Y15 + U5;
1493  YVU9ToRGBsubroutine(rgb, R, G, B);
1494  rgb = (rgb - (val_9 * width)) + 1;
1495  }
1496  yuv += val_3 * width;
1497  rgb += val_9 * width;
1498  }
1499 }
1500 END_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:67