Visual Servoing Platform  version 3.5.1 under development (2023-09-22)
vpImageConvert.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Convert image types.
33  *
34 *****************************************************************************/
35 
41 #include <map>
42 #include <sstream>
43 
44 #if defined _OPENMP
45 #include <omp.h>
46 #endif
47 
48 // image
49 #include "private/vpBayerConversion.h"
50 #include "private/vpImageConvert_impl.h"
51 #include <Simd/SimdLib.hpp>
52 #include <visp3/core/vpImageConvert.h>
53 
54 bool vpImageConvert::YCbCrLUTcomputed = false;
55 int vpImageConvert::vpCrr[256];
56 int vpImageConvert::vpCgb[256];
57 int vpImageConvert::vpCgr[256];
58 int vpImageConvert::vpCbb[256];
59 
69 {
70  dest.resize(src.getHeight(), src.getWidth());
71 
72  GreyToRGBa(src.bitmap, reinterpret_cast<unsigned char *>(dest.bitmap), src.getWidth(), src.getHeight());
73 }
74 
84 void vpImageConvert::convert(const vpImage<vpRGBa> &src, vpImage<unsigned char> &dest, unsigned int nThreads)
85 {
86  dest.resize(src.getHeight(), src.getWidth());
87 
88  RGBaToGrey(reinterpret_cast<unsigned char *>(src.bitmap), dest.bitmap, src.getWidth(), src.getHeight(), nThreads);
89 }
90 
98 {
99  dest.resize(src.getHeight(), src.getWidth());
100  unsigned int max_xy = src.getWidth() * src.getHeight();
101  float min, max;
102 
103  src.getMinMaxValue(min, max);
104 
105  for (unsigned int i = 0; i < max_xy; i++) {
106  float val = 255.f * (src.bitmap[i] - min) / (max - min);
107  if (val < 0)
108  dest.bitmap[i] = 0;
109  else if (val > 255)
110  dest.bitmap[i] = 255;
111  else
112  dest.bitmap[i] = (unsigned char)val;
113  }
114 }
115 
123 {
124  dest.resize(src.getHeight(), src.getWidth());
125  vpRGBf min, max;
126  src.getMinMaxValue(min, max);
127 
128  for (unsigned int i = 0; i < src.getHeight(); i++) {
129  for (unsigned int j = 0; j < src.getWidth(); j++) {
130  for (unsigned int c = 0; c < 3; c++) {
131  float val = 255.f * (reinterpret_cast<const float *>(&(src[i][j]))[c] - reinterpret_cast<float *>(&min)[c]) /
132  (reinterpret_cast<float *>(&max)[c] - reinterpret_cast<float *>(&min)[c]);
133  if (val < 0)
134  reinterpret_cast<unsigned char *>(&(dest[i][j]))[c] = 0;
135  else if (val > 255)
136  reinterpret_cast<unsigned char *>(&(dest[i][j]))[c] = 255;
137  else
138  reinterpret_cast<unsigned char *>(&(dest[i][j]))[c] = (unsigned char)val;
139  }
140  }
141  }
142 }
143 
150 {
151  dest.resize(src.getHeight(), src.getWidth());
152  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
153  dest.bitmap[i] = (float)src.bitmap[i];
154 }
155 
163 {
164  dest.resize(src.getHeight(), src.getWidth());
165  unsigned int max_xy = src.getWidth() * src.getHeight();
166  double min, max;
167 
168  src.getMinMaxValue(min, max);
169 
170  for (unsigned int i = 0; i < max_xy; i++) {
171  double val = 255. * (src.bitmap[i] - min) / (max - min);
172  if (val < 0)
173  dest.bitmap[i] = 0;
174  else if (val > 255)
175  dest.bitmap[i] = 255;
176  else
177  dest.bitmap[i] = (unsigned char)val;
178  }
179 }
180 
187 void vpImageConvert::convert(const vpImage<uint16_t> &src, vpImage<unsigned char> &dest, unsigned char bitshift)
188 {
189  dest.resize(src.getHeight(), src.getWidth());
190 
191  for (unsigned int i = 0; i < src.getSize(); i++)
192  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] >> bitshift);
193 }
194 
201 void vpImageConvert::convert(const vpImage<unsigned char> &src, vpImage<uint16_t> &dest, unsigned char bitshift)
202 {
203  dest.resize(src.getHeight(), src.getWidth());
204 
205  for (unsigned int i = 0; i < src.getSize(); i++)
206  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] << bitshift);
207 }
208 
215 {
216  dest.resize(src.getHeight(), src.getWidth());
217  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
218  dest.bitmap[i] = (double)src.bitmap[i];
219 }
220 
229 {
230  vp_createDepthHistogram(src_depth, dest_rgba);
231 }
232 
240 {
241  vp_createDepthHistogram(src_depth, dest_depth);
242 }
243 
252 {
253  vp_createDepthHistogram(src_depth, dest_rgba);
254 }
255 
263 {
264  vp_createDepthHistogram(src_depth, dest_depth);
265 }
266 
267 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
268 
309 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, bool flip)
310 {
311  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
312 
313  if (src.type() == CV_8UC4) {
314  vpRGBa rgbaVal;
315  for (unsigned int i = 0; i < dest.getRows(); ++i)
316  for (unsigned int j = 0; j < dest.getCols(); ++j) {
317  cv::Vec4b tmp = src.at<cv::Vec4b>((int)i, (int)j);
318  rgbaVal.R = tmp[2];
319  rgbaVal.G = tmp[1];
320  rgbaVal.B = tmp[0];
321  rgbaVal.A = tmp[3];
322  if (flip)
323  dest[dest.getRows() - i - 1][j] = rgbaVal;
324  else
325  dest[i][j] = rgbaVal;
326  }
327  }
328  else if (src.type() == CV_8UC3) {
329  if (src.isContinuous() && !flip) {
330  SimdRgbToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
331  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
332  }
333  else {
334  vpRGBa rgbaVal;
335  rgbaVal.A = vpRGBa::alpha_default;
336  for (unsigned int i = 0; i < dest.getRows(); ++i) {
337  for (unsigned int j = 0; j < dest.getCols(); ++j) {
338  cv::Vec3b tmp = src.at<cv::Vec3b>((int)i, (int)j);
339  rgbaVal.R = tmp[2];
340  rgbaVal.G = tmp[1];
341  rgbaVal.B = tmp[0];
342  if (flip) {
343  dest[dest.getRows() - i - 1][j] = rgbaVal;
344  }
345  else {
346  dest[i][j] = rgbaVal;
347  }
348  }
349  }
350  }
351  }
352  else if (src.type() == CV_8UC1) {
353  if (src.isContinuous() && !flip) {
354  SimdGrayToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
355  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
356  }
357  else {
358  vpRGBa rgbaVal;
359  for (unsigned int i = 0; i < dest.getRows(); ++i) {
360  for (unsigned int j = 0; j < dest.getCols(); ++j) {
361  rgbaVal = src.at<unsigned char>((int)i, (int)j);
362  if (flip) {
363  dest[dest.getRows() - i - 1][j] = rgbaVal;
364  }
365  else {
366  dest[i][j] = rgbaVal;
367  }
368  }
369  }
370  }
371  }
372 }
373 
409 void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, bool flip, unsigned int nThreads)
410 {
411  if (src.type() == CV_8UC1) {
412  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
413  if (src.isContinuous() && !flip) {
414  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols));
415  }
416  else {
417  if (flip) {
418  for (unsigned int i = 0; i < dest.getRows(); ++i) {
419  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1(), (size_t)src.step);
420  }
421  }
422  else {
423  for (unsigned int i = 0; i < dest.getRows(); ++i) {
424  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1(), (size_t)src.step);
425  }
426  }
427  }
428  }
429  else if (src.type() == CV_8UC3) {
430  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
431  if (src.isContinuous()) {
432  BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows,
433  flip, nThreads);
434  }
435  else {
436  if (flip) {
437  for (unsigned int i = 0; i < dest.getRows(); ++i) {
438  BGRToGrey((unsigned char *)src.data + i * src.step1(),
439  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
440  (unsigned int)dest.getCols(), 1, false);
441  }
442  }
443  else {
444  for (unsigned int i = 0; i < dest.getRows(); ++i) {
445  BGRToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
446  (unsigned int)dest.getCols(), 1, false);
447  }
448  }
449  }
450  }
451  else if (src.type() == CV_8UC4) {
452  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
453  if (src.isContinuous()) {
454  BGRaToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols,
455  (unsigned int)src.rows, flip, nThreads);
456  }
457  else {
458  if (flip) {
459  for (unsigned int i = 0; i < dest.getRows(); ++i) {
460  BGRaToGrey((unsigned char *)src.data + i * src.step1(),
461  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
462  (unsigned int)dest.getCols(), 1, false);
463  }
464  }
465  else {
466  for (unsigned int i = 0; i < dest.getRows(); ++i) {
467  BGRaToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
468  (unsigned int)dest.getCols(), 1, false);
469  }
470  }
471  }
472  }
473 }
474 
482 void vpImageConvert::convert(const cv::Mat &src, vpImage<float> &dest, bool flip)
483 {
484  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
485 
486  if (src.type() == CV_32FC1) {
487  for (unsigned int i = 0; i < dest.getRows(); ++i)
488  for (unsigned int j = 0; j < dest.getCols(); ++j) {
489  if (flip)
490  dest[dest.getRows() - i - 1][j] = src.at<float>((int)i, (int)j);
491  else
492  dest[i][j] = src.at<float>((int)i, (int)j);
493  }
494  }
495  else {
496  throw vpException(vpException::badValue, "cv::Mat type is not supported!");
497  }
498 }
499 
507 void vpImageConvert::convert(const cv::Mat &src, vpImage<uint16_t> &dest, bool flip)
508 {
509  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
510 
511  if (src.type() == CV_16UC1) {
512  if (src.isContinuous()) {
513  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols) * sizeof(uint16_t));
514  }
515  else {
516  if (flip) {
517  for (unsigned int i = 0; i < dest.getRows(); ++i) {
518  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1() * sizeof(uint16_t), (size_t)src.step);
519  }
520  }
521  else {
522  for (unsigned int i = 0; i < dest.getRows(); ++i) {
523  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1() * sizeof(uint16_t), (size_t)src.step);
524  }
525  }
526  }
527  }
528  else {
529  throw(vpException(vpException::fatalError, "cv:Mat format not supported for conversion into vpImage<uint16_t>"));
530  }
531 }
532 
540 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBf> &dest, bool flip)
541 {
542  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
543 
544  if (src.type() == CV_32FC3) {
545  vpRGBf rgbVal;
546  for (unsigned int i = 0; i < dest.getRows(); ++i)
547  for (unsigned int j = 0; j < dest.getCols(); ++j) {
548  cv::Vec3f tmp = src.at<cv::Vec3f>((int)i, (int)j);
549  rgbVal.R = tmp[2];
550  rgbVal.G = tmp[1];
551  rgbVal.B = tmp[0];
552  if (flip)
553  dest[dest.getRows() - i - 1][j] = rgbVal;
554  else
555  dest[i][j] = rgbVal;
556  }
557  }
558  else {
559  throw vpException(vpException::badValue, "cv::Mat type is not supported!");
560  }
561 }
562 
599 void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
600 {
601  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_8UC4, (void *)src.bitmap);
602  cv::cvtColor(vpToMat, dest, cv::COLOR_RGBA2BGR);
603 }
604 
643 void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, bool copyData)
644 {
645  if (copyData) {
646  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
647  dest = tmpMap.clone();
648  }
649  else {
650  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
651  }
652 }
653 
654 void vpImageConvert::convert(const vpImage<float> &src, cv::Mat &dest, bool copyData)
655 {
656  if (copyData) {
657  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_32FC1, (void *)src.bitmap);
658  dest = tmpMap.clone();
659  }
660  else {
661  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_32FC1, (void *)src.bitmap);
662  }
663 }
664 
665 void vpImageConvert::convert(const vpImage<vpRGBf> &src, cv::Mat &dest)
666 {
667  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_32FC3, (void *)src.bitmap);
668  cv::cvtColor(vpToMat, dest, cv::COLOR_RGB2BGR);
669 }
670 
671 #endif
672 
673 #ifdef VISP_HAVE_YARP
707 void vpImageConvert::convert(const vpImage<unsigned char> &src, yarp::sig::ImageOf<yarp::sig::PixelMono> *dest,
708  bool copyData)
709 {
710  if (copyData) {
711  dest->resize(src.getWidth(), src.getHeight());
712  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth());
713  }
714  else
715  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
716 }
717 
756 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelMono> *src, vpImage<unsigned char> &dest,
757  bool copyData)
758 {
759  dest.resize(src->height(), src->width());
760  if (copyData)
761  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelMono));
762  else
763  dest.bitmap = src->getRawImage();
764 }
765 
800 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgba> *dest, bool copyData)
801 {
802  if (copyData) {
803  dest->resize(src.getWidth(), src.getHeight());
804  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() * sizeof(vpRGBa));
805  }
806  else
807  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
808 }
809 
848 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgba> *src, vpImage<vpRGBa> &dest, bool copyData)
849 {
850  dest.resize(src->height(), src->width());
851  if (copyData)
852  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelRgba));
853  else
854  dest.bitmap = static_cast<vpRGBa *>(src->getRawImage());
855 }
856 
889 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgb> *dest)
890 {
891  dest->resize(src.getWidth(), src.getHeight());
892  for (unsigned int i = 0; i < src.getRows(); i++) {
893  for (unsigned int j = 0; j < src.getWidth(); j++) {
894  dest->pixel(j, i).r = src[i][j].R;
895  dest->pixel(j, i).g = src[i][j].G;
896  dest->pixel(j, i).b = src[i][j].B;
897  }
898  }
899 }
900 
939 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgb> *src, vpImage<vpRGBa> &dest)
940 {
941  dest.resize(src->height(), src->width());
942  for (int i = 0; i < src->height(); i++) {
943  for (int j = 0; j < src->width(); j++) {
944  dest[i][j].R = src->pixel(j, i).r;
945  dest[i][j].G = src->pixel(j, i).g;
946  dest[i][j].B = src->pixel(j, i).b;
947  dest[i][j].A = vpRGBa::alpha_default;
948  }
949  }
950 }
951 
952 #endif
953 
954 #define vpSAT(c) \
955  if (c & (~255)) { \
956  if (c < 0) \
957  c = 0; \
958  else \
959  c = 255; \
960  }
973 void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
974 {
975  unsigned char *s;
976  unsigned char *d;
977  int w, h;
978  int r, g, b, cr, cg, cb, y1, y2;
979 
980  h = (int)height;
981  w = (int)width;
982  s = yuyv;
983  d = rgba;
984  while (h--) {
985  int c = w >> 1;
986  while (c--) {
987  y1 = *s++;
988  cb = ((*s - 128) * 454) >> 8;
989  cg = (*s++ - 128) * 88;
990  y2 = *s++;
991  cr = ((*s - 128) * 359) >> 8;
992  cg = (cg + (*s++ - 128) * 183) >> 8;
993 
994  r = y1 + cr;
995  b = y1 + cb;
996  g = y1 - cg;
997  vpSAT(r) vpSAT(g) vpSAT(b)
998 
999  *d++ = static_cast<unsigned char>(r);
1000  *d++ = static_cast<unsigned char>(g);
1001  *d++ = static_cast<unsigned char>(b);
1002  *d++ = vpRGBa::alpha_default;
1003 
1004  r = y2 + cr;
1005  b = y2 + cb;
1006  g = y2 - cg;
1007  vpSAT(r) vpSAT(g) vpSAT(b)
1008 
1009  *d++ = static_cast<unsigned char>(r);
1010  *d++ = static_cast<unsigned char>(g);
1011  *d++ = static_cast<unsigned char>(b);
1012  *d++ = vpRGBa::alpha_default;
1013  }
1014  }
1015 }
1016 
1027 void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
1028 {
1029  unsigned char *s;
1030  unsigned char *d;
1031  int h, w;
1032  int r, g, b, cr, cg, cb, y1, y2;
1033 
1034  h = (int)height;
1035  w = (int)width;
1036  s = yuyv;
1037  d = rgb;
1038  while (h--) {
1039  int c = w >> 1;
1040  while (c--) {
1041  y1 = *s++;
1042  cb = ((*s - 128) * 454) >> 8;
1043  cg = (*s++ - 128) * 88;
1044  y2 = *s++;
1045  cr = ((*s - 128) * 359) >> 8;
1046  cg = (cg + (*s++ - 128) * 183) >> 8;
1047 
1048  r = y1 + cr;
1049  b = y1 + cb;
1050  g = y1 - cg;
1051  vpSAT(r) vpSAT(g) vpSAT(b)
1052 
1053  *d++ = static_cast<unsigned char>(r);
1054  *d++ = static_cast<unsigned char>(g);
1055  *d++ = static_cast<unsigned char>(b);
1056 
1057  r = y2 + cr;
1058  b = y2 + cb;
1059  g = y2 - cg;
1060  vpSAT(r) vpSAT(g) vpSAT(b)
1061 
1062  *d++ = static_cast<unsigned char>(r);
1063  *d++ = static_cast<unsigned char>(g);
1064  *d++ = static_cast<unsigned char>(b);
1065  }
1066  }
1067 }
1068 
1079 void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
1080 {
1081  unsigned int i = 0, j = 0;
1082 
1083  while (j < size * 2) {
1084  grey[i++] = yuyv[j];
1085  grey[i++] = yuyv[j + 2];
1086  j += 4;
1087  }
1088 }
1089 
1099 void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1100 {
1101 #if 1
1102  // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1103  for (unsigned int i = size / 4; i; i--) {
1104  int U = (int)((*yuv++ - 128) * 0.354);
1105  int U5 = 5 * U;
1106  int Y0 = *yuv++;
1107  int Y1 = *yuv++;
1108  int V = (int)((*yuv++ - 128) * 0.707);
1109  int V2 = 2 * V;
1110  int Y2 = *yuv++;
1111  int Y3 = *yuv++;
1112  int UV = -U - V;
1113 
1114  // Original equations
1115  // R = Y + 1.402 V
1116  // G = Y - 0.344 U - 0.714 V
1117  // B = Y + 1.772 U
1118  int R = Y0 + V2;
1119  if ((R >> 8) > 0)
1120  R = 255;
1121  else if (R < 0)
1122  R = 0;
1123 
1124  int G = Y0 + UV;
1125  if ((G >> 8) > 0)
1126  G = 255;
1127  else if (G < 0)
1128  G = 0;
1129 
1130  int B = Y0 + U5;
1131  if ((B >> 8) > 0)
1132  B = 255;
1133  else if (B < 0)
1134  B = 0;
1135 
1136  *rgba++ = (unsigned char)R;
1137  *rgba++ = (unsigned char)G;
1138  *rgba++ = (unsigned char)B;
1139  *rgba++ = vpRGBa::alpha_default;
1140 
1141  //---
1142  R = Y1 + V2;
1143  if ((R >> 8) > 0)
1144  R = 255;
1145  else if (R < 0)
1146  R = 0;
1147 
1148  G = Y1 + UV;
1149  if ((G >> 8) > 0)
1150  G = 255;
1151  else if (G < 0)
1152  G = 0;
1153 
1154  B = Y1 + U5;
1155  if ((B >> 8) > 0)
1156  B = 255;
1157  else if (B < 0)
1158  B = 0;
1159 
1160  *rgba++ = (unsigned char)R;
1161  *rgba++ = (unsigned char)G;
1162  *rgba++ = (unsigned char)B;
1163  *rgba++ = vpRGBa::alpha_default;
1164 
1165  //---
1166  R = Y2 + V2;
1167  if ((R >> 8) > 0)
1168  R = 255;
1169  else if (R < 0)
1170  R = 0;
1171 
1172  G = Y2 + UV;
1173  if ((G >> 8) > 0)
1174  G = 255;
1175  else if (G < 0)
1176  G = 0;
1177 
1178  B = Y2 + U5;
1179  if ((B >> 8) > 0)
1180  B = 255;
1181  else if (B < 0)
1182  B = 0;
1183 
1184  *rgba++ = (unsigned char)R;
1185  *rgba++ = (unsigned char)G;
1186  *rgba++ = (unsigned char)B;
1187  *rgba++ = vpRGBa::alpha_default;
1188 
1189  //---
1190  R = Y3 + V2;
1191  if ((R >> 8) > 0)
1192  R = 255;
1193  else if (R < 0)
1194  R = 0;
1195 
1196  G = Y3 + UV;
1197  if ((G >> 8) > 0)
1198  G = 255;
1199  else if (G < 0)
1200  G = 0;
1201 
1202  B = Y3 + U5;
1203  if ((B >> 8) > 0)
1204  B = 255;
1205  else if (B < 0)
1206  B = 0;
1207 
1208  *rgba++ = (unsigned char)R;
1209  *rgba++ = (unsigned char)G;
1210  *rgba++ = (unsigned char)B;
1211  *rgba++ = vpRGBa::alpha_default;
1212  }
1213 #else
1214  // tres tres lent ....
1215  unsigned int i = 0, j = 0;
1216  unsigned char r, g, b;
1217  while (j < numpixels * 3 / 2) {
1218 
1219  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1220  rgba[i] = r;
1221  rgba[i + 1] = g;
1222  rgba[i + 2] = b;
1223  rgba[i + 3] = vpRGBa::alpha_default;
1224  i += 4;
1225 
1226  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1227  rgba[i] = r;
1228  rgba[i + 1] = g;
1229  rgba[i + 2] = b;
1230  rgba[i + 3] = vpRGBa::alpha_default;
1231  i += 4;
1232 
1233  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1234  rgba[i] = r;
1235  rgba[i + 1] = g;
1236  rgba[i + 2] = b;
1237  rgba[i + 3] = vpRGBa::alpha_default;
1238  i += 4;
1239 
1240  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1241  rgba[i] = r;
1242  rgba[i + 1] = g;
1243  rgba[i + 2] = b;
1244  rgba[i + 3] = vpRGBa::alpha_default;
1245  i += 4;
1246 
1247  j += 6;
1248  }
1249 #endif
1250 }
1251 
1264 void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1265 {
1266 
1267 #if 1
1268  // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1269  for (unsigned int i = size / 2; i; i--) {
1270  int U = (int)((*yuv++ - 128) * 0.354);
1271  int U5 = 5 * U;
1272  int Y0 = *yuv++;
1273  int V = (int)((*yuv++ - 128) * 0.707);
1274  int V2 = 2 * V;
1275  int Y1 = *yuv++;
1276  int UV = -U - V;
1277 
1278  //---
1279  int R = Y0 + V2;
1280  if ((R >> 8) > 0)
1281  R = 255;
1282  else if (R < 0)
1283  R = 0;
1284 
1285  int G = Y0 + UV;
1286  if ((G >> 8) > 0)
1287  G = 255;
1288  else if (G < 0)
1289  G = 0;
1290 
1291  int B = Y0 + U5;
1292  if ((B >> 8) > 0)
1293  B = 255;
1294  else if (B < 0)
1295  B = 0;
1296 
1297  *rgba++ = (unsigned char)R;
1298  *rgba++ = (unsigned char)G;
1299  *rgba++ = (unsigned char)B;
1300  *rgba++ = vpRGBa::alpha_default;
1301 
1302  //---
1303  R = Y1 + V2;
1304  if ((R >> 8) > 0)
1305  R = 255;
1306  else if (R < 0)
1307  R = 0;
1308 
1309  G = Y1 + UV;
1310  if ((G >> 8) > 0)
1311  G = 255;
1312  else if (G < 0)
1313  G = 0;
1314 
1315  B = Y1 + U5;
1316  if ((B >> 8) > 0)
1317  B = 255;
1318  else if (B < 0)
1319  B = 0;
1320 
1321  *rgba++ = (unsigned char)R;
1322  *rgba++ = (unsigned char)G;
1323  *rgba++ = (unsigned char)B;
1324  *rgba++ = vpRGBa::alpha_default;
1325  }
1326 
1327 #else
1328  // tres tres lent ....
1329  unsigned int i = 0, j = 0;
1330  unsigned char r, g, b;
1331 
1332  while (j < size * 2) {
1333 
1334  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1335  rgba[i] = r;
1336  rgba[i + 1] = g;
1337  rgba[i + 2] = b;
1338  rgba[i + 3] = vpRGBa::alpha_default;
1339  i += 4;
1340 
1341  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1342  rgba[i] = r;
1343  rgba[i + 1] = g;
1344  rgba[i + 2] = b;
1345  rgba[i + 3] = vpRGBa::alpha_default;
1346  i += 4;
1347  j += 4;
1348  }
1349 #endif
1350 }
1351 
1360 void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1361 {
1362  unsigned int i = 0, j = 0;
1363  while (j < size * 3 / 2) {
1364  grey[i] = yuv[j + 1];
1365  grey[i + 1] = yuv[j + 2];
1366  grey[i + 2] = yuv[j + 4];
1367  grey[i + 3] = yuv[j + 5];
1368 
1369  i += 4;
1370 
1371  j += 6;
1372  }
1373 }
1374 
1385 void vpImageConvert::YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1386 {
1387 #if 1
1388  // std::cout << "call optimized convertYUV422ToRGB()" << std::endl;
1389  for (unsigned int i = size / 2; i; i--) {
1390  int U = (int)((*yuv++ - 128) * 0.354);
1391  int U5 = 5 * U;
1392  int Y0 = *yuv++;
1393  int V = (int)((*yuv++ - 128) * 0.707);
1394  int V2 = 2 * V;
1395  int Y1 = *yuv++;
1396  int UV = -U - V;
1397 
1398  //---
1399  int R = Y0 + V2;
1400  if ((R >> 8) > 0)
1401  R = 255;
1402  else if (R < 0)
1403  R = 0;
1404 
1405  int G = Y0 + UV;
1406  if ((G >> 8) > 0)
1407  G = 255;
1408  else if (G < 0)
1409  G = 0;
1410 
1411  int B = Y0 + U5;
1412  if ((B >> 8) > 0)
1413  B = 255;
1414  else if (B < 0)
1415  B = 0;
1416 
1417  *rgb++ = (unsigned char)R;
1418  *rgb++ = (unsigned char)G;
1419  *rgb++ = (unsigned char)B;
1420 
1421  //---
1422  R = Y1 + V2;
1423  if ((R >> 8) > 0)
1424  R = 255;
1425  else if (R < 0)
1426  R = 0;
1427 
1428  G = Y1 + UV;
1429  if ((G >> 8) > 0)
1430  G = 255;
1431  else if (G < 0)
1432  G = 0;
1433 
1434  B = Y1 + U5;
1435  if ((B >> 8) > 0)
1436  B = 255;
1437  else if (B < 0)
1438  B = 0;
1439 
1440  *rgb++ = (unsigned char)R;
1441  *rgb++ = (unsigned char)G;
1442  *rgb++ = (unsigned char)B;
1443  }
1444 
1445 #else
1446  // tres tres lent ....
1447  unsigned int i = 0, j = 0;
1448  unsigned char r, g, b;
1449 
1450  while (j < size * 2) {
1451 
1452  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1453  rgb[i] = r;
1454  rgb[i + 1] = g;
1455  rgb[i + 2] = b;
1456  i += 3;
1457 
1458  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1459  rgb[i] = r;
1460  rgb[i + 1] = g;
1461  rgb[i + 2] = b;
1462  i += 3;
1463  j += 4;
1464  }
1465 #endif
1466 }
1467 
1478 void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1479 {
1480  unsigned int i = 0, j = 0;
1481 
1482  while (j < size * 2) {
1483  grey[i++] = yuv[j + 1];
1484  grey[i++] = yuv[j + 3];
1485  j += 4;
1486  }
1487 }
1488 
1497 void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1498 {
1499 #if 1
1500  // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1501  for (unsigned int i = size / 4; i; i--) {
1502  int U = (int)((*yuv++ - 128) * 0.354);
1503  int U5 = 5 * U;
1504  int Y0 = *yuv++;
1505  int Y1 = *yuv++;
1506  int V = (int)((*yuv++ - 128) * 0.707);
1507  int V2 = 2 * V;
1508  int Y2 = *yuv++;
1509  int Y3 = *yuv++;
1510  int UV = -U - V;
1511 
1512  // Original equations
1513  // R = Y + 1.402 V
1514  // G = Y - 0.344 U - 0.714 V
1515  // B = Y + 1.772 U
1516  int R = Y0 + V2;
1517  if ((R >> 8) > 0)
1518  R = 255;
1519  else if (R < 0)
1520  R = 0;
1521 
1522  int G = Y0 + UV;
1523  if ((G >> 8) > 0)
1524  G = 255;
1525  else if (G < 0)
1526  G = 0;
1527 
1528  int B = Y0 + U5;
1529  if ((B >> 8) > 0)
1530  B = 255;
1531  else if (B < 0)
1532  B = 0;
1533 
1534  *rgb++ = (unsigned char)R;
1535  *rgb++ = (unsigned char)G;
1536  *rgb++ = (unsigned char)B;
1537 
1538  //---
1539  R = Y1 + V2;
1540  if ((R >> 8) > 0)
1541  R = 255;
1542  else if (R < 0)
1543  R = 0;
1544 
1545  G = Y1 + UV;
1546  if ((G >> 8) > 0)
1547  G = 255;
1548  else if (G < 0)
1549  G = 0;
1550 
1551  B = Y1 + U5;
1552  if ((B >> 8) > 0)
1553  B = 255;
1554  else if (B < 0)
1555  B = 0;
1556 
1557  *rgb++ = (unsigned char)R;
1558  *rgb++ = (unsigned char)G;
1559  *rgb++ = (unsigned char)B;
1560 
1561  //---
1562  R = Y2 + V2;
1563  if ((R >> 8) > 0)
1564  R = 255;
1565  else if (R < 0)
1566  R = 0;
1567 
1568  G = Y2 + UV;
1569  if ((G >> 8) > 0)
1570  G = 255;
1571  else if (G < 0)
1572  G = 0;
1573 
1574  B = Y2 + U5;
1575  if ((B >> 8) > 0)
1576  B = 255;
1577  else if (B < 0)
1578  B = 0;
1579 
1580  *rgb++ = (unsigned char)R;
1581  *rgb++ = (unsigned char)G;
1582  *rgb++ = (unsigned char)B;
1583 
1584  //---
1585  R = Y3 + V2;
1586  if ((R >> 8) > 0)
1587  R = 255;
1588  else if (R < 0)
1589  R = 0;
1590 
1591  G = Y3 + UV;
1592  if ((G >> 8) > 0)
1593  G = 255;
1594  else if (G < 0)
1595  G = 0;
1596 
1597  B = Y3 + U5;
1598  if ((B >> 8) > 0)
1599  B = 255;
1600  else if (B < 0)
1601  B = 0;
1602 
1603  *rgb++ = (unsigned char)R;
1604  *rgb++ = (unsigned char)G;
1605  *rgb++ = (unsigned char)B;
1606  }
1607 #else
1608  // tres tres lent ....
1609 
1610  unsigned int i = 0, j = 0;
1611  unsigned char r, g, b;
1612 
1613  while (j < size * 3 / 2) {
1614  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1615  rgb[i] = r;
1616  rgb[i + 1] = g;
1617  rgb[i + 2] = b;
1618  i += 3;
1619 
1620  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1621  rgb[i] = r;
1622  rgb[i + 1] = g;
1623  rgb[i + 2] = b;
1624  i += 3;
1625 
1626  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1627  rgb[i] = r;
1628  rgb[i + 1] = g;
1629  rgb[i + 2] = b;
1630  i += 3;
1631 
1632  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1633  rgb[i] = r;
1634  rgb[i + 1] = g;
1635  rgb[i + 2] = b;
1636  i += 3;
1637  // TRACE("r= %d g=%d b=%d", r, g, b);
1638 
1639  j += 6;
1640  }
1641 #endif
1642 }
1643 
1654 void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1655 {
1656  // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
1657  int U, V, R, G, B, V2, U5, UV;
1658  int Y0, Y1, Y2, Y3;
1659  unsigned int size = width * height;
1660  unsigned char *iU = yuv + size;
1661  unsigned char *iV = yuv + 5 * size / 4;
1662  for (unsigned int i = 0; i < height / 2; i++) {
1663  for (unsigned int j = 0; j < width / 2; j++) {
1664  U = (int)((*iU++ - 128) * 0.354);
1665  U5 = 5 * U;
1666  V = (int)((*iV++ - 128) * 0.707);
1667  V2 = 2 * V;
1668  UV = -U - V;
1669  Y0 = *yuv++;
1670  Y1 = *yuv;
1671  yuv = yuv + width - 1;
1672  Y2 = *yuv++;
1673  Y3 = *yuv;
1674  yuv = yuv - width + 1;
1675 
1676  // Original equations
1677  // R = Y + 1.402 V
1678  // G = Y - 0.344 U - 0.714 V
1679  // B = Y + 1.772 U
1680  R = Y0 + V2;
1681  if ((R >> 8) > 0)
1682  R = 255;
1683  else if (R < 0)
1684  R = 0;
1685 
1686  G = Y0 + UV;
1687  if ((G >> 8) > 0)
1688  G = 255;
1689  else if (G < 0)
1690  G = 0;
1691 
1692  B = Y0 + U5;
1693  if ((B >> 8) > 0)
1694  B = 255;
1695  else if (B < 0)
1696  B = 0;
1697 
1698  *rgba++ = (unsigned char)R;
1699  *rgba++ = (unsigned char)G;
1700  *rgba++ = (unsigned char)B;
1701  *rgba++ = vpRGBa::alpha_default;
1702 
1703  //---
1704  R = Y1 + V2;
1705  if ((R >> 8) > 0)
1706  R = 255;
1707  else if (R < 0)
1708  R = 0;
1709 
1710  G = Y1 + UV;
1711  if ((G >> 8) > 0)
1712  G = 255;
1713  else if (G < 0)
1714  G = 0;
1715 
1716  B = Y1 + U5;
1717  if ((B >> 8) > 0)
1718  B = 255;
1719  else if (B < 0)
1720  B = 0;
1721 
1722  *rgba++ = (unsigned char)R;
1723  *rgba++ = (unsigned char)G;
1724  *rgba++ = (unsigned char)B;
1725  *rgba = vpRGBa::alpha_default;
1726  rgba = rgba + 4 * width - 7;
1727 
1728  //---
1729  R = Y2 + V2;
1730  if ((R >> 8) > 0)
1731  R = 255;
1732  else if (R < 0)
1733  R = 0;
1734 
1735  G = Y2 + UV;
1736  if ((G >> 8) > 0)
1737  G = 255;
1738  else if (G < 0)
1739  G = 0;
1740 
1741  B = Y2 + U5;
1742  if ((B >> 8) > 0)
1743  B = 255;
1744  else if (B < 0)
1745  B = 0;
1746 
1747  *rgba++ = (unsigned char)R;
1748  *rgba++ = (unsigned char)G;
1749  *rgba++ = (unsigned char)B;
1750  *rgba++ = vpRGBa::alpha_default;
1751 
1752  //---
1753  R = Y3 + V2;
1754  if ((R >> 8) > 0)
1755  R = 255;
1756  else if (R < 0)
1757  R = 0;
1758 
1759  G = Y3 + UV;
1760  if ((G >> 8) > 0)
1761  G = 255;
1762  else if (G < 0)
1763  G = 0;
1764 
1765  B = Y3 + U5;
1766  if ((B >> 8) > 0)
1767  B = 255;
1768  else if (B < 0)
1769  B = 0;
1770 
1771  *rgba++ = (unsigned char)R;
1772  *rgba++ = (unsigned char)G;
1773  *rgba++ = (unsigned char)B;
1774  *rgba = vpRGBa::alpha_default;
1775  rgba = rgba - 4 * width + 1;
1776  }
1777  yuv += width;
1778  rgba += 4 * width;
1779  }
1780 }
1781 
1790 void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
1791 {
1792  // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
1793  int U, V, R, G, B, V2, U5, UV;
1794  int Y0, Y1, Y2, Y3;
1795  unsigned int size = width * height;
1796  unsigned char *iU = yuv + size;
1797  unsigned char *iV = yuv + 5 * size / 4;
1798  for (unsigned int i = 0; i < height / 2; i++) {
1799  for (unsigned int j = 0; j < width / 2; j++) {
1800  U = (int)((*iU++ - 128) * 0.354);
1801  U5 = 5 * U;
1802  V = (int)((*iV++ - 128) * 0.707);
1803  V2 = 2 * V;
1804  UV = -U - V;
1805  Y0 = *yuv++;
1806  Y1 = *yuv;
1807  yuv = yuv + width - 1;
1808  Y2 = *yuv++;
1809  Y3 = *yuv;
1810  yuv = yuv - width + 1;
1811 
1812  // Original equations
1813  // R = Y + 1.402 V
1814  // G = Y - 0.344 U - 0.714 V
1815  // B = Y + 1.772 U
1816  R = Y0 + V2;
1817  if ((R >> 8) > 0)
1818  R = 255;
1819  else if (R < 0)
1820  R = 0;
1821 
1822  G = Y0 + UV;
1823  if ((G >> 8) > 0)
1824  G = 255;
1825  else if (G < 0)
1826  G = 0;
1827 
1828  B = Y0 + U5;
1829  if ((B >> 8) > 0)
1830  B = 255;
1831  else if (B < 0)
1832  B = 0;
1833 
1834  *rgb++ = (unsigned char)R;
1835  *rgb++ = (unsigned char)G;
1836  *rgb++ = (unsigned char)B;
1837 
1838  //---
1839  R = Y1 + V2;
1840  if ((R >> 8) > 0)
1841  R = 255;
1842  else if (R < 0)
1843  R = 0;
1844 
1845  G = Y1 + UV;
1846  if ((G >> 8) > 0)
1847  G = 255;
1848  else if (G < 0)
1849  G = 0;
1850 
1851  B = Y1 + U5;
1852  if ((B >> 8) > 0)
1853  B = 255;
1854  else if (B < 0)
1855  B = 0;
1856 
1857  *rgb++ = (unsigned char)R;
1858  *rgb++ = (unsigned char)G;
1859  *rgb = (unsigned char)B;
1860  rgb = rgb + 3 * width - 5;
1861 
1862  //---
1863  R = Y2 + V2;
1864  if ((R >> 8) > 0)
1865  R = 255;
1866  else if (R < 0)
1867  R = 0;
1868 
1869  G = Y2 + UV;
1870  if ((G >> 8) > 0)
1871  G = 255;
1872  else if (G < 0)
1873  G = 0;
1874 
1875  B = Y2 + U5;
1876  if ((B >> 8) > 0)
1877  B = 255;
1878  else if (B < 0)
1879  B = 0;
1880 
1881  *rgb++ = (unsigned char)R;
1882  *rgb++ = (unsigned char)G;
1883  *rgb++ = (unsigned char)B;
1884 
1885  //---
1886  R = Y3 + V2;
1887  if ((R >> 8) > 0)
1888  R = 255;
1889  else if (R < 0)
1890  R = 0;
1891 
1892  G = Y3 + UV;
1893  if ((G >> 8) > 0)
1894  G = 255;
1895  else if (G < 0)
1896  G = 0;
1897 
1898  B = Y3 + U5;
1899  if ((B >> 8) > 0)
1900  B = 255;
1901  else if (B < 0)
1902  B = 0;
1903 
1904  *rgb++ = (unsigned char)R;
1905  *rgb++ = (unsigned char)G;
1906  *rgb = (unsigned char)B;
1907  rgb = rgb - 3 * width + 1;
1908  }
1909  yuv += width;
1910  rgb += 3 * width;
1911  }
1912 }
1913 
1921 void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1922 {
1923  for (unsigned int i = 0; i < size; i++) {
1924  *grey++ = *yuv++;
1925  }
1926 }
1927 
1937 void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1938 {
1939  for (unsigned int i = 0; i < size; i++) {
1940  int U = (int)((*yuv++ - 128) * 0.354);
1941  int U5 = 5 * U;
1942  int Y = *yuv++;
1943  int V = (int)((*yuv++ - 128) * 0.707);
1944  int V2 = 2 * V;
1945  int UV = -U - V;
1946 
1947  // Original equations
1948  // R = Y + 1.402 V
1949  // G = Y - 0.344 U - 0.714 V
1950  // B = Y + 1.772 U
1951  int R = Y + V2;
1952  if ((R >> 8) > 0)
1953  R = 255;
1954  else if (R < 0)
1955  R = 0;
1956 
1957  int G = Y + UV;
1958  if ((G >> 8) > 0)
1959  G = 255;
1960  else if (G < 0)
1961  G = 0;
1962 
1963  int B = Y + U5;
1964  if ((B >> 8) > 0)
1965  B = 255;
1966  else if (B < 0)
1967  B = 0;
1968 
1969  *rgba++ = (unsigned char)R;
1970  *rgba++ = (unsigned char)G;
1971  *rgba++ = (unsigned char)B;
1972  *rgba++ = vpRGBa::alpha_default;
1973  }
1974 }
1975 
1983 void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1984 {
1985  for (unsigned int i = 0; i < size; i++) {
1986  int U = (int)((*yuv++ - 128) * 0.354);
1987  int U5 = 5 * U;
1988  int Y = *yuv++;
1989  int V = (int)((*yuv++ - 128) * 0.707);
1990  int V2 = 2 * V;
1991  int UV = -U - V;
1992 
1993  // Original equations
1994  // R = Y + 1.402 V
1995  // G = Y - 0.344 U - 0.714 V
1996  // B = Y + 1.772 U
1997  int R = Y + V2;
1998  if ((R >> 8) > 0)
1999  R = 255;
2000  else if (R < 0)
2001  R = 0;
2002 
2003  int G = Y + UV;
2004  if ((G >> 8) > 0)
2005  G = 255;
2006  else if (G < 0)
2007  G = 0;
2008 
2009  int B = Y + U5;
2010  if ((B >> 8) > 0)
2011  B = 255;
2012  else if (B < 0)
2013  B = 0;
2014 
2015  *rgb++ = (unsigned char)R;
2016  *rgb++ = (unsigned char)G;
2017  *rgb++ = (unsigned char)B;
2018  }
2019 }
2020 
2028 void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2029 {
2030  yuv++;
2031  for (unsigned int i = 0; i < size; i++) {
2032  *grey++ = *yuv;
2033  yuv = yuv + 3;
2034  }
2035 }
2036 
2047 void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2048 {
2049  // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
2050  int U, V, R, G, B, V2, U5, UV;
2051  int Y0, Y1, Y2, Y3;
2052  unsigned int size = width * height;
2053  unsigned char *iV = yuv + size;
2054  unsigned char *iU = yuv + 5 * size / 4;
2055  for (unsigned int i = 0; i < height / 2; i++) {
2056  for (unsigned int j = 0; j < width / 2; j++) {
2057  U = (int)((*iU++ - 128) * 0.354);
2058  U5 = 5 * U;
2059  V = (int)((*iV++ - 128) * 0.707);
2060  V2 = 2 * V;
2061  UV = -U - V;
2062  Y0 = *yuv++;
2063  Y1 = *yuv;
2064  yuv = yuv + width - 1;
2065  Y2 = *yuv++;
2066  Y3 = *yuv;
2067  yuv = yuv - width + 1;
2068 
2069  // Original equations
2070  // R = Y + 1.402 V
2071  // G = Y - 0.344 U - 0.714 V
2072  // B = Y + 1.772 U
2073  R = Y0 + V2;
2074  if ((R >> 8) > 0)
2075  R = 255;
2076  else if (R < 0)
2077  R = 0;
2078 
2079  G = Y0 + UV;
2080  if ((G >> 8) > 0)
2081  G = 255;
2082  else if (G < 0)
2083  G = 0;
2084 
2085  B = Y0 + U5;
2086  if ((B >> 8) > 0)
2087  B = 255;
2088  else if (B < 0)
2089  B = 0;
2090 
2091  *rgba++ = (unsigned char)R;
2092  *rgba++ = (unsigned char)G;
2093  *rgba++ = (unsigned char)B;
2094  *rgba++ = vpRGBa::alpha_default;
2095 
2096  //---
2097  R = Y1 + V2;
2098  if ((R >> 8) > 0)
2099  R = 255;
2100  else if (R < 0)
2101  R = 0;
2102 
2103  G = Y1 + UV;
2104  if ((G >> 8) > 0)
2105  G = 255;
2106  else if (G < 0)
2107  G = 0;
2108 
2109  B = Y1 + U5;
2110  if ((B >> 8) > 0)
2111  B = 255;
2112  else if (B < 0)
2113  B = 0;
2114 
2115  *rgba++ = (unsigned char)R;
2116  *rgba++ = (unsigned char)G;
2117  *rgba++ = (unsigned char)B;
2118  *rgba = 0;
2119  rgba = rgba + 4 * width - 7;
2120 
2121  //---
2122  R = Y2 + V2;
2123  if ((R >> 8) > 0)
2124  R = 255;
2125  else if (R < 0)
2126  R = 0;
2127 
2128  G = Y2 + UV;
2129  if ((G >> 8) > 0)
2130  G = 255;
2131  else if (G < 0)
2132  G = 0;
2133 
2134  B = Y2 + U5;
2135  if ((B >> 8) > 0)
2136  B = 255;
2137  else if (B < 0)
2138  B = 0;
2139 
2140  *rgba++ = (unsigned char)R;
2141  *rgba++ = (unsigned char)G;
2142  *rgba++ = (unsigned char)B;
2143  *rgba++ = vpRGBa::alpha_default;
2144 
2145  //---
2146  R = Y3 + V2;
2147  if ((R >> 8) > 0)
2148  R = 255;
2149  else if (R < 0)
2150  R = 0;
2151 
2152  G = Y3 + UV;
2153  if ((G >> 8) > 0)
2154  G = 255;
2155  else if (G < 0)
2156  G = 0;
2157 
2158  B = Y3 + U5;
2159  if ((B >> 8) > 0)
2160  B = 255;
2161  else if (B < 0)
2162  B = 0;
2163 
2164  *rgba++ = (unsigned char)R;
2165  *rgba++ = (unsigned char)G;
2166  *rgba++ = (unsigned char)B;
2167  *rgba = vpRGBa::alpha_default;
2168  rgba = rgba - 4 * width + 1;
2169  }
2170  yuv += width;
2171  rgba += 4 * width;
2172  }
2173 }
2174 
2183 void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2184 {
2185  // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2186  int U, V, R, G, B, V2, U5, UV;
2187  int Y0, Y1, Y2, Y3;
2188  unsigned int size = width * height;
2189  unsigned char *iV = yuv + size;
2190  unsigned char *iU = yuv + 5 * size / 4;
2191  for (unsigned int i = 0; i < height / 2; i++) {
2192  for (unsigned int j = 0; j < width / 2; j++) {
2193  U = (int)((*iU++ - 128) * 0.354);
2194  U5 = 5 * U;
2195  V = (int)((*iV++ - 128) * 0.707);
2196  V2 = 2 * V;
2197  UV = -U - V;
2198  Y0 = *yuv++;
2199  Y1 = *yuv;
2200  yuv = yuv + width - 1;
2201  Y2 = *yuv++;
2202  Y3 = *yuv;
2203  yuv = yuv - width + 1;
2204 
2205  // Original equations
2206  // R = Y + 1.402 V
2207  // G = Y - 0.344 U - 0.714 V
2208  // B = Y + 1.772 U
2209  R = Y0 + V2;
2210  if ((R >> 8) > 0)
2211  R = 255;
2212  else if (R < 0)
2213  R = 0;
2214 
2215  G = Y0 + UV;
2216  if ((G >> 8) > 0)
2217  G = 255;
2218  else if (G < 0)
2219  G = 0;
2220 
2221  B = Y0 + U5;
2222  if ((B >> 8) > 0)
2223  B = 255;
2224  else if (B < 0)
2225  B = 0;
2226 
2227  *rgb++ = (unsigned char)R;
2228  *rgb++ = (unsigned char)G;
2229  *rgb++ = (unsigned char)B;
2230 
2231  //---
2232  R = Y1 + V2;
2233  if ((R >> 8) > 0)
2234  R = 255;
2235  else if (R < 0)
2236  R = 0;
2237 
2238  G = Y1 + UV;
2239  if ((G >> 8) > 0)
2240  G = 255;
2241  else if (G < 0)
2242  G = 0;
2243 
2244  B = Y1 + U5;
2245  if ((B >> 8) > 0)
2246  B = 255;
2247  else if (B < 0)
2248  B = 0;
2249 
2250  *rgb++ = (unsigned char)R;
2251  *rgb++ = (unsigned char)G;
2252  *rgb = (unsigned char)B;
2253  rgb = rgb + 3 * width - 5;
2254 
2255  //---
2256  R = Y2 + V2;
2257  if ((R >> 8) > 0)
2258  R = 255;
2259  else if (R < 0)
2260  R = 0;
2261 
2262  G = Y2 + UV;
2263  if ((G >> 8) > 0)
2264  G = 255;
2265  else if (G < 0)
2266  G = 0;
2267 
2268  B = Y2 + U5;
2269  if ((B >> 8) > 0)
2270  B = 255;
2271  else if (B < 0)
2272  B = 0;
2273 
2274  *rgb++ = (unsigned char)R;
2275  *rgb++ = (unsigned char)G;
2276  *rgb++ = (unsigned char)B;
2277 
2278  //---
2279  R = Y3 + V2;
2280  if ((R >> 8) > 0)
2281  R = 255;
2282  else if (R < 0)
2283  R = 0;
2284 
2285  G = Y3 + UV;
2286  if ((G >> 8) > 0)
2287  G = 255;
2288  else if (G < 0)
2289  G = 0;
2290 
2291  B = Y3 + U5;
2292  if ((B >> 8) > 0)
2293  B = 255;
2294  else if (B < 0)
2295  B = 0;
2296 
2297  *rgb++ = (unsigned char)R;
2298  *rgb++ = (unsigned char)G;
2299  *rgb = (unsigned char)B;
2300  rgb = rgb - 3 * width + 1;
2301  }
2302  yuv += width;
2303  rgb += 3 * width;
2304  }
2305 }
2306 
2317 void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2318 {
2319  // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2320  int U, V, R, G, B, V2, U5, UV;
2321  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2322  unsigned int size = width * height;
2323  unsigned char *iV = yuv + size;
2324  unsigned char *iU = yuv + 17 * size / 16;
2325  for (unsigned int i = 0; i < height / 4; i++) {
2326  for (unsigned int j = 0; j < width / 4; j++) {
2327  U = (int)((*iU++ - 128) * 0.354);
2328  U5 = 5 * U;
2329  V = (int)((*iV++ - 128) * 0.707);
2330  V2 = 2 * V;
2331  UV = -U - V;
2332  Y0 = *yuv++;
2333  Y1 = *yuv++;
2334  Y2 = *yuv++;
2335  Y3 = *yuv;
2336  yuv = yuv + width - 3;
2337  Y4 = *yuv++;
2338  Y5 = *yuv++;
2339  Y6 = *yuv++;
2340  Y7 = *yuv;
2341  yuv = yuv + width - 3;
2342  Y8 = *yuv++;
2343  Y9 = *yuv++;
2344  Y10 = *yuv++;
2345  Y11 = *yuv;
2346  yuv = yuv + width - 3;
2347  Y12 = *yuv++;
2348  Y13 = *yuv++;
2349  Y14 = *yuv++;
2350  Y15 = *yuv;
2351  yuv = yuv - 3 * width + 1;
2352 
2353  // Original equations
2354  // R = Y + 1.402 V
2355  // G = Y - 0.344 U - 0.714 V
2356  // B = Y + 1.772 U
2357  R = Y0 + V2;
2358  if ((R >> 8) > 0)
2359  R = 255;
2360  else if (R < 0)
2361  R = 0;
2362 
2363  G = Y0 + UV;
2364  if ((G >> 8) > 0)
2365  G = 255;
2366  else if (G < 0)
2367  G = 0;
2368 
2369  B = Y0 + U5;
2370  if ((B >> 8) > 0)
2371  B = 255;
2372  else if (B < 0)
2373  B = 0;
2374 
2375  *rgba++ = (unsigned char)R;
2376  *rgba++ = (unsigned char)G;
2377  *rgba++ = (unsigned char)B;
2378  *rgba++ = vpRGBa::alpha_default;
2379 
2380  //---
2381  R = Y1 + V2;
2382  if ((R >> 8) > 0)
2383  R = 255;
2384  else if (R < 0)
2385  R = 0;
2386 
2387  G = Y1 + UV;
2388  if ((G >> 8) > 0)
2389  G = 255;
2390  else if (G < 0)
2391  G = 0;
2392 
2393  B = Y1 + U5;
2394  if ((B >> 8) > 0)
2395  B = 255;
2396  else if (B < 0)
2397  B = 0;
2398 
2399  *rgba++ = (unsigned char)R;
2400  *rgba++ = (unsigned char)G;
2401  *rgba++ = (unsigned char)B;
2402  *rgba++ = vpRGBa::alpha_default;
2403 
2404  //---
2405  R = Y2 + V2;
2406  if ((R >> 8) > 0)
2407  R = 255;
2408  else if (R < 0)
2409  R = 0;
2410 
2411  G = Y2 + UV;
2412  if ((G >> 8) > 0)
2413  G = 255;
2414  else if (G < 0)
2415  G = 0;
2416 
2417  B = Y2 + U5;
2418  if ((B >> 8) > 0)
2419  B = 255;
2420  else if (B < 0)
2421  B = 0;
2422 
2423  *rgba++ = (unsigned char)R;
2424  *rgba++ = (unsigned char)G;
2425  *rgba++ = (unsigned char)B;
2426  *rgba++ = vpRGBa::alpha_default;
2427 
2428  //---
2429  R = Y3 + V2;
2430  if ((R >> 8) > 0)
2431  R = 255;
2432  else if (R < 0)
2433  R = 0;
2434 
2435  G = Y3 + UV;
2436  if ((G >> 8) > 0)
2437  G = 255;
2438  else if (G < 0)
2439  G = 0;
2440 
2441  B = Y3 + U5;
2442  if ((B >> 8) > 0)
2443  B = 255;
2444  else if (B < 0)
2445  B = 0;
2446 
2447  *rgba++ = (unsigned char)R;
2448  *rgba++ = (unsigned char)G;
2449  *rgba++ = (unsigned char)B;
2450  *rgba = vpRGBa::alpha_default;
2451  rgba = rgba + 4 * width - 15;
2452 
2453  R = Y4 + V2;
2454  if ((R >> 8) > 0)
2455  R = 255;
2456  else if (R < 0)
2457  R = 0;
2458 
2459  G = Y4 + UV;
2460  if ((G >> 8) > 0)
2461  G = 255;
2462  else if (G < 0)
2463  G = 0;
2464 
2465  B = Y4 + U5;
2466  if ((B >> 8) > 0)
2467  B = 255;
2468  else if (B < 0)
2469  B = 0;
2470 
2471  *rgba++ = (unsigned char)R;
2472  *rgba++ = (unsigned char)G;
2473  *rgba++ = (unsigned char)B;
2474  *rgba++ = vpRGBa::alpha_default;
2475 
2476  //---
2477  R = Y5 + V2;
2478  if ((R >> 8) > 0)
2479  R = 255;
2480  else if (R < 0)
2481  R = 0;
2482 
2483  G = Y5 + UV;
2484  if ((G >> 8) > 0)
2485  G = 255;
2486  else if (G < 0)
2487  G = 0;
2488 
2489  B = Y5 + U5;
2490  if ((B >> 8) > 0)
2491  B = 255;
2492  else if (B < 0)
2493  B = 0;
2494 
2495  *rgba++ = (unsigned char)R;
2496  *rgba++ = (unsigned char)G;
2497  *rgba++ = (unsigned char)B;
2498  *rgba++ = vpRGBa::alpha_default;
2499 
2500  //---
2501  R = Y6 + V2;
2502  if ((R >> 8) > 0)
2503  R = 255;
2504  else if (R < 0)
2505  R = 0;
2506 
2507  G = Y6 + UV;
2508  if ((G >> 8) > 0)
2509  G = 255;
2510  else if (G < 0)
2511  G = 0;
2512 
2513  B = Y6 + U5;
2514  if ((B >> 8) > 0)
2515  B = 255;
2516  else if (B < 0)
2517  B = 0;
2518 
2519  *rgba++ = (unsigned char)R;
2520  *rgba++ = (unsigned char)G;
2521  *rgba++ = (unsigned char)B;
2522  *rgba++ = vpRGBa::alpha_default;
2523 
2524  //---
2525  R = Y7 + V2;
2526  if ((R >> 8) > 0)
2527  R = 255;
2528  else if (R < 0)
2529  R = 0;
2530 
2531  G = Y7 + UV;
2532  if ((G >> 8) > 0)
2533  G = 255;
2534  else if (G < 0)
2535  G = 0;
2536 
2537  B = Y7 + U5;
2538  if ((B >> 8) > 0)
2539  B = 255;
2540  else if (B < 0)
2541  B = 0;
2542 
2543  *rgba++ = (unsigned char)R;
2544  *rgba++ = (unsigned char)G;
2545  *rgba++ = (unsigned char)B;
2546  *rgba = vpRGBa::alpha_default;
2547  rgba = rgba + 4 * width - 15;
2548 
2549  R = Y8 + V2;
2550  if ((R >> 8) > 0)
2551  R = 255;
2552  else if (R < 0)
2553  R = 0;
2554 
2555  G = Y8 + UV;
2556  if ((G >> 8) > 0)
2557  G = 255;
2558  else if (G < 0)
2559  G = 0;
2560 
2561  B = Y8 + U5;
2562  if ((B >> 8) > 0)
2563  B = 255;
2564  else if (B < 0)
2565  B = 0;
2566 
2567  *rgba++ = (unsigned char)R;
2568  *rgba++ = (unsigned char)G;
2569  *rgba++ = (unsigned char)B;
2570  *rgba++ = vpRGBa::alpha_default;
2571 
2572  //---
2573  R = Y9 + V2;
2574  if ((R >> 8) > 0)
2575  R = 255;
2576  else if (R < 0)
2577  R = 0;
2578 
2579  G = Y9 + UV;
2580  if ((G >> 8) > 0)
2581  G = 255;
2582  else if (G < 0)
2583  G = 0;
2584 
2585  B = Y9 + U5;
2586  if ((B >> 8) > 0)
2587  B = 255;
2588  else if (B < 0)
2589  B = 0;
2590 
2591  *rgba++ = (unsigned char)R;
2592  *rgba++ = (unsigned char)G;
2593  *rgba++ = (unsigned char)B;
2594  *rgba++ = vpRGBa::alpha_default;
2595 
2596  //---
2597  R = Y10 + V2;
2598  if ((R >> 8) > 0)
2599  R = 255;
2600  else if (R < 0)
2601  R = 0;
2602 
2603  G = Y10 + UV;
2604  if ((G >> 8) > 0)
2605  G = 255;
2606  else if (G < 0)
2607  G = 0;
2608 
2609  B = Y10 + U5;
2610  if ((B >> 8) > 0)
2611  B = 255;
2612  else if (B < 0)
2613  B = 0;
2614 
2615  *rgba++ = (unsigned char)R;
2616  *rgba++ = (unsigned char)G;
2617  *rgba++ = (unsigned char)B;
2618  *rgba++ = vpRGBa::alpha_default;
2619 
2620  //---
2621  R = Y11 + V2;
2622  if ((R >> 8) > 0)
2623  R = 255;
2624  else if (R < 0)
2625  R = 0;
2626 
2627  G = Y11 + UV;
2628  if ((G >> 8) > 0)
2629  G = 255;
2630  else if (G < 0)
2631  G = 0;
2632 
2633  B = Y11 + U5;
2634  if ((B >> 8) > 0)
2635  B = 255;
2636  else if (B < 0)
2637  B = 0;
2638 
2639  *rgba++ = (unsigned char)R;
2640  *rgba++ = (unsigned char)G;
2641  *rgba++ = (unsigned char)B;
2642  *rgba = vpRGBa::alpha_default;
2643  rgba = rgba + 4 * width - 15;
2644 
2645  R = Y12 + V2;
2646  if ((R >> 8) > 0)
2647  R = 255;
2648  else if (R < 0)
2649  R = 0;
2650 
2651  G = Y12 + UV;
2652  if ((G >> 8) > 0)
2653  G = 255;
2654  else if (G < 0)
2655  G = 0;
2656 
2657  B = Y12 + U5;
2658  if ((B >> 8) > 0)
2659  B = 255;
2660  else if (B < 0)
2661  B = 0;
2662 
2663  *rgba++ = (unsigned char)R;
2664  *rgba++ = (unsigned char)G;
2665  *rgba++ = (unsigned char)B;
2666  *rgba++ = vpRGBa::alpha_default;
2667 
2668  //---
2669  R = Y13 + V2;
2670  if ((R >> 8) > 0)
2671  R = 255;
2672  else if (R < 0)
2673  R = 0;
2674 
2675  G = Y13 + UV;
2676  if ((G >> 8) > 0)
2677  G = 255;
2678  else if (G < 0)
2679  G = 0;
2680 
2681  B = Y13 + U5;
2682  if ((B >> 8) > 0)
2683  B = 255;
2684  else if (B < 0)
2685  B = 0;
2686 
2687  *rgba++ = (unsigned char)R;
2688  *rgba++ = (unsigned char)G;
2689  *rgba++ = (unsigned char)B;
2690  *rgba++ = vpRGBa::alpha_default;
2691 
2692  //---
2693  R = Y14 + V2;
2694  if ((R >> 8) > 0)
2695  R = 255;
2696  else if (R < 0)
2697  R = 0;
2698 
2699  G = Y14 + UV;
2700  if ((G >> 8) > 0)
2701  G = 255;
2702  else if (G < 0)
2703  G = 0;
2704 
2705  B = Y14 + U5;
2706  if ((B >> 8) > 0)
2707  B = 255;
2708  else if (B < 0)
2709  B = 0;
2710 
2711  *rgba++ = (unsigned char)R;
2712  *rgba++ = (unsigned char)G;
2713  *rgba++ = (unsigned char)B;
2714  *rgba++ = vpRGBa::alpha_default;
2715 
2716  //---
2717  R = Y15 + V2;
2718  if ((R >> 8) > 0)
2719  R = 255;
2720  else if (R < 0)
2721  R = 0;
2722 
2723  G = Y15 + UV;
2724  if ((G >> 8) > 0)
2725  G = 255;
2726  else if (G < 0)
2727  G = 0;
2728 
2729  B = Y15 + U5;
2730  if ((B >> 8) > 0)
2731  B = 255;
2732  else if (B < 0)
2733  B = 0;
2734 
2735  *rgba++ = (unsigned char)R;
2736  *rgba++ = (unsigned char)G;
2737  *rgba++ = (unsigned char)B;
2738  *rgba = vpRGBa::alpha_default;
2739  rgba = rgba - 12 * width + 1;
2740  }
2741  yuv += 3 * width;
2742  rgba += 12 * width;
2743  }
2744 }
2745 
2753 void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2754 {
2755  // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
2756  int U, V, R, G, B, V2, U5, UV;
2757  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2758  unsigned int size = width * height;
2759  unsigned char *iV = yuv + size;
2760  unsigned char *iU = yuv + 17 * size / 16;
2761  for (unsigned int i = 0; i < height / 4; i++) {
2762  for (unsigned int j = 0; j < width / 4; j++) {
2763  U = (int)((*iU++ - 128) * 0.354);
2764  U5 = 5 * U;
2765  V = (int)((*iV++ - 128) * 0.707);
2766  V2 = 2 * V;
2767  UV = -U - V;
2768  Y0 = *yuv++;
2769  Y1 = *yuv++;
2770  Y2 = *yuv++;
2771  Y3 = *yuv;
2772  yuv = yuv + width - 3;
2773  Y4 = *yuv++;
2774  Y5 = *yuv++;
2775  Y6 = *yuv++;
2776  Y7 = *yuv;
2777  yuv = yuv + width - 3;
2778  Y8 = *yuv++;
2779  Y9 = *yuv++;
2780  Y10 = *yuv++;
2781  Y11 = *yuv;
2782  yuv = yuv + width - 3;
2783  Y12 = *yuv++;
2784  Y13 = *yuv++;
2785  Y14 = *yuv++;
2786  Y15 = *yuv;
2787  yuv = yuv - 3 * width + 1;
2788 
2789  // Original equations
2790  // R = Y + 1.402 V
2791  // G = Y - 0.344 U - 0.714 V
2792  // B = Y + 1.772 U
2793  R = Y0 + V2;
2794  if ((R >> 8) > 0)
2795  R = 255;
2796  else if (R < 0)
2797  R = 0;
2798 
2799  G = Y0 + UV;
2800  if ((G >> 8) > 0)
2801  G = 255;
2802  else if (G < 0)
2803  G = 0;
2804 
2805  B = Y0 + U5;
2806  if ((B >> 8) > 0)
2807  B = 255;
2808  else if (B < 0)
2809  B = 0;
2810 
2811  *rgb++ = (unsigned char)R;
2812  *rgb++ = (unsigned char)G;
2813  *rgb++ = (unsigned char)B;
2814 
2815  //---
2816  R = Y1 + V2;
2817  if ((R >> 8) > 0)
2818  R = 255;
2819  else if (R < 0)
2820  R = 0;
2821 
2822  G = Y1 + UV;
2823  if ((G >> 8) > 0)
2824  G = 255;
2825  else if (G < 0)
2826  G = 0;
2827 
2828  B = Y1 + U5;
2829  if ((B >> 8) > 0)
2830  B = 255;
2831  else if (B < 0)
2832  B = 0;
2833 
2834  *rgb++ = (unsigned char)R;
2835  *rgb++ = (unsigned char)G;
2836  *rgb++ = (unsigned char)B;
2837 
2838  //---
2839  R = Y2 + V2;
2840  if ((R >> 8) > 0)
2841  R = 255;
2842  else if (R < 0)
2843  R = 0;
2844 
2845  G = Y2 + UV;
2846  if ((G >> 8) > 0)
2847  G = 255;
2848  else if (G < 0)
2849  G = 0;
2850 
2851  B = Y2 + U5;
2852  if ((B >> 8) > 0)
2853  B = 255;
2854  else if (B < 0)
2855  B = 0;
2856 
2857  *rgb++ = (unsigned char)R;
2858  *rgb++ = (unsigned char)G;
2859  *rgb++ = (unsigned char)B;
2860 
2861  //---
2862  R = Y3 + V2;
2863  if ((R >> 8) > 0)
2864  R = 255;
2865  else if (R < 0)
2866  R = 0;
2867 
2868  G = Y3 + UV;
2869  if ((G >> 8) > 0)
2870  G = 255;
2871  else if (G < 0)
2872  G = 0;
2873 
2874  B = Y3 + U5;
2875  if ((B >> 8) > 0)
2876  B = 255;
2877  else if (B < 0)
2878  B = 0;
2879 
2880  *rgb++ = (unsigned char)R;
2881  *rgb++ = (unsigned char)G;
2882  *rgb = (unsigned char)B;
2883  rgb = rgb + 3 * width - 11;
2884 
2885  R = Y4 + V2;
2886  if ((R >> 8) > 0)
2887  R = 255;
2888  else if (R < 0)
2889  R = 0;
2890 
2891  G = Y4 + UV;
2892  if ((G >> 8) > 0)
2893  G = 255;
2894  else if (G < 0)
2895  G = 0;
2896 
2897  B = Y4 + U5;
2898  if ((B >> 8) > 0)
2899  B = 255;
2900  else if (B < 0)
2901  B = 0;
2902 
2903  *rgb++ = (unsigned char)R;
2904  *rgb++ = (unsigned char)G;
2905  *rgb++ = (unsigned char)B;
2906 
2907  //---
2908  R = Y5 + V2;
2909  if ((R >> 8) > 0)
2910  R = 255;
2911  else if (R < 0)
2912  R = 0;
2913 
2914  G = Y5 + UV;
2915  if ((G >> 8) > 0)
2916  G = 255;
2917  else if (G < 0)
2918  G = 0;
2919 
2920  B = Y5 + U5;
2921  if ((B >> 8) > 0)
2922  B = 255;
2923  else if (B < 0)
2924  B = 0;
2925 
2926  *rgb++ = (unsigned char)R;
2927  *rgb++ = (unsigned char)G;
2928  *rgb++ = (unsigned char)B;
2929 
2930  //---
2931  R = Y6 + V2;
2932  if ((R >> 8) > 0)
2933  R = 255;
2934  else if (R < 0)
2935  R = 0;
2936 
2937  G = Y6 + UV;
2938  if ((G >> 8) > 0)
2939  G = 255;
2940  else if (G < 0)
2941  G = 0;
2942 
2943  B = Y6 + U5;
2944  if ((B >> 8) > 0)
2945  B = 255;
2946  else if (B < 0)
2947  B = 0;
2948 
2949  *rgb++ = (unsigned char)R;
2950  *rgb++ = (unsigned char)G;
2951  *rgb++ = (unsigned char)B;
2952 
2953  //---
2954  R = Y7 + V2;
2955  if ((R >> 8) > 0)
2956  R = 255;
2957  else if (R < 0)
2958  R = 0;
2959 
2960  G = Y7 + UV;
2961  if ((G >> 8) > 0)
2962  G = 255;
2963  else if (G < 0)
2964  G = 0;
2965 
2966  B = Y7 + U5;
2967  if ((B >> 8) > 0)
2968  B = 255;
2969  else if (B < 0)
2970  B = 0;
2971 
2972  *rgb++ = (unsigned char)R;
2973  *rgb++ = (unsigned char)G;
2974  *rgb = (unsigned char)B;
2975  rgb = rgb + 3 * width - 11;
2976 
2977  R = Y8 + V2;
2978  if ((R >> 8) > 0)
2979  R = 255;
2980  else if (R < 0)
2981  R = 0;
2982 
2983  G = Y8 + UV;
2984  if ((G >> 8) > 0)
2985  G = 255;
2986  else if (G < 0)
2987  G = 0;
2988 
2989  B = Y8 + U5;
2990  if ((B >> 8) > 0)
2991  B = 255;
2992  else if (B < 0)
2993  B = 0;
2994 
2995  *rgb++ = (unsigned char)R;
2996  *rgb++ = (unsigned char)G;
2997  *rgb++ = (unsigned char)B;
2998 
2999  //---
3000  R = Y9 + V2;
3001  if ((R >> 8) > 0)
3002  R = 255;
3003  else if (R < 0)
3004  R = 0;
3005 
3006  G = Y9 + UV;
3007  if ((G >> 8) > 0)
3008  G = 255;
3009  else if (G < 0)
3010  G = 0;
3011 
3012  B = Y9 + U5;
3013  if ((B >> 8) > 0)
3014  B = 255;
3015  else if (B < 0)
3016  B = 0;
3017 
3018  *rgb++ = (unsigned char)R;
3019  *rgb++ = (unsigned char)G;
3020  *rgb++ = (unsigned char)B;
3021 
3022  //---
3023  R = Y10 + V2;
3024  if ((R >> 8) > 0)
3025  R = 255;
3026  else if (R < 0)
3027  R = 0;
3028 
3029  G = Y10 + UV;
3030  if ((G >> 8) > 0)
3031  G = 255;
3032  else if (G < 0)
3033  G = 0;
3034 
3035  B = Y10 + U5;
3036  if ((B >> 8) > 0)
3037  B = 255;
3038  else if (B < 0)
3039  B = 0;
3040 
3041  *rgb++ = (unsigned char)R;
3042  *rgb++ = (unsigned char)G;
3043  *rgb++ = (unsigned char)B;
3044 
3045  //---
3046  R = Y11 + V2;
3047  if ((R >> 8) > 0)
3048  R = 255;
3049  else if (R < 0)
3050  R = 0;
3051 
3052  G = Y11 + UV;
3053  if ((G >> 8) > 0)
3054  G = 255;
3055  else if (G < 0)
3056  G = 0;
3057 
3058  B = Y11 + U5;
3059  if ((B >> 8) > 0)
3060  B = 255;
3061  else if (B < 0)
3062  B = 0;
3063 
3064  *rgb++ = (unsigned char)R;
3065  *rgb++ = (unsigned char)G;
3066  *rgb = (unsigned char)B;
3067  rgb = rgb + 3 * width - 11;
3068 
3069  R = Y12 + V2;
3070  if ((R >> 8) > 0)
3071  R = 255;
3072  else if (R < 0)
3073  R = 0;
3074 
3075  G = Y12 + UV;
3076  if ((G >> 8) > 0)
3077  G = 255;
3078  else if (G < 0)
3079  G = 0;
3080 
3081  B = Y12 + U5;
3082  if ((B >> 8) > 0)
3083  B = 255;
3084  else if (B < 0)
3085  B = 0;
3086 
3087  *rgb++ = (unsigned char)R;
3088  *rgb++ = (unsigned char)G;
3089  *rgb++ = (unsigned char)B;
3090 
3091  //---
3092  R = Y13 + V2;
3093  if ((R >> 8) > 0)
3094  R = 255;
3095  else if (R < 0)
3096  R = 0;
3097 
3098  G = Y13 + UV;
3099  if ((G >> 8) > 0)
3100  G = 255;
3101  else if (G < 0)
3102  G = 0;
3103 
3104  B = Y13 + U5;
3105  if ((B >> 8) > 0)
3106  B = 255;
3107  else if (B < 0)
3108  B = 0;
3109 
3110  *rgb++ = (unsigned char)R;
3111  *rgb++ = (unsigned char)G;
3112  *rgb++ = (unsigned char)B;
3113 
3114  //---
3115  R = Y14 + V2;
3116  if ((R >> 8) > 0)
3117  R = 255;
3118  else if (R < 0)
3119  R = 0;
3120 
3121  G = Y14 + UV;
3122  if ((G >> 8) > 0)
3123  G = 255;
3124  else if (G < 0)
3125  G = 0;
3126 
3127  B = Y14 + U5;
3128  if ((B >> 8) > 0)
3129  B = 255;
3130  else if (B < 0)
3131  B = 0;
3132 
3133  *rgb++ = (unsigned char)R;
3134  *rgb++ = (unsigned char)G;
3135  *rgb++ = (unsigned char)B;
3136 
3137  //---
3138  R = Y15 + V2;
3139  if ((R >> 8) > 0)
3140  R = 255;
3141  else if (R < 0)
3142  R = 0;
3143 
3144  G = Y15 + UV;
3145  if ((G >> 8) > 0)
3146  G = 255;
3147  else if (G < 0)
3148  G = 0;
3149 
3150  B = Y15 + U5;
3151  if ((B >> 8) > 0)
3152  B = 255;
3153  else if (B < 0)
3154  B = 0;
3155 
3156  *rgb++ = (unsigned char)R;
3157  *rgb++ = (unsigned char)G;
3158  *rgb++ = (unsigned char)B;
3159  rgb = rgb - 9 * width + 1;
3160  }
3161  yuv += 3 * width;
3162  rgb += 9 * width;
3163  }
3164 }
3165 
3175 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
3176 {
3177  RGBToRGBa(rgb, rgba, size, 1, false);
3178 }
3179 
3195 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int width, unsigned int height,
3196  bool flip)
3197 {
3198  if (!flip) {
3199  SimdBgrToBgra(rgb, width, height, width * 3, rgba, width * 4, vpRGBa::alpha_default);
3200  }
3201  else {
3202  // if we have to flip the image, we start from the end last scanline so the
3203  // step is negative
3204  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3205 
3206  // starting source address = last line if we need to flip the image
3207  unsigned char *src = (flip) ? (rgb + (width * height * 3) + lineStep) : rgb;
3208 
3209  unsigned int j = 0;
3210  unsigned int i = 0;
3211 
3212  for (i = 0; i < height; i++) {
3213  unsigned char *line = src;
3214  for (j = 0; j < width; j++) {
3215  *rgba++ = *(line++);
3216  *rgba++ = *(line++);
3217  *rgba++ = *(line++);
3218  *rgba++ = vpRGBa::alpha_default;
3219  }
3220  // go to the next line
3221  src += lineStep;
3222  }
3223  }
3224 }
3225 
3238 void vpImageConvert::RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
3239 {
3240  SimdBgraToBgr(rgba, size, 1, size * 4, rgb, size * 3);
3241 }
3242 
3255 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
3256 {
3257  RGBToGrey(rgb, grey, size, 1, false);
3258 }
3259 
3273 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height,
3274  bool flip)
3275 {
3276  if (!flip) {
3277  SimdRgbToGray(rgb, width, height, width * 3, grey, width);
3278  }
3279  else {
3280  // if we have to flip the image, we start from the end last scanline so
3281  // the step is negative
3282  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3283 
3284  // starting source address = last line if we need to flip the image
3285  unsigned char *src = (flip) ? rgb + (width * height * 3) + lineStep : rgb;
3286 
3287  unsigned int j = 0;
3288  unsigned int i = 0;
3289 
3290  unsigned r, g, b;
3291 
3292  for (i = 0; i < height; i++) {
3293  unsigned char *line = src;
3294  for (j = 0; j < width; j++) {
3295  r = *(line++);
3296  g = *(line++);
3297  b = *(line++);
3298  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3299  }
3300 
3301  // go to the next line
3302  src += lineStep;
3303  }
3304  }
3305 }
3306 
3322 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height,
3323  unsigned int
3324 #if defined _OPENMP
3325  nThreads
3326 #endif
3327 )
3328 {
3329 #if defined _OPENMP
3330  if (nThreads > 0) {
3331  omp_set_num_threads(static_cast<int>(nThreads));
3332  }
3333 #pragma omp parallel for
3334 #endif
3335  for (int i = 0; i < static_cast<int>(height); i++) {
3336  SimdRgbaToGray(rgba + i * width * 4, width, 1, width * 4, grey + i * width, width);
3337  }
3338 }
3339 
3354 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
3355 {
3356  SimdRgbaToGray(rgba, size, 1, size * 4, grey, size);
3357 }
3358 
3370 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
3371 {
3372  SimdGrayToBgra(grey, width, height, width, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3373 }
3374 
3387 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
3388 {
3389  GreyToRGBa(grey, rgba, size, 1);
3390 }
3391 
3402 void vpImageConvert::GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
3403 {
3404  SimdGrayToBgr(grey, size, 1, size, rgb, size * 3);
3405 }
3406 
3422 void vpImageConvert::BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height,
3423  bool flip)
3424 {
3425  if (!flip) {
3426  SimdRgbToBgra(bgr, width, height, width * 3, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3427  }
3428  else {
3429  // if we have to flip the image, we start from the end last scanline so the
3430  // step is negative
3431  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3432 
3433  // starting source address = last line if we need to flip the image
3434  unsigned char *src = (flip) ? (bgr + (width * height * 3) + lineStep) : bgr;
3435 
3436  for (unsigned int i = 0; i < height; i++) {
3437  unsigned char *line = src;
3438  for (unsigned int j = 0; j < width; j++) {
3439  *rgba++ = *(line + 2);
3440  *rgba++ = *(line + 1);
3441  *rgba++ = *(line + 0);
3442  *rgba++ = vpRGBa::alpha_default;
3443 
3444  line += 3;
3445  }
3446  // go to the next line
3447  src += lineStep;
3448  }
3449  }
3450 }
3451 
3466 void vpImageConvert::BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height,
3467  bool flip)
3468 {
3469  if (!flip) {
3470  SimdBgraToRgba(bgra, width, height, width * 4, rgba, width * 4);
3471  }
3472  else {
3473  // if we have to flip the image, we start from the end last scanline so the
3474  // step is negative
3475  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3476 
3477  // starting source address = last line if we need to flip the image
3478  unsigned char *src = (flip) ? (bgra + (width * height * 4) + lineStep) : bgra;
3479 
3480  for (unsigned int i = 0; i < height; i++) {
3481  unsigned char *line = src;
3482  for (unsigned int j = 0; j < width; j++) {
3483  *rgba++ = *(line + 2);
3484  *rgba++ = *(line + 1);
3485  *rgba++ = *(line + 0);
3486  *rgba++ = *(line + 3);
3487 
3488  line += 4;
3489  }
3490  // go to the next line
3491  src += lineStep;
3492  }
3493  }
3494 }
3495 
3510 void vpImageConvert::BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height,
3511  bool flip,
3512  unsigned int
3513 #if defined _OPENMP
3514  nThreads
3515 #endif
3516 )
3517 {
3518  if (!flip) {
3519 #if defined _OPENMP
3520  if (nThreads > 0) {
3521  omp_set_num_threads(static_cast<int>(nThreads));
3522  }
3523 #pragma omp parallel for
3524 #endif
3525  for (int i = 0; i < static_cast<int>(height); i++) {
3526  SimdBgrToGray(bgr + i * width * 3, width, 1, width * 3, grey + i * width, width);
3527  }
3528  }
3529  else {
3530  // if we have to flip the image, we start from the end last scanline so
3531  // the step is negative
3532  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3533 
3534  // starting source address = last line if we need to flip the image
3535  unsigned char *src = (flip) ? bgr + (width * height * 3) + lineStep : bgr;
3536 
3537  for (unsigned int i = 0; i < height; i++) {
3538  unsigned char *line = src;
3539  for (unsigned int j = 0; j < width; j++) {
3540  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3541  line += 3;
3542  }
3543 
3544  // go to the next line
3545  src += lineStep;
3546  }
3547  }
3548 }
3549 
3564 void vpImageConvert::BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height,
3565  bool flip,
3566  unsigned int
3567 #if defined _OPENMP
3568  nThreads
3569 #endif
3570 )
3571 {
3572  if (!flip) {
3573 #if defined _OPENMP
3574  if (nThreads > 0) {
3575  omp_set_num_threads(static_cast<int>(nThreads));
3576  }
3577 #pragma omp parallel for
3578 #endif
3579  for (int i = 0; i < static_cast<int>(height); i++) {
3580  SimdBgraToGray(bgra + i * width * 4, width, 1, width * 4, grey + i * width, width);
3581  }
3582  }
3583  else {
3584  // if we have to flip the image, we start from the end last scanline so
3585  // the step is negative
3586  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3587 
3588  // starting source address = last line if we need to flip the image
3589  unsigned char *src = (flip) ? bgra + (width * height * 4) + lineStep : bgra;
3590 
3591  for (unsigned int i = 0; i < height; i++) {
3592  unsigned char *line = src;
3593  for (unsigned int j = 0; j < width; j++) {
3594  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3595  line += 4;
3596  }
3597 
3598  // go to the next line
3599  src += lineStep;
3600  }
3601  }
3602 }
3603 
3607 void vpImageConvert::computeYCbCrLUT()
3608 {
3609  if (YCbCrLUTcomputed == false) {
3610  int index = 256;
3611 
3612  while (index--) {
3613 
3614  int aux = index - 128;
3615  vpImageConvert::vpCrr[index] = (int)(364.6610 * aux) >> 8;
3616  vpImageConvert::vpCgb[index] = (int)(-89.8779 * aux) >> 8;
3617  vpImageConvert::vpCgr[index] = (int)(-185.8154 * aux) >> 8;
3618  vpImageConvert::vpCbb[index] = (int)(460.5724 * aux) >> 8;
3619  }
3620 
3621  YCbCrLUTcomputed = true;
3622  }
3623 }
3624 
3646 void vpImageConvert::YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
3647 {
3648  unsigned char *cbv;
3649  unsigned char *crv;
3650  unsigned char *pt_ycbcr = ycbcr;
3651  unsigned char *pt_rgb = rgb;
3652  cbv = pt_ycbcr + 1;
3653  crv = pt_ycbcr + 3;
3654 
3655  vpImageConvert::computeYCbCrLUT();
3656 
3657  int col = 0;
3658 
3659  while (size--) {
3660  int val_r, val_g, val_b;
3661  if (!(col++ % 2)) {
3662  cbv = pt_ycbcr + 1;
3663  crv = pt_ycbcr + 3;
3664  }
3665 
3666  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3667  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3668  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3669 
3670  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3671 
3672  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3673  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3674  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3675 
3676  pt_ycbcr += 2;
3677  }
3678 }
3679 
3705 void vpImageConvert::YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgba, unsigned int size)
3706 {
3707  unsigned char *cbv;
3708  unsigned char *crv;
3709  unsigned char *pt_ycbcr = ycbcr;
3710  unsigned char *pt_rgba = rgba;
3711  cbv = pt_ycbcr + 1;
3712  crv = pt_ycbcr + 3;
3713 
3714  vpImageConvert::computeYCbCrLUT();
3715 
3716  int col = 0;
3717 
3718  while (size--) {
3719  int val_r, val_g, val_b;
3720  if (!(col++ % 2)) {
3721  cbv = pt_ycbcr + 1;
3722  crv = pt_ycbcr + 3;
3723  }
3724 
3725  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3726  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3727  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3728 
3729  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3730 
3731  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3732  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3733  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3734  *pt_rgba++ = vpRGBa::alpha_default;
3735 
3736  pt_ycbcr += 2;
3737  }
3738 }
3739 
3759 void vpImageConvert::YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
3760 {
3761  unsigned int i = 0, j = 0;
3762 
3763  while (j < size * 2) {
3764  grey[i++] = ycbcr[j];
3765  grey[i++] = ycbcr[j + 2];
3766  j += 4;
3767  }
3768 }
3769 
3791 void vpImageConvert::YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
3792 {
3793  unsigned char *cbv;
3794  unsigned char *crv;
3795  unsigned char *pt_ycbcr = ycrcb;
3796  unsigned char *pt_rgb = rgb;
3797  crv = pt_ycbcr + 1;
3798  cbv = pt_ycbcr + 3;
3799 
3800  vpImageConvert::computeYCbCrLUT();
3801 
3802  int col = 0;
3803 
3804  while (size--) {
3805  int val_r, val_g, val_b;
3806  if (!(col++ % 2)) {
3807  crv = pt_ycbcr + 1;
3808  cbv = pt_ycbcr + 3;
3809  }
3810 
3811  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3812  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3813  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3814 
3815  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3816 
3817  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3818  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3819  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3820 
3821  pt_ycbcr += 2;
3822  }
3823 }
3824 
3849 void vpImageConvert::YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgba, unsigned int size)
3850 {
3851  unsigned char *cbv;
3852  unsigned char *crv;
3853  unsigned char *pt_ycbcr = ycrcb;
3854  unsigned char *pt_rgba = rgba;
3855  crv = pt_ycbcr + 1;
3856  cbv = pt_ycbcr + 3;
3857 
3858  vpImageConvert::computeYCbCrLUT();
3859 
3860  int col = 0;
3861 
3862  while (size--) {
3863  int val_r, val_g, val_b;
3864  if (!(col++ % 2)) {
3865  crv = pt_ycbcr + 1;
3866  cbv = pt_ycbcr + 3;
3867  }
3868 
3869  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3870  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3871  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3872 
3873  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3874 
3875  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3876  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3877  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3878  *pt_rgba++ = vpRGBa::alpha_default;
3879 
3880  pt_ycbcr += 2;
3881  }
3882 }
3883 
3924 {
3925  if (src.getSize() > 0) {
3926  if (pR) {
3927  pR->resize(src.getHeight(), src.getWidth());
3928  }
3929  if (pG) {
3930  pG->resize(src.getHeight(), src.getWidth());
3931  }
3932  if (pB) {
3933  pB->resize(src.getHeight(), src.getWidth());
3934  }
3935  if (pa) {
3936  pa->resize(src.getHeight(), src.getWidth());
3937  }
3938 
3939  unsigned char *ptrR = pR ? pR->bitmap : new unsigned char[src.getSize()];
3940  unsigned char *ptrG = pG ? pG->bitmap : new unsigned char[src.getSize()];
3941  unsigned char *ptrB = pB ? pB->bitmap : new unsigned char[src.getSize()];
3942  unsigned char *ptrA = pa ? pa->bitmap : new unsigned char[src.getSize()];
3943 
3944  SimdDeinterleaveBgra(reinterpret_cast<unsigned char *>(src.bitmap), src.getWidth() * sizeof(vpRGBa), src.getWidth(),
3945  src.getHeight(), ptrR, src.getWidth(), ptrG, src.getWidth(), ptrB, src.getWidth(), ptrA,
3946  src.getWidth());
3947 
3948  if (!pR) {
3949  delete[] ptrR;
3950  }
3951  if (!pG) {
3952  delete[] ptrG;
3953  }
3954  if (!pB) {
3955  delete[] ptrB;
3956  }
3957  if (!pa) {
3958  delete[] ptrA;
3959  }
3960  }
3961 }
3962 
3975 {
3976  // Check if the input channels have all the same dimensions
3977  std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
3978  if (R != NULL) {
3979  mapOfWidths[R->getWidth()]++;
3980  mapOfHeights[R->getHeight()]++;
3981  }
3982 
3983  if (G != NULL) {
3984  mapOfWidths[G->getWidth()]++;
3985  mapOfHeights[G->getHeight()]++;
3986  }
3987 
3988  if (B != NULL) {
3989  mapOfWidths[B->getWidth()]++;
3990  mapOfHeights[B->getHeight()]++;
3991  }
3992 
3993  if (a != NULL) {
3994  mapOfWidths[a->getWidth()]++;
3995  mapOfHeights[a->getHeight()]++;
3996  }
3997 
3998  if (mapOfWidths.size() == 1 && mapOfHeights.size() == 1) {
3999  unsigned int width = mapOfWidths.begin()->first;
4000  unsigned int height = mapOfHeights.begin()->first;
4001 
4002  RGBa.resize(height, width);
4003 
4004  if (R != NULL && G != NULL && B != NULL && a != NULL) {
4005  SimdInterleaveBgra(R->bitmap, width, G->bitmap, width, B->bitmap, width, a->bitmap, width, width, height,
4006  reinterpret_cast<uint8_t *>(RGBa.bitmap), width * sizeof(vpRGBa));
4007  }
4008  else {
4009  unsigned int size = width * height;
4010  for (unsigned int i = 0; i < size; i++) {
4011  if (R != NULL) {
4012  RGBa.bitmap[i].R = R->bitmap[i];
4013  }
4014 
4015  if (G != NULL) {
4016  RGBa.bitmap[i].G = G->bitmap[i];
4017  }
4018 
4019  if (B != NULL) {
4020  RGBa.bitmap[i].B = B->bitmap[i];
4021  }
4022 
4023  if (a != NULL) {
4024  RGBa.bitmap[i].A = a->bitmap[i];
4025  }
4026  }
4027  }
4028  }
4029  else {
4030  throw vpException(vpException::dimensionError, "Mismatched dimensions!");
4031  }
4032 }
4033 
4044 void vpImageConvert::MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
4045 {
4046  int i = (((int)size) << 1) - 1;
4047  int j = (int)size - 1;
4048 
4049  while (i >= 0) {
4050  int y = grey16[i--];
4051  grey[j--] = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4052  }
4053 }
4054 
4066 void vpImageConvert::MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
4067 {
4068  int i = (((int)size) << 1) - 1;
4069  int j = (int)(size * 4 - 1);
4070 
4071  while (i >= 0) {
4072  int y = grey16[i--];
4073  unsigned char v = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4074  rgba[j--] = vpRGBa::alpha_default;
4075  rgba[j--] = v;
4076  rgba[j--] = v;
4077  rgba[j--] = v;
4078  }
4079 }
4080 
4091 void vpImageConvert::HSV2RGB(const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
4092  unsigned int size, unsigned int step)
4093 {
4094  for (unsigned int i = 0; i < size; i++) {
4095  double hue = hue_[i], saturation = saturation_[i], value = value_[i];
4096 
4097  if (vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
4098  hue = value;
4099  saturation = value;
4100  }
4101  else {
4102  double h = hue * 6.0;
4103  double s = saturation;
4104  double v = value;
4105 
4106  if (vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
4107  h = 0.0;
4108  }
4109 
4110  double f = h - (int)h;
4111  double p = v * (1.0 - s);
4112  double q = v * (1.0 - s * f);
4113  double t = v * (1.0 - s * (1.0 - f));
4114 
4115  switch ((int)h) {
4116  case 0:
4117  hue = v;
4118  saturation = t;
4119  value = p;
4120  break;
4121 
4122  case 1:
4123  hue = q;
4124  saturation = v;
4125  value = p;
4126  break;
4127 
4128  case 2:
4129  hue = p;
4130  saturation = v;
4131  value = t;
4132  break;
4133 
4134  case 3:
4135  hue = p;
4136  saturation = q;
4137  value = v;
4138  break;
4139 
4140  case 4:
4141  hue = t;
4142  saturation = p;
4143  value = v;
4144  break;
4145 
4146  default: // case 5:
4147  hue = v;
4148  saturation = p;
4149  value = q;
4150  break;
4151  }
4152  }
4153 
4154  rgb[i * step] = (unsigned char)vpMath::round(hue * 255.0);
4155  rgb[i * step + 1] = (unsigned char)vpMath::round(saturation * 255.0);
4156  rgb[i * step + 2] = (unsigned char)vpMath::round(value * 255.0);
4157  if (step == 4) // alpha
4158  rgb[i * step + 3] = vpRGBa::alpha_default;
4159  }
4160 }
4161 
4172 void vpImageConvert::RGB2HSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4173  unsigned int size, unsigned int step)
4174 {
4175  for (unsigned int i = 0; i < size; i++) {
4176  double red, green, blue;
4177  double h, s, v;
4178  double min, max;
4179 
4180  red = rgb[i * step] / 255.0;
4181  green = rgb[i * step + 1] / 255.0;
4182  blue = rgb[i * step + 2] / 255.0;
4183 
4184  if (red > green) {
4185  max = ((std::max))(red, blue);
4186  min = ((std::min))(green, blue);
4187  }
4188  else {
4189  max = ((std::max))(green, blue);
4190  min = ((std::min))(red, blue);
4191  }
4192 
4193  v = max;
4194 
4195  if (!vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
4196  s = (max - min) / max;
4197  }
4198  else {
4199  s = 0.0;
4200  }
4201 
4202  if (vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
4203  h = 0.0;
4204  }
4205  else {
4206  double delta = max - min;
4207  if (vpMath::equal(delta, 0.0, std::numeric_limits<double>::epsilon())) {
4208  delta = 1.0;
4209  }
4210 
4211  if (vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
4212  h = (green - blue) / delta;
4213  }
4214  else if (vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
4215  h = 2 + (blue - red) / delta;
4216  }
4217  else {
4218  h = 4 + (red - green) / delta;
4219  }
4220 
4221  h /= 6.0;
4222  if (h < 0.0) {
4223  h += 1.0;
4224  }
4225  else if (h > 1.0) {
4226  h -= 1.0;
4227  }
4228  }
4229 
4230  hue[i] = h;
4231  saturation[i] = s;
4232  value[i] = v;
4233  }
4234 }
4235 
4248 void vpImageConvert::HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba,
4249  unsigned int size)
4250 {
4251  vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
4252 }
4253 
4266 void vpImageConvert::HSVToRGBa(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4267  unsigned char *rgba, unsigned int size)
4268 {
4269  for (unsigned int i = 0; i < size; i++) {
4270  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4271 
4272  vpImageConvert::HSVToRGBa(&h, &s, &v, (rgba + i * 4), 1);
4273  }
4274 }
4275 
4288 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value,
4289  unsigned int size)
4290 {
4291  vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
4292 }
4293 
4305 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
4306  unsigned char *value, unsigned int size)
4307 {
4308  for (unsigned int i = 0; i < size; i++) {
4309  double h, s, v;
4310  vpImageConvert::RGBaToHSV((rgba + i * 4), &h, &s, &v, 1);
4311 
4312  hue[i] = (unsigned char)(255.0 * h);
4313  saturation[i] = (unsigned char)(255.0 * s);
4314  value[i] = (unsigned char)(255.0 * v);
4315  }
4316 }
4317 
4328 void vpImageConvert::HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb,
4329  unsigned int size)
4330 {
4331  vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
4332 }
4333 
4344 void vpImageConvert::HSVToRGB(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4345  unsigned char *rgb, unsigned int size)
4346 {
4347  for (unsigned int i = 0; i < size; i++) {
4348  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4349 
4350  vpImageConvert::HSVToRGB(&h, &s, &v, (rgb + i * 3), 1);
4351  }
4352 }
4353 
4365 void vpImageConvert::RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4366  unsigned int size)
4367 {
4368  vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
4369 }
4370 
4381 void vpImageConvert::RGBToHSV(const unsigned char *rgb, unsigned char *hue, unsigned char *saturation,
4382  unsigned char *value, unsigned int size)
4383 {
4384  for (unsigned int i = 0; i < size; i++) {
4385  double h, s, v;
4386 
4387  vpImageConvert::RGBToHSV((rgb + i * 3), &h, &s, &v, 1);
4388 
4389  hue[i] = (unsigned char)(255.0 * h);
4390  saturation[i] = (unsigned char)(255.0 * s);
4391  value[i] = (unsigned char)(255.0 * v);
4392  }
4393 }
4394 
4395 // Bilinear
4396 
4409 void vpImageConvert::demosaicBGGRToRGBaBilinear(const uint8_t *bggr, uint8_t *rgba, unsigned int width,
4410  unsigned int height, unsigned int nThreads)
4411 {
4412  demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
4413 }
4414 
4427 void vpImageConvert::demosaicBGGRToRGBaBilinear(const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4428  unsigned int height, unsigned int nThreads)
4429 {
4430  demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
4431 }
4432 
4445 void vpImageConvert::demosaicGBRGToRGBaBilinear(const uint8_t *gbrg, uint8_t *rgba, unsigned int width,
4446  unsigned int height, unsigned int nThreads)
4447 {
4448  demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
4449 }
4450 
4463 void vpImageConvert::demosaicGBRGToRGBaBilinear(const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4464  unsigned int height, unsigned int nThreads)
4465 {
4466  demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
4467 }
4468 
4481 void vpImageConvert::demosaicGRBGToRGBaBilinear(const uint8_t *grbg, uint8_t *rgba, unsigned int width,
4482  unsigned int height, unsigned int nThreads)
4483 {
4484  demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
4485 }
4486 
4499 void vpImageConvert::demosaicGRBGToRGBaBilinear(const uint16_t *grbg, uint16_t *rgba, unsigned int width,
4500  unsigned int height, unsigned int nThreads)
4501 {
4502  demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
4503 }
4504 
4517 void vpImageConvert::demosaicRGGBToRGBaBilinear(const uint8_t *rggb, uint8_t *rgba, unsigned int width,
4518  unsigned int height, unsigned int nThreads)
4519 {
4520  demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
4521 }
4522 
4535 void vpImageConvert::demosaicRGGBToRGBaBilinear(const uint16_t *rggb, uint16_t *rgba, unsigned int width,
4536  unsigned int height, unsigned int nThreads)
4537 {
4538  demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
4539 }
4540 
4541 // Malvar
4542 
4555 void vpImageConvert::demosaicBGGRToRGBaMalvar(const uint8_t *bggr, uint8_t *rgba, unsigned int width,
4556  unsigned int height, unsigned int nThreads)
4557 {
4558  demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
4559 }
4560 
4573 void vpImageConvert::demosaicBGGRToRGBaMalvar(const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4574  unsigned int height, unsigned int nThreads)
4575 {
4576  demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
4577 }
4578 
4591 void vpImageConvert::demosaicGBRGToRGBaMalvar(const uint8_t *gbrg, uint8_t *rgba, unsigned int width,
4592  unsigned int height, unsigned int nThreads)
4593 {
4594  demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
4595 }
4596 
4609 void vpImageConvert::demosaicGBRGToRGBaMalvar(const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4610  unsigned int height, unsigned int nThreads)
4611 {
4612  demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
4613 }
4614 
4627 void vpImageConvert::demosaicGRBGToRGBaMalvar(const uint8_t *grbg, uint8_t *rgba, unsigned int width,
4628  unsigned int height, unsigned int nThreads)
4629 {
4630  demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
4631 }
4632 
4645 void vpImageConvert::demosaicGRBGToRGBaMalvar(const uint16_t *grbg, uint16_t *rgba, unsigned int width,
4646  unsigned int height, unsigned int nThreads)
4647 {
4648  demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
4649 }
4650 
4663 void vpImageConvert::demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width,
4664  unsigned int height, unsigned int nThreads)
4665 {
4666  demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
4667 }
4668 
4681 void vpImageConvert::demosaicRGGBToRGBaMalvar(const uint16_t *rggb, uint16_t *rgba, unsigned int width,
4682  unsigned int height, unsigned int nThreads)
4683 {
4684  demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
4685 }
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:85
@ dimensionError
Bad dimension.
Definition: vpException.h:83
@ fatalError
Fatal error.
Definition: vpException.h:84
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 MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, unsigned int size)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
static void demosaicBGGRToRGBaBilinear(const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void demosaicGRBGToRGBaBilinear(const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
static void RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value, unsigned int size)
static void demosaicGRBGToRGBaMalvar(const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
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 demosaicGBRGToRGBaMalvar(const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
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 demosaicBGGRToRGBaMalvar(const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
static void demosaicGBRGToRGBaBilinear(const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
static void YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
static void YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, unsigned int size)
static void demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
static void YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
static void YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
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 BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void demosaicRGGBToRGBaBilinear(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, 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 HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb, unsigned int size)
static void YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
unsigned int getWidth() const
Definition: vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:795
unsigned int getSize() const
Definition: vpImage.h:223
unsigned int getCols() const
Definition: vpImage.h:175
Type * bitmap
points toward the bitmap
Definition: vpImage.h:139
unsigned int getHeight() const
Definition: vpImage.h:184
unsigned int getRows() const
Definition: vpImage.h:214
void getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal=true) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:1054
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:369
static int round(double x)
Definition: vpMath.h:323
Definition: vpRGBa.h:61
unsigned char B
Blue component.
Definition: vpRGBa.h:140
unsigned char R
Red component.
Definition: vpRGBa.h:138
unsigned char G
Green component.
Definition: vpRGBa.h:139
@ alpha_default
Definition: vpRGBa.h:63
unsigned char A
Additionnal component.
Definition: vpRGBa.h:141
Definition: vpRGBf.h:57
float B
Blue component.
Definition: vpRGBf.h:127
float G
Green component.
Definition: vpRGBf.h:126
float R
Red component.
Definition: vpRGBf.h:125
#define vpDEBUG_TRACE
Definition: vpDebug.h:482