Visual Servoing Platform  version 3.5.1 under development (2022-10-02)
vpImageConvert.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2021 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 http://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  * Authors:
35  * Eric Marchand
36  * Fabien Spindler
37  * Anthony Saunier
38  *
39  *****************************************************************************/
40 
46 #include <map>
47 #include <sstream>
48 
49 #if defined _OPENMP
50 #include <omp.h>
51 #endif
52 
53 // image
54 #include "private/vpBayerConversion.h"
55 #include "private/vpImageConvert_impl.h"
56 #include <Simd/SimdLib.hpp>
57 #include <visp3/core/vpImageConvert.h>
58 
59 bool vpImageConvert::YCbCrLUTcomputed = false;
60 int vpImageConvert::vpCrr[256];
61 int vpImageConvert::vpCgb[256];
62 int vpImageConvert::vpCgr[256];
63 int vpImageConvert::vpCbb[256];
64 
74 {
75  dest.resize(src.getHeight(), src.getWidth());
76 
77  GreyToRGBa(src.bitmap, reinterpret_cast<unsigned char *>(dest.bitmap), src.getWidth(), src.getHeight());
78 }
79 
89 void vpImageConvert::convert(const vpImage<vpRGBa> &src, vpImage<unsigned char> &dest, unsigned int nThreads)
90 {
91  dest.resize(src.getHeight(), src.getWidth());
92 
93  RGBaToGrey(reinterpret_cast<unsigned char *>(src.bitmap), dest.bitmap, src.getWidth(), src.getHeight(), nThreads);
94 }
95 
103 {
104  dest.resize(src.getHeight(), src.getWidth());
105  unsigned int max_xy = src.getWidth() * src.getHeight();
106  float min, max;
107 
108  src.getMinMaxValue(min, max);
109 
110  for (unsigned int i = 0; i < max_xy; i++) {
111  float val = 255.f * (src.bitmap[i] - min) / (max - min);
112  if (val < 0)
113  dest.bitmap[i] = 0;
114  else if (val > 255)
115  dest.bitmap[i] = 255;
116  else
117  dest.bitmap[i] = (unsigned char)val;
118  }
119 }
120 
127 {
128  dest.resize(src.getHeight(), src.getWidth());
129  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
130  dest.bitmap[i] = (float)src.bitmap[i];
131 }
132 
140 {
141  dest.resize(src.getHeight(), src.getWidth());
142  unsigned int max_xy = src.getWidth() * src.getHeight();
143  double min, max;
144 
145  src.getMinMaxValue(min, max);
146 
147  for (unsigned int i = 0; i < max_xy; i++) {
148  double val = 255. * (src.bitmap[i] - min) / (max - min);
149  if (val < 0)
150  dest.bitmap[i] = 0;
151  else if (val > 255)
152  dest.bitmap[i] = 255;
153  else
154  dest.bitmap[i] = (unsigned char)val;
155  }
156 }
157 
164 void vpImageConvert::convert(const vpImage<uint16_t> &src, vpImage<unsigned char> &dest, unsigned char bitshift)
165 {
166  dest.resize(src.getHeight(), src.getWidth());
167 
168  for (unsigned int i = 0; i < src.getSize(); i++)
169  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] >> bitshift);
170 }
171 
178 void vpImageConvert::convert(const vpImage<unsigned char> &src, vpImage<uint16_t> &dest, unsigned char bitshift)
179 {
180  dest.resize(src.getHeight(), src.getWidth());
181 
182  for (unsigned int i = 0; i < src.getSize(); i++)
183  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] << bitshift);
184 }
185 
192 {
193  dest.resize(src.getHeight(), src.getWidth());
194  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
195  dest.bitmap[i] = (double)src.bitmap[i];
196 }
197 
206 {
207  vp_createDepthHistogram(src_depth, dest_rgba);
208 }
209 
217 {
218  vp_createDepthHistogram(src_depth, dest_depth);
219 }
220 
229 {
230  vp_createDepthHistogram(src_depth, dest_rgba);
231 }
232 
240 {
241  vp_createDepthHistogram(src_depth, dest_depth);
242 }
243 
244 #ifdef VISP_HAVE_OPENCV
245 // Deprecated: will be removed with OpenCV transcient from C to C++ api
291 void vpImageConvert::convert(const IplImage *src, vpImage<vpRGBa> &dest, bool flip)
292 {
293  int nChannel = src->nChannels;
294  int depth = src->depth;
295  int height = src->height;
296  int width = src->width;
297  int widthStep = src->widthStep;
298  int lineStep = (flip) ? 1 : 0;
299 
300  if (nChannel == 3 && depth == 8) {
301  dest.resize((unsigned int)height, (unsigned int)width);
302 
303  // starting source address
304  unsigned char *input = (unsigned char *)src->imageData;
305  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
306 
307  for (int i = 0; i < height; i++) {
308  unsigned char *line = input;
309  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
310  for (int j = 0; j < width; j++) {
311  *(output++) = *(line + 2);
312  *(output++) = *(line + 1);
313  *(output++) = *(line);
314  *(output++) = vpRGBa::alpha_default;
315 
316  line += 3;
317  }
318  // go to the next line
319  input += widthStep;
320  }
321  } else if (nChannel == 1 && depth == 8) {
322  dest.resize((unsigned int)height, (unsigned int)width);
323  // starting source address
324  unsigned char *input = (unsigned char *)src->imageData;
325  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
326 
327  for (int i = 0; i < height; i++) {
328  unsigned char *line = input;
329  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
330  for (int j = 0; j < width; j++) {
331  *output++ = *(line);
332  *output++ = *(line);
333  *output++ = *(line);
334  *output++ = vpRGBa::alpha_default; // alpha
335 
336  line++;
337  }
338  // go to the next line
339  input += widthStep;
340  }
341  }
342 }
343 
386 void vpImageConvert::convert(const IplImage *src, vpImage<unsigned char> &dest, bool flip)
387 {
388  int nChannel = src->nChannels;
389  int depth = src->depth;
390  int height = src->height;
391  int width = src->width;
392  int widthStep = src->widthStep;
393  int lineStep = (flip) ? 1 : 0;
394 
395  if (flip == false) {
396  if (widthStep == width) {
397  if (nChannel == 1 && depth == 8) {
398  dest.resize((unsigned int)height, (unsigned int)width);
399  memcpy(dest.bitmap, src->imageData, (size_t)(height * width));
400  }
401  if (nChannel == 3 && depth == 8) {
402  dest.resize((unsigned int)height, (unsigned int)width);
403  BGRToGrey((unsigned char *)src->imageData, dest.bitmap, (unsigned int)width, (unsigned int)height, false);
404  }
405  } else {
406  if (nChannel == 1 && depth == 8) {
407  dest.resize((unsigned int)height, (unsigned int)width);
408  for (int i = 0; i < height; i++) {
409  memcpy(dest.bitmap + i * width, src->imageData + i * widthStep, (size_t)width);
410  }
411  }
412  if (nChannel == 3 && depth == 8) {
413  dest.resize((unsigned int)height, (unsigned int)width);
414  for (int i = 0; i < height; i++) {
415  BGRToGrey((unsigned char *)src->imageData + i * widthStep, dest.bitmap + i * width, (unsigned int)width, 1,
416  false);
417  }
418  }
419  }
420  } else {
421  if (nChannel == 1 && depth == 8) {
422  dest.resize((unsigned int)height, (unsigned int)width);
423  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
424  for (int i = 0; i < height; i++) {
425  memcpy(beginOutput + lineStep * (4 * width * (height - 1 - i)), src->imageData + i * widthStep, (size_t)width);
426  }
427  }
428  if (nChannel == 3 && depth == 8) {
429  dest.resize((unsigned int)height, (unsigned int)width);
430  // for (int i = 0 ; i < height ; i++){
431  BGRToGrey((unsigned char *)src->imageData /*+ i*widthStep*/, dest.bitmap /*+ i*width*/, (unsigned int)width,
432  (unsigned int)height /*1*/, true);
433  //}
434  }
435  }
436 }
437 
481 void vpImageConvert::convert(const vpImage<vpRGBa> &src, IplImage *&dest)
482 {
483  int height = (int)src.getHeight();
484  int width = (int)src.getWidth();
485  CvSize size = cvSize(width, height);
486  int depth = 8;
487  int channels = 3;
488  if (dest != NULL) {
489  if (dest->nChannels != channels || dest->depth != depth || dest->height != height || dest->width != width) {
490  if (dest->nChannels != 0)
491  cvReleaseImage(&dest);
492  dest = cvCreateImage(size, depth, channels);
493  }
494  } else
495  dest = cvCreateImage(size, depth, channels);
496 
497  // starting source address
498  unsigned char *input = (unsigned char *)src.bitmap; // rgba image
499  unsigned char *output = (unsigned char *)dest->imageData; // bgr image
500 
501  int j = 0;
502  int i = 0;
503  int widthStep = dest->widthStep;
504 
505  for (i = 0; i < height; i++) {
506  output = (unsigned char *)dest->imageData + i * widthStep;
507  unsigned char *line = input;
508  for (j = 0; j < width; j++) {
509  *output++ = *(line + 2); // B
510  *output++ = *(line + 1); // G
511  *output++ = *(line); // R
512 
513  line += 4;
514  }
515  // go to the next line
516  input += 4 * width;
517  }
518 }
519 
563 void vpImageConvert::convert(const vpImage<unsigned char> &src, IplImage *&dest)
564 {
565  unsigned int height = src.getHeight();
566  unsigned int width = src.getWidth();
567  CvSize size = cvSize((int)width, (int)height);
568  int depth = 8;
569  int channels = 1;
570  if (dest != NULL) {
571  if (dest->nChannels != channels || dest->depth != depth || dest->height != (int)height ||
572  dest->width != (int)width) {
573  if (dest->nChannels != 0)
574  cvReleaseImage(&dest);
575  dest = cvCreateImage(size, depth, channels);
576  }
577  } else
578  dest = cvCreateImage(size, depth, channels);
579 
580  unsigned int widthStep = (unsigned int)dest->widthStep;
581 
582  if (width == widthStep) {
583  memcpy(dest->imageData, src.bitmap, width * height);
584  } else {
585  // copying each line taking account of the widthStep
586  for (unsigned int i = 0; i < height; i++) {
587  memcpy(dest->imageData + i * widthStep, src.bitmap + i * width, width);
588  }
589  }
590 }
591 
592 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
640 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, bool flip)
641 {
642  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
643 
644  if (src.type() == CV_8UC4) {
645  vpRGBa rgbaVal;
646  for (unsigned int i = 0; i < dest.getRows(); ++i)
647  for (unsigned int j = 0; j < dest.getCols(); ++j) {
648  cv::Vec4b tmp = src.at<cv::Vec4b>((int)i, (int)j);
649  rgbaVal.R = tmp[2];
650  rgbaVal.G = tmp[1];
651  rgbaVal.B = tmp[0];
652  rgbaVal.A = tmp[3];
653  if (flip)
654  dest[dest.getRows() - i - 1][j] = rgbaVal;
655  else
656  dest[i][j] = rgbaVal;
657  }
658  } else if (src.type() == CV_8UC3) {
659  if (src.isContinuous() && !flip) {
660  SimdRgbToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
661  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
662  } else {
663  vpRGBa rgbaVal;
664  rgbaVal.A = vpRGBa::alpha_default;
665  for (unsigned int i = 0; i < dest.getRows(); ++i) {
666  for (unsigned int j = 0; j < dest.getCols(); ++j) {
667  cv::Vec3b tmp = src.at<cv::Vec3b>((int)i, (int)j);
668  rgbaVal.R = tmp[2];
669  rgbaVal.G = tmp[1];
670  rgbaVal.B = tmp[0];
671  if (flip) {
672  dest[dest.getRows() - i - 1][j] = rgbaVal;
673  } else {
674  dest[i][j] = rgbaVal;
675  }
676  }
677  }
678  }
679  } else if (src.type() == CV_8UC1) {
680  if (src.isContinuous() && !flip) {
681  SimdGrayToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
682  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
683  } else {
684  vpRGBa rgbaVal;
685  for (unsigned int i = 0; i < dest.getRows(); ++i) {
686  for (unsigned int j = 0; j < dest.getCols(); ++j) {
687  rgbaVal = src.at<unsigned char>((int)i, (int)j);
688  if (flip) {
689  dest[dest.getRows() - i - 1][j] = rgbaVal;
690  } else {
691  dest[i][j] = rgbaVal;
692  }
693  }
694  }
695  }
696  }
697 }
698 
741 void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, bool flip, unsigned int nThreads)
742 {
743  if (src.type() == CV_8UC1) {
744  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
745  if (src.isContinuous() && !flip) {
746  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols));
747  } else {
748  if (flip) {
749  for (unsigned int i = 0; i < dest.getRows(); ++i) {
750  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1(), (size_t)src.step);
751  }
752  } else {
753  for (unsigned int i = 0; i < dest.getRows(); ++i) {
754  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1(), (size_t)src.step);
755  }
756  }
757  }
758  } else if (src.type() == CV_8UC3) {
759  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
760  if (src.isContinuous()) {
761  BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows,
762  flip, nThreads);
763  } else {
764  if (flip) {
765  for (unsigned int i = 0; i < dest.getRows(); ++i) {
766  BGRToGrey((unsigned char *)src.data + i * src.step1(),
767  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
768  (unsigned int)dest.getCols(), 1, false);
769  }
770  } else {
771  for (unsigned int i = 0; i < dest.getRows(); ++i) {
772  BGRToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
773  (unsigned int)dest.getCols(), 1, false);
774  }
775  }
776  }
777  } else if (src.type() == CV_8UC4) {
778  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
779  if (src.isContinuous()) {
780  BGRaToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols,
781  (unsigned int)src.rows, flip, nThreads);
782  } else {
783  if (flip) {
784  for (unsigned int i = 0; i < dest.getRows(); ++i) {
785  BGRaToGrey((unsigned char *)src.data + i * src.step1(),
786  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
787  (unsigned int)dest.getCols(), 1, false);
788  }
789  } else {
790  for (unsigned int i = 0; i < dest.getRows(); ++i) {
791  BGRaToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
792  (unsigned int)dest.getCols(), 1, false);
793  }
794  }
795  }
796  }
797 }
798 
835 void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
836 {
837  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_8UC4, (void *)src.bitmap);
838  cv::cvtColor(vpToMat, dest, cv::COLOR_RGBA2BGR);
839 }
840 
879 void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, bool copyData)
880 {
881  if (copyData) {
882  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
883  dest = tmpMap.clone();
884  } else {
885  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
886  }
887 }
888 
889 #endif
890 #endif
891 
892 #ifdef VISP_HAVE_YARP
926 void vpImageConvert::convert(const vpImage<unsigned char> &src, yarp::sig::ImageOf<yarp::sig::PixelMono> *dest,
927  bool copyData)
928 {
929  if (copyData) {
930  dest->resize(src.getWidth(), src.getHeight());
931  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth());
932  } else
933  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
934 }
935 
974 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelMono> *src, vpImage<unsigned char> &dest,
975  bool copyData)
976 {
977  dest.resize(src->height(), src->width());
978  if (copyData)
979  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelMono));
980  else
981  dest.bitmap = src->getRawImage();
982 }
983 
1018 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgba> *dest, bool copyData)
1019 {
1020  if (copyData) {
1021  dest->resize(src.getWidth(), src.getHeight());
1022  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() * sizeof(vpRGBa));
1023  } else
1024  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
1025 }
1026 
1065 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgba> *src, vpImage<vpRGBa> &dest, bool copyData)
1066 {
1067  dest.resize(src->height(), src->width());
1068  if (copyData)
1069  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelRgba));
1070  else
1071  dest.bitmap = static_cast<vpRGBa *>(src->getRawImage());
1072 }
1073 
1106 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgb> *dest)
1107 {
1108  dest->resize(src.getWidth(), src.getHeight());
1109  for (unsigned int i = 0; i < src.getRows(); i++) {
1110  for (unsigned int j = 0; j < src.getWidth(); j++) {
1111  dest->pixel(j, i).r = src[i][j].R;
1112  dest->pixel(j, i).g = src[i][j].G;
1113  dest->pixel(j, i).b = src[i][j].B;
1114  }
1115  }
1116 }
1117 
1156 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgb> *src, vpImage<vpRGBa> &dest)
1157 {
1158  dest.resize(src->height(), src->width());
1159  for (int i = 0; i < src->height(); i++) {
1160  for (int j = 0; j < src->width(); j++) {
1161  dest[i][j].R = src->pixel(j, i).r;
1162  dest[i][j].G = src->pixel(j, i).g;
1163  dest[i][j].B = src->pixel(j, i).b;
1164  dest[i][j].A = vpRGBa::alpha_default;
1165  }
1166  }
1167 }
1168 
1169 #endif
1170 
1171 #define vpSAT(c) \
1172  if (c & (~255)) { \
1173  if (c < 0) \
1174  c = 0; \
1175  else \
1176  c = 255; \
1177  }
1190 void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
1191 {
1192  unsigned char *s;
1193  unsigned char *d;
1194  int w, h;
1195  int r, g, b, cr, cg, cb, y1, y2;
1196 
1197  h = (int)height;
1198  w = (int)width;
1199  s = yuyv;
1200  d = rgba;
1201  while (h--) {
1202  int c = w >> 1;
1203  while (c--) {
1204  y1 = *s++;
1205  cb = ((*s - 128) * 454) >> 8;
1206  cg = (*s++ - 128) * 88;
1207  y2 = *s++;
1208  cr = ((*s - 128) * 359) >> 8;
1209  cg = (cg + (*s++ - 128) * 183) >> 8;
1210 
1211  r = y1 + cr;
1212  b = y1 + cb;
1213  g = y1 - cg;
1214  vpSAT(r) vpSAT(g) vpSAT(b)
1215 
1216  *d++ = static_cast<unsigned char>(r);
1217  *d++ = static_cast<unsigned char>(g);
1218  *d++ = static_cast<unsigned char>(b);
1219  *d++ = vpRGBa::alpha_default;
1220 
1221  r = y2 + cr;
1222  b = y2 + cb;
1223  g = y2 - cg;
1224  vpSAT(r) vpSAT(g) vpSAT(b)
1225 
1226  *d++ = static_cast<unsigned char>(r);
1227  *d++ = static_cast<unsigned char>(g);
1228  *d++ = static_cast<unsigned char>(b);
1229  *d++ = vpRGBa::alpha_default;
1230  }
1231  }
1232 }
1233 
1244 void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
1245 {
1246  unsigned char *s;
1247  unsigned char *d;
1248  int h, w;
1249  int r, g, b, cr, cg, cb, y1, y2;
1250 
1251  h = (int)height;
1252  w = (int)width;
1253  s = yuyv;
1254  d = rgb;
1255  while (h--) {
1256  int c = w >> 1;
1257  while (c--) {
1258  y1 = *s++;
1259  cb = ((*s - 128) * 454) >> 8;
1260  cg = (*s++ - 128) * 88;
1261  y2 = *s++;
1262  cr = ((*s - 128) * 359) >> 8;
1263  cg = (cg + (*s++ - 128) * 183) >> 8;
1264 
1265  r = y1 + cr;
1266  b = y1 + cb;
1267  g = y1 - cg;
1268  vpSAT(r) vpSAT(g) vpSAT(b)
1269 
1270  *d++ = static_cast<unsigned char>(r);
1271  *d++ = static_cast<unsigned char>(g);
1272  *d++ = static_cast<unsigned char>(b);
1273 
1274  r = y2 + cr;
1275  b = y2 + cb;
1276  g = y2 - cg;
1277  vpSAT(r) vpSAT(g) vpSAT(b)
1278 
1279  *d++ = static_cast<unsigned char>(r);
1280  *d++ = static_cast<unsigned char>(g);
1281  *d++ = static_cast<unsigned char>(b);
1282  }
1283  }
1284 }
1285 
1296 void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
1297 {
1298  unsigned int i = 0, j = 0;
1299 
1300  while (j < size * 2) {
1301  grey[i++] = yuyv[j];
1302  grey[i++] = yuyv[j + 2];
1303  j += 4;
1304  }
1305 }
1306 
1316 void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1317 {
1318 #if 1
1319  // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1320  for (unsigned int i = size / 4; i; i--) {
1321  int U = (int)((*yuv++ - 128) * 0.354);
1322  int U5 = 5 * U;
1323  int Y0 = *yuv++;
1324  int Y1 = *yuv++;
1325  int V = (int)((*yuv++ - 128) * 0.707);
1326  int V2 = 2 * V;
1327  int Y2 = *yuv++;
1328  int Y3 = *yuv++;
1329  int UV = -U - V;
1330 
1331  // Original equations
1332  // R = Y + 1.402 V
1333  // G = Y - 0.344 U - 0.714 V
1334  // B = Y + 1.772 U
1335  int R = Y0 + V2;
1336  if ((R >> 8) > 0)
1337  R = 255;
1338  else if (R < 0)
1339  R = 0;
1340 
1341  int G = Y0 + UV;
1342  if ((G >> 8) > 0)
1343  G = 255;
1344  else if (G < 0)
1345  G = 0;
1346 
1347  int B = Y0 + U5;
1348  if ((B >> 8) > 0)
1349  B = 255;
1350  else if (B < 0)
1351  B = 0;
1352 
1353  *rgba++ = (unsigned char)R;
1354  *rgba++ = (unsigned char)G;
1355  *rgba++ = (unsigned char)B;
1356  *rgba++ = vpRGBa::alpha_default;
1357 
1358  //---
1359  R = Y1 + V2;
1360  if ((R >> 8) > 0)
1361  R = 255;
1362  else if (R < 0)
1363  R = 0;
1364 
1365  G = Y1 + UV;
1366  if ((G >> 8) > 0)
1367  G = 255;
1368  else if (G < 0)
1369  G = 0;
1370 
1371  B = Y1 + U5;
1372  if ((B >> 8) > 0)
1373  B = 255;
1374  else if (B < 0)
1375  B = 0;
1376 
1377  *rgba++ = (unsigned char)R;
1378  *rgba++ = (unsigned char)G;
1379  *rgba++ = (unsigned char)B;
1380  *rgba++ = vpRGBa::alpha_default;
1381 
1382  //---
1383  R = Y2 + V2;
1384  if ((R >> 8) > 0)
1385  R = 255;
1386  else if (R < 0)
1387  R = 0;
1388 
1389  G = Y2 + UV;
1390  if ((G >> 8) > 0)
1391  G = 255;
1392  else if (G < 0)
1393  G = 0;
1394 
1395  B = Y2 + U5;
1396  if ((B >> 8) > 0)
1397  B = 255;
1398  else if (B < 0)
1399  B = 0;
1400 
1401  *rgba++ = (unsigned char)R;
1402  *rgba++ = (unsigned char)G;
1403  *rgba++ = (unsigned char)B;
1404  *rgba++ = vpRGBa::alpha_default;
1405 
1406  //---
1407  R = Y3 + V2;
1408  if ((R >> 8) > 0)
1409  R = 255;
1410  else if (R < 0)
1411  R = 0;
1412 
1413  G = Y3 + UV;
1414  if ((G >> 8) > 0)
1415  G = 255;
1416  else if (G < 0)
1417  G = 0;
1418 
1419  B = Y3 + U5;
1420  if ((B >> 8) > 0)
1421  B = 255;
1422  else if (B < 0)
1423  B = 0;
1424 
1425  *rgba++ = (unsigned char)R;
1426  *rgba++ = (unsigned char)G;
1427  *rgba++ = (unsigned char)B;
1428  *rgba++ = vpRGBa::alpha_default;
1429  }
1430 #else
1431  // tres tres lent ....
1432  unsigned int i = 0, j = 0;
1433  unsigned char r, g, b;
1434  while (j < numpixels * 3 / 2) {
1435 
1436  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1437  rgba[i] = r;
1438  rgba[i + 1] = g;
1439  rgba[i + 2] = b;
1440  rgba[i + 3] = vpRGBa::alpha_default;
1441  i += 4;
1442 
1443  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1444  rgba[i] = r;
1445  rgba[i + 1] = g;
1446  rgba[i + 2] = b;
1447  rgba[i + 3] = vpRGBa::alpha_default;
1448  i += 4;
1449 
1450  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1451  rgba[i] = r;
1452  rgba[i + 1] = g;
1453  rgba[i + 2] = b;
1454  rgba[i + 3] = vpRGBa::alpha_default;
1455  i += 4;
1456 
1457  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1458  rgba[i] = r;
1459  rgba[i + 1] = g;
1460  rgba[i + 2] = b;
1461  rgba[i + 3] = vpRGBa::alpha_default;
1462  i += 4;
1463 
1464  j += 6;
1465  }
1466 #endif
1467 }
1468 
1481 void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1482 {
1483 
1484 #if 1
1485  // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1486  for (unsigned int i = size / 2; i; i--) {
1487  int U = (int)((*yuv++ - 128) * 0.354);
1488  int U5 = 5 * U;
1489  int Y0 = *yuv++;
1490  int V = (int)((*yuv++ - 128) * 0.707);
1491  int V2 = 2 * V;
1492  int Y1 = *yuv++;
1493  int UV = -U - V;
1494 
1495  //---
1496  int R = Y0 + V2;
1497  if ((R >> 8) > 0)
1498  R = 255;
1499  else if (R < 0)
1500  R = 0;
1501 
1502  int G = Y0 + UV;
1503  if ((G >> 8) > 0)
1504  G = 255;
1505  else if (G < 0)
1506  G = 0;
1507 
1508  int B = Y0 + U5;
1509  if ((B >> 8) > 0)
1510  B = 255;
1511  else if (B < 0)
1512  B = 0;
1513 
1514  *rgba++ = (unsigned char)R;
1515  *rgba++ = (unsigned char)G;
1516  *rgba++ = (unsigned char)B;
1517  *rgba++ = vpRGBa::alpha_default;
1518 
1519  //---
1520  R = Y1 + V2;
1521  if ((R >> 8) > 0)
1522  R = 255;
1523  else if (R < 0)
1524  R = 0;
1525 
1526  G = Y1 + UV;
1527  if ((G >> 8) > 0)
1528  G = 255;
1529  else if (G < 0)
1530  G = 0;
1531 
1532  B = Y1 + U5;
1533  if ((B >> 8) > 0)
1534  B = 255;
1535  else if (B < 0)
1536  B = 0;
1537 
1538  *rgba++ = (unsigned char)R;
1539  *rgba++ = (unsigned char)G;
1540  *rgba++ = (unsigned char)B;
1541  *rgba++ = vpRGBa::alpha_default;
1542  }
1543 
1544 #else
1545  // tres tres lent ....
1546  unsigned int i = 0, j = 0;
1547  unsigned char r, g, b;
1548 
1549  while (j < size * 2) {
1550 
1551  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1552  rgba[i] = r;
1553  rgba[i + 1] = g;
1554  rgba[i + 2] = b;
1555  rgba[i + 3] = vpRGBa::alpha_default;
1556  i += 4;
1557 
1558  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1559  rgba[i] = r;
1560  rgba[i + 1] = g;
1561  rgba[i + 2] = b;
1562  rgba[i + 3] = vpRGBa::alpha_default;
1563  i += 4;
1564  j += 4;
1565  }
1566 #endif
1567 }
1568 
1577 void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1578 {
1579  unsigned int i = 0, j = 0;
1580  while (j < size * 3 / 2) {
1581  grey[i] = yuv[j + 1];
1582  grey[i + 1] = yuv[j + 2];
1583  grey[i + 2] = yuv[j + 4];
1584  grey[i + 3] = yuv[j + 5];
1585 
1586  i += 4;
1587 
1588  j += 6;
1589  }
1590 }
1591 
1602 void vpImageConvert::YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1603 {
1604 #if 1
1605  // std::cout << "call optimized convertYUV422ToRGB()" << std::endl;
1606  for (unsigned int i = size / 2; i; i--) {
1607  int U = (int)((*yuv++ - 128) * 0.354);
1608  int U5 = 5 * U;
1609  int Y0 = *yuv++;
1610  int V = (int)((*yuv++ - 128) * 0.707);
1611  int V2 = 2 * V;
1612  int Y1 = *yuv++;
1613  int UV = -U - V;
1614 
1615  //---
1616  int R = Y0 + V2;
1617  if ((R >> 8) > 0)
1618  R = 255;
1619  else if (R < 0)
1620  R = 0;
1621 
1622  int G = Y0 + UV;
1623  if ((G >> 8) > 0)
1624  G = 255;
1625  else if (G < 0)
1626  G = 0;
1627 
1628  int B = Y0 + U5;
1629  if ((B >> 8) > 0)
1630  B = 255;
1631  else if (B < 0)
1632  B = 0;
1633 
1634  *rgb++ = (unsigned char)R;
1635  *rgb++ = (unsigned char)G;
1636  *rgb++ = (unsigned char)B;
1637 
1638  //---
1639  R = Y1 + V2;
1640  if ((R >> 8) > 0)
1641  R = 255;
1642  else if (R < 0)
1643  R = 0;
1644 
1645  G = Y1 + UV;
1646  if ((G >> 8) > 0)
1647  G = 255;
1648  else if (G < 0)
1649  G = 0;
1650 
1651  B = Y1 + U5;
1652  if ((B >> 8) > 0)
1653  B = 255;
1654  else if (B < 0)
1655  B = 0;
1656 
1657  *rgb++ = (unsigned char)R;
1658  *rgb++ = (unsigned char)G;
1659  *rgb++ = (unsigned char)B;
1660  }
1661 
1662 #else
1663  // tres tres lent ....
1664  unsigned int i = 0, j = 0;
1665  unsigned char r, g, b;
1666 
1667  while (j < size * 2) {
1668 
1669  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1670  rgb[i] = r;
1671  rgb[i + 1] = g;
1672  rgb[i + 2] = b;
1673  i += 3;
1674 
1675  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1676  rgb[i] = r;
1677  rgb[i + 1] = g;
1678  rgb[i + 2] = b;
1679  i += 3;
1680  j += 4;
1681  }
1682 #endif
1683 }
1684 
1695 void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1696 {
1697  unsigned int i = 0, j = 0;
1698 
1699  while (j < size * 2) {
1700  grey[i++] = yuv[j + 1];
1701  grey[i++] = yuv[j + 3];
1702  j += 4;
1703  }
1704 }
1705 
1714 void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1715 {
1716 #if 1
1717  // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1718  for (unsigned int i = size / 4; i; i--) {
1719  int U = (int)((*yuv++ - 128) * 0.354);
1720  int U5 = 5 * U;
1721  int Y0 = *yuv++;
1722  int Y1 = *yuv++;
1723  int V = (int)((*yuv++ - 128) * 0.707);
1724  int V2 = 2 * V;
1725  int Y2 = *yuv++;
1726  int Y3 = *yuv++;
1727  int UV = -U - V;
1728 
1729  // Original equations
1730  // R = Y + 1.402 V
1731  // G = Y - 0.344 U - 0.714 V
1732  // B = Y + 1.772 U
1733  int R = Y0 + V2;
1734  if ((R >> 8) > 0)
1735  R = 255;
1736  else if (R < 0)
1737  R = 0;
1738 
1739  int G = Y0 + UV;
1740  if ((G >> 8) > 0)
1741  G = 255;
1742  else if (G < 0)
1743  G = 0;
1744 
1745  int B = Y0 + U5;
1746  if ((B >> 8) > 0)
1747  B = 255;
1748  else if (B < 0)
1749  B = 0;
1750 
1751  *rgb++ = (unsigned char)R;
1752  *rgb++ = (unsigned char)G;
1753  *rgb++ = (unsigned char)B;
1754 
1755  //---
1756  R = Y1 + V2;
1757  if ((R >> 8) > 0)
1758  R = 255;
1759  else if (R < 0)
1760  R = 0;
1761 
1762  G = Y1 + UV;
1763  if ((G >> 8) > 0)
1764  G = 255;
1765  else if (G < 0)
1766  G = 0;
1767 
1768  B = Y1 + U5;
1769  if ((B >> 8) > 0)
1770  B = 255;
1771  else if (B < 0)
1772  B = 0;
1773 
1774  *rgb++ = (unsigned char)R;
1775  *rgb++ = (unsigned char)G;
1776  *rgb++ = (unsigned char)B;
1777 
1778  //---
1779  R = Y2 + V2;
1780  if ((R >> 8) > 0)
1781  R = 255;
1782  else if (R < 0)
1783  R = 0;
1784 
1785  G = Y2 + UV;
1786  if ((G >> 8) > 0)
1787  G = 255;
1788  else if (G < 0)
1789  G = 0;
1790 
1791  B = Y2 + U5;
1792  if ((B >> 8) > 0)
1793  B = 255;
1794  else if (B < 0)
1795  B = 0;
1796 
1797  *rgb++ = (unsigned char)R;
1798  *rgb++ = (unsigned char)G;
1799  *rgb++ = (unsigned char)B;
1800 
1801  //---
1802  R = Y3 + V2;
1803  if ((R >> 8) > 0)
1804  R = 255;
1805  else if (R < 0)
1806  R = 0;
1807 
1808  G = Y3 + UV;
1809  if ((G >> 8) > 0)
1810  G = 255;
1811  else if (G < 0)
1812  G = 0;
1813 
1814  B = Y3 + U5;
1815  if ((B >> 8) > 0)
1816  B = 255;
1817  else if (B < 0)
1818  B = 0;
1819 
1820  *rgb++ = (unsigned char)R;
1821  *rgb++ = (unsigned char)G;
1822  *rgb++ = (unsigned char)B;
1823  }
1824 #else
1825  // tres tres lent ....
1826 
1827  unsigned int i = 0, j = 0;
1828  unsigned char r, g, b;
1829 
1830  while (j < size * 3 / 2) {
1831  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1832  rgb[i] = r;
1833  rgb[i + 1] = g;
1834  rgb[i + 2] = b;
1835  i += 3;
1836 
1837  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1838  rgb[i] = r;
1839  rgb[i + 1] = g;
1840  rgb[i + 2] = b;
1841  i += 3;
1842 
1843  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1844  rgb[i] = r;
1845  rgb[i + 1] = g;
1846  rgb[i + 2] = b;
1847  i += 3;
1848 
1849  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1850  rgb[i] = r;
1851  rgb[i + 1] = g;
1852  rgb[i + 2] = b;
1853  i += 3;
1854  // TRACE("r= %d g=%d b=%d", r, g, b);
1855 
1856  j += 6;
1857  }
1858 #endif
1859 }
1860 
1871 void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1872 {
1873  // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
1874  int U, V, R, G, B, V2, U5, UV;
1875  int Y0, Y1, Y2, Y3;
1876  unsigned int size = width * height;
1877  unsigned char *iU = yuv + size;
1878  unsigned char *iV = yuv + 5 * size / 4;
1879  for (unsigned int i = 0; i < height / 2; i++) {
1880  for (unsigned int j = 0; j < width / 2; j++) {
1881  U = (int)((*iU++ - 128) * 0.354);
1882  U5 = 5 * U;
1883  V = (int)((*iV++ - 128) * 0.707);
1884  V2 = 2 * V;
1885  UV = -U - V;
1886  Y0 = *yuv++;
1887  Y1 = *yuv;
1888  yuv = yuv + width - 1;
1889  Y2 = *yuv++;
1890  Y3 = *yuv;
1891  yuv = yuv - width + 1;
1892 
1893  // Original equations
1894  // R = Y + 1.402 V
1895  // G = Y - 0.344 U - 0.714 V
1896  // B = Y + 1.772 U
1897  R = Y0 + V2;
1898  if ((R >> 8) > 0)
1899  R = 255;
1900  else if (R < 0)
1901  R = 0;
1902 
1903  G = Y0 + UV;
1904  if ((G >> 8) > 0)
1905  G = 255;
1906  else if (G < 0)
1907  G = 0;
1908 
1909  B = Y0 + U5;
1910  if ((B >> 8) > 0)
1911  B = 255;
1912  else if (B < 0)
1913  B = 0;
1914 
1915  *rgba++ = (unsigned char)R;
1916  *rgba++ = (unsigned char)G;
1917  *rgba++ = (unsigned char)B;
1918  *rgba++ = vpRGBa::alpha_default;
1919 
1920  //---
1921  R = Y1 + V2;
1922  if ((R >> 8) > 0)
1923  R = 255;
1924  else if (R < 0)
1925  R = 0;
1926 
1927  G = Y1 + UV;
1928  if ((G >> 8) > 0)
1929  G = 255;
1930  else if (G < 0)
1931  G = 0;
1932 
1933  B = Y1 + U5;
1934  if ((B >> 8) > 0)
1935  B = 255;
1936  else if (B < 0)
1937  B = 0;
1938 
1939  *rgba++ = (unsigned char)R;
1940  *rgba++ = (unsigned char)G;
1941  *rgba++ = (unsigned char)B;
1942  *rgba = vpRGBa::alpha_default;
1943  rgba = rgba + 4 * width - 7;
1944 
1945  //---
1946  R = Y2 + V2;
1947  if ((R >> 8) > 0)
1948  R = 255;
1949  else if (R < 0)
1950  R = 0;
1951 
1952  G = Y2 + UV;
1953  if ((G >> 8) > 0)
1954  G = 255;
1955  else if (G < 0)
1956  G = 0;
1957 
1958  B = Y2 + U5;
1959  if ((B >> 8) > 0)
1960  B = 255;
1961  else if (B < 0)
1962  B = 0;
1963 
1964  *rgba++ = (unsigned char)R;
1965  *rgba++ = (unsigned char)G;
1966  *rgba++ = (unsigned char)B;
1967  *rgba++ = vpRGBa::alpha_default;
1968 
1969  //---
1970  R = Y3 + V2;
1971  if ((R >> 8) > 0)
1972  R = 255;
1973  else if (R < 0)
1974  R = 0;
1975 
1976  G = Y3 + UV;
1977  if ((G >> 8) > 0)
1978  G = 255;
1979  else if (G < 0)
1980  G = 0;
1981 
1982  B = Y3 + U5;
1983  if ((B >> 8) > 0)
1984  B = 255;
1985  else if (B < 0)
1986  B = 0;
1987 
1988  *rgba++ = (unsigned char)R;
1989  *rgba++ = (unsigned char)G;
1990  *rgba++ = (unsigned char)B;
1991  *rgba = vpRGBa::alpha_default;
1992  rgba = rgba - 4 * width + 1;
1993  }
1994  yuv += width;
1995  rgba += 4 * width;
1996  }
1997 }
1998 
2007 void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
2008 {
2009  // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
2010  int U, V, R, G, B, V2, U5, UV;
2011  int Y0, Y1, Y2, Y3;
2012  unsigned int size = width * height;
2013  unsigned char *iU = yuv + size;
2014  unsigned char *iV = yuv + 5 * size / 4;
2015  for (unsigned int i = 0; i < height / 2; i++) {
2016  for (unsigned int j = 0; j < width / 2; j++) {
2017  U = (int)((*iU++ - 128) * 0.354);
2018  U5 = 5 * U;
2019  V = (int)((*iV++ - 128) * 0.707);
2020  V2 = 2 * V;
2021  UV = -U - V;
2022  Y0 = *yuv++;
2023  Y1 = *yuv;
2024  yuv = yuv + width - 1;
2025  Y2 = *yuv++;
2026  Y3 = *yuv;
2027  yuv = yuv - width + 1;
2028 
2029  // Original equations
2030  // R = Y + 1.402 V
2031  // G = Y - 0.344 U - 0.714 V
2032  // B = Y + 1.772 U
2033  R = Y0 + V2;
2034  if ((R >> 8) > 0)
2035  R = 255;
2036  else if (R < 0)
2037  R = 0;
2038 
2039  G = Y0 + UV;
2040  if ((G >> 8) > 0)
2041  G = 255;
2042  else if (G < 0)
2043  G = 0;
2044 
2045  B = Y0 + U5;
2046  if ((B >> 8) > 0)
2047  B = 255;
2048  else if (B < 0)
2049  B = 0;
2050 
2051  *rgb++ = (unsigned char)R;
2052  *rgb++ = (unsigned char)G;
2053  *rgb++ = (unsigned char)B;
2054 
2055  //---
2056  R = Y1 + V2;
2057  if ((R >> 8) > 0)
2058  R = 255;
2059  else if (R < 0)
2060  R = 0;
2061 
2062  G = Y1 + UV;
2063  if ((G >> 8) > 0)
2064  G = 255;
2065  else if (G < 0)
2066  G = 0;
2067 
2068  B = Y1 + U5;
2069  if ((B >> 8) > 0)
2070  B = 255;
2071  else if (B < 0)
2072  B = 0;
2073 
2074  *rgb++ = (unsigned char)R;
2075  *rgb++ = (unsigned char)G;
2076  *rgb = (unsigned char)B;
2077  rgb = rgb + 3 * width - 5;
2078 
2079  //---
2080  R = Y2 + V2;
2081  if ((R >> 8) > 0)
2082  R = 255;
2083  else if (R < 0)
2084  R = 0;
2085 
2086  G = Y2 + UV;
2087  if ((G >> 8) > 0)
2088  G = 255;
2089  else if (G < 0)
2090  G = 0;
2091 
2092  B = Y2 + U5;
2093  if ((B >> 8) > 0)
2094  B = 255;
2095  else if (B < 0)
2096  B = 0;
2097 
2098  *rgb++ = (unsigned char)R;
2099  *rgb++ = (unsigned char)G;
2100  *rgb++ = (unsigned char)B;
2101 
2102  //---
2103  R = Y3 + V2;
2104  if ((R >> 8) > 0)
2105  R = 255;
2106  else if (R < 0)
2107  R = 0;
2108 
2109  G = Y3 + UV;
2110  if ((G >> 8) > 0)
2111  G = 255;
2112  else if (G < 0)
2113  G = 0;
2114 
2115  B = Y3 + U5;
2116  if ((B >> 8) > 0)
2117  B = 255;
2118  else if (B < 0)
2119  B = 0;
2120 
2121  *rgb++ = (unsigned char)R;
2122  *rgb++ = (unsigned char)G;
2123  *rgb = (unsigned char)B;
2124  rgb = rgb - 3 * width + 1;
2125  }
2126  yuv += width;
2127  rgb += 3 * width;
2128  }
2129 }
2130 
2138 void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2139 {
2140  for (unsigned int i = 0; i < size; i++) {
2141  *grey++ = *yuv++;
2142  }
2143 }
2144 
2154 void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
2155 {
2156  for (unsigned int i = 0; i < size; i++) {
2157  int U = (int)((*yuv++ - 128) * 0.354);
2158  int U5 = 5 * U;
2159  int Y = *yuv++;
2160  int V = (int)((*yuv++ - 128) * 0.707);
2161  int V2 = 2 * V;
2162  int UV = -U - V;
2163 
2164  // Original equations
2165  // R = Y + 1.402 V
2166  // G = Y - 0.344 U - 0.714 V
2167  // B = Y + 1.772 U
2168  int R = Y + V2;
2169  if ((R >> 8) > 0)
2170  R = 255;
2171  else if (R < 0)
2172  R = 0;
2173 
2174  int G = Y + UV;
2175  if ((G >> 8) > 0)
2176  G = 255;
2177  else if (G < 0)
2178  G = 0;
2179 
2180  int B = Y + U5;
2181  if ((B >> 8) > 0)
2182  B = 255;
2183  else if (B < 0)
2184  B = 0;
2185 
2186  *rgba++ = (unsigned char)R;
2187  *rgba++ = (unsigned char)G;
2188  *rgba++ = (unsigned char)B;
2189  *rgba++ = vpRGBa::alpha_default;
2190  }
2191 }
2192 
2200 void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
2201 {
2202  for (unsigned int i = 0; i < size; i++) {
2203  int U = (int)((*yuv++ - 128) * 0.354);
2204  int U5 = 5 * U;
2205  int Y = *yuv++;
2206  int V = (int)((*yuv++ - 128) * 0.707);
2207  int V2 = 2 * V;
2208  int UV = -U - V;
2209 
2210  // Original equations
2211  // R = Y + 1.402 V
2212  // G = Y - 0.344 U - 0.714 V
2213  // B = Y + 1.772 U
2214  int R = Y + V2;
2215  if ((R >> 8) > 0)
2216  R = 255;
2217  else if (R < 0)
2218  R = 0;
2219 
2220  int G = Y + UV;
2221  if ((G >> 8) > 0)
2222  G = 255;
2223  else if (G < 0)
2224  G = 0;
2225 
2226  int B = Y + U5;
2227  if ((B >> 8) > 0)
2228  B = 255;
2229  else if (B < 0)
2230  B = 0;
2231 
2232  *rgb++ = (unsigned char)R;
2233  *rgb++ = (unsigned char)G;
2234  *rgb++ = (unsigned char)B;
2235  }
2236 }
2237 
2245 void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2246 {
2247  yuv++;
2248  for (unsigned int i = 0; i < size; i++) {
2249  *grey++ = *yuv;
2250  yuv = yuv + 3;
2251  }
2252 }
2253 
2264 void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2265 {
2266  // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
2267  int U, V, R, G, B, V2, U5, UV;
2268  int Y0, Y1, Y2, Y3;
2269  unsigned int size = width * height;
2270  unsigned char *iV = yuv + size;
2271  unsigned char *iU = yuv + 5 * size / 4;
2272  for (unsigned int i = 0; i < height / 2; i++) {
2273  for (unsigned int j = 0; j < width / 2; j++) {
2274  U = (int)((*iU++ - 128) * 0.354);
2275  U5 = 5 * U;
2276  V = (int)((*iV++ - 128) * 0.707);
2277  V2 = 2 * V;
2278  UV = -U - V;
2279  Y0 = *yuv++;
2280  Y1 = *yuv;
2281  yuv = yuv + width - 1;
2282  Y2 = *yuv++;
2283  Y3 = *yuv;
2284  yuv = yuv - width + 1;
2285 
2286  // Original equations
2287  // R = Y + 1.402 V
2288  // G = Y - 0.344 U - 0.714 V
2289  // B = Y + 1.772 U
2290  R = Y0 + V2;
2291  if ((R >> 8) > 0)
2292  R = 255;
2293  else if (R < 0)
2294  R = 0;
2295 
2296  G = Y0 + UV;
2297  if ((G >> 8) > 0)
2298  G = 255;
2299  else if (G < 0)
2300  G = 0;
2301 
2302  B = Y0 + U5;
2303  if ((B >> 8) > 0)
2304  B = 255;
2305  else if (B < 0)
2306  B = 0;
2307 
2308  *rgba++ = (unsigned char)R;
2309  *rgba++ = (unsigned char)G;
2310  *rgba++ = (unsigned char)B;
2311  *rgba++ = vpRGBa::alpha_default;
2312 
2313  //---
2314  R = Y1 + V2;
2315  if ((R >> 8) > 0)
2316  R = 255;
2317  else if (R < 0)
2318  R = 0;
2319 
2320  G = Y1 + UV;
2321  if ((G >> 8) > 0)
2322  G = 255;
2323  else if (G < 0)
2324  G = 0;
2325 
2326  B = Y1 + U5;
2327  if ((B >> 8) > 0)
2328  B = 255;
2329  else if (B < 0)
2330  B = 0;
2331 
2332  *rgba++ = (unsigned char)R;
2333  *rgba++ = (unsigned char)G;
2334  *rgba++ = (unsigned char)B;
2335  *rgba = 0;
2336  rgba = rgba + 4 * width - 7;
2337 
2338  //---
2339  R = Y2 + V2;
2340  if ((R >> 8) > 0)
2341  R = 255;
2342  else if (R < 0)
2343  R = 0;
2344 
2345  G = Y2 + UV;
2346  if ((G >> 8) > 0)
2347  G = 255;
2348  else if (G < 0)
2349  G = 0;
2350 
2351  B = Y2 + U5;
2352  if ((B >> 8) > 0)
2353  B = 255;
2354  else if (B < 0)
2355  B = 0;
2356 
2357  *rgba++ = (unsigned char)R;
2358  *rgba++ = (unsigned char)G;
2359  *rgba++ = (unsigned char)B;
2360  *rgba++ = vpRGBa::alpha_default;
2361 
2362  //---
2363  R = Y3 + V2;
2364  if ((R >> 8) > 0)
2365  R = 255;
2366  else if (R < 0)
2367  R = 0;
2368 
2369  G = Y3 + UV;
2370  if ((G >> 8) > 0)
2371  G = 255;
2372  else if (G < 0)
2373  G = 0;
2374 
2375  B = Y3 + U5;
2376  if ((B >> 8) > 0)
2377  B = 255;
2378  else if (B < 0)
2379  B = 0;
2380 
2381  *rgba++ = (unsigned char)R;
2382  *rgba++ = (unsigned char)G;
2383  *rgba++ = (unsigned char)B;
2384  *rgba = vpRGBa::alpha_default;
2385  rgba = rgba - 4 * width + 1;
2386  }
2387  yuv += width;
2388  rgba += 4 * width;
2389  }
2390 }
2391 
2400 void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2401 {
2402  // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2403  int U, V, R, G, B, V2, U5, UV;
2404  int Y0, Y1, Y2, Y3;
2405  unsigned int size = width * height;
2406  unsigned char *iV = yuv + size;
2407  unsigned char *iU = yuv + 5 * size / 4;
2408  for (unsigned int i = 0; i < height / 2; i++) {
2409  for (unsigned int j = 0; j < width / 2; j++) {
2410  U = (int)((*iU++ - 128) * 0.354);
2411  U5 = 5 * U;
2412  V = (int)((*iV++ - 128) * 0.707);
2413  V2 = 2 * V;
2414  UV = -U - V;
2415  Y0 = *yuv++;
2416  Y1 = *yuv;
2417  yuv = yuv + width - 1;
2418  Y2 = *yuv++;
2419  Y3 = *yuv;
2420  yuv = yuv - width + 1;
2421 
2422  // Original equations
2423  // R = Y + 1.402 V
2424  // G = Y - 0.344 U - 0.714 V
2425  // B = Y + 1.772 U
2426  R = Y0 + V2;
2427  if ((R >> 8) > 0)
2428  R = 255;
2429  else if (R < 0)
2430  R = 0;
2431 
2432  G = Y0 + UV;
2433  if ((G >> 8) > 0)
2434  G = 255;
2435  else if (G < 0)
2436  G = 0;
2437 
2438  B = Y0 + U5;
2439  if ((B >> 8) > 0)
2440  B = 255;
2441  else if (B < 0)
2442  B = 0;
2443 
2444  *rgb++ = (unsigned char)R;
2445  *rgb++ = (unsigned char)G;
2446  *rgb++ = (unsigned char)B;
2447 
2448  //---
2449  R = Y1 + V2;
2450  if ((R >> 8) > 0)
2451  R = 255;
2452  else if (R < 0)
2453  R = 0;
2454 
2455  G = Y1 + UV;
2456  if ((G >> 8) > 0)
2457  G = 255;
2458  else if (G < 0)
2459  G = 0;
2460 
2461  B = Y1 + U5;
2462  if ((B >> 8) > 0)
2463  B = 255;
2464  else if (B < 0)
2465  B = 0;
2466 
2467  *rgb++ = (unsigned char)R;
2468  *rgb++ = (unsigned char)G;
2469  *rgb = (unsigned char)B;
2470  rgb = rgb + 3 * width - 5;
2471 
2472  //---
2473  R = Y2 + V2;
2474  if ((R >> 8) > 0)
2475  R = 255;
2476  else if (R < 0)
2477  R = 0;
2478 
2479  G = Y2 + UV;
2480  if ((G >> 8) > 0)
2481  G = 255;
2482  else if (G < 0)
2483  G = 0;
2484 
2485  B = Y2 + U5;
2486  if ((B >> 8) > 0)
2487  B = 255;
2488  else if (B < 0)
2489  B = 0;
2490 
2491  *rgb++ = (unsigned char)R;
2492  *rgb++ = (unsigned char)G;
2493  *rgb++ = (unsigned char)B;
2494 
2495  //---
2496  R = Y3 + V2;
2497  if ((R >> 8) > 0)
2498  R = 255;
2499  else if (R < 0)
2500  R = 0;
2501 
2502  G = Y3 + UV;
2503  if ((G >> 8) > 0)
2504  G = 255;
2505  else if (G < 0)
2506  G = 0;
2507 
2508  B = Y3 + U5;
2509  if ((B >> 8) > 0)
2510  B = 255;
2511  else if (B < 0)
2512  B = 0;
2513 
2514  *rgb++ = (unsigned char)R;
2515  *rgb++ = (unsigned char)G;
2516  *rgb = (unsigned char)B;
2517  rgb = rgb - 3 * width + 1;
2518  }
2519  yuv += width;
2520  rgb += 3 * width;
2521  }
2522 }
2523 
2534 void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2535 {
2536  // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2537  int U, V, R, G, B, V2, U5, UV;
2538  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2539  unsigned int size = width * height;
2540  unsigned char *iV = yuv + size;
2541  unsigned char *iU = yuv + 17 * size / 16;
2542  for (unsigned int i = 0; i < height / 4; i++) {
2543  for (unsigned int j = 0; j < width / 4; j++) {
2544  U = (int)((*iU++ - 128) * 0.354);
2545  U5 = 5 * U;
2546  V = (int)((*iV++ - 128) * 0.707);
2547  V2 = 2 * V;
2548  UV = -U - V;
2549  Y0 = *yuv++;
2550  Y1 = *yuv++;
2551  Y2 = *yuv++;
2552  Y3 = *yuv;
2553  yuv = yuv + width - 3;
2554  Y4 = *yuv++;
2555  Y5 = *yuv++;
2556  Y6 = *yuv++;
2557  Y7 = *yuv;
2558  yuv = yuv + width - 3;
2559  Y8 = *yuv++;
2560  Y9 = *yuv++;
2561  Y10 = *yuv++;
2562  Y11 = *yuv;
2563  yuv = yuv + width - 3;
2564  Y12 = *yuv++;
2565  Y13 = *yuv++;
2566  Y14 = *yuv++;
2567  Y15 = *yuv;
2568  yuv = yuv - 3 * width + 1;
2569 
2570  // Original equations
2571  // R = Y + 1.402 V
2572  // G = Y - 0.344 U - 0.714 V
2573  // B = Y + 1.772 U
2574  R = Y0 + V2;
2575  if ((R >> 8) > 0)
2576  R = 255;
2577  else if (R < 0)
2578  R = 0;
2579 
2580  G = Y0 + UV;
2581  if ((G >> 8) > 0)
2582  G = 255;
2583  else if (G < 0)
2584  G = 0;
2585 
2586  B = Y0 + U5;
2587  if ((B >> 8) > 0)
2588  B = 255;
2589  else if (B < 0)
2590  B = 0;
2591 
2592  *rgba++ = (unsigned char)R;
2593  *rgba++ = (unsigned char)G;
2594  *rgba++ = (unsigned char)B;
2595  *rgba++ = vpRGBa::alpha_default;
2596 
2597  //---
2598  R = Y1 + V2;
2599  if ((R >> 8) > 0)
2600  R = 255;
2601  else if (R < 0)
2602  R = 0;
2603 
2604  G = Y1 + UV;
2605  if ((G >> 8) > 0)
2606  G = 255;
2607  else if (G < 0)
2608  G = 0;
2609 
2610  B = Y1 + U5;
2611  if ((B >> 8) > 0)
2612  B = 255;
2613  else if (B < 0)
2614  B = 0;
2615 
2616  *rgba++ = (unsigned char)R;
2617  *rgba++ = (unsigned char)G;
2618  *rgba++ = (unsigned char)B;
2619  *rgba++ = vpRGBa::alpha_default;
2620 
2621  //---
2622  R = Y2 + V2;
2623  if ((R >> 8) > 0)
2624  R = 255;
2625  else if (R < 0)
2626  R = 0;
2627 
2628  G = Y2 + UV;
2629  if ((G >> 8) > 0)
2630  G = 255;
2631  else if (G < 0)
2632  G = 0;
2633 
2634  B = Y2 + U5;
2635  if ((B >> 8) > 0)
2636  B = 255;
2637  else if (B < 0)
2638  B = 0;
2639 
2640  *rgba++ = (unsigned char)R;
2641  *rgba++ = (unsigned char)G;
2642  *rgba++ = (unsigned char)B;
2643  *rgba++ = vpRGBa::alpha_default;
2644 
2645  //---
2646  R = Y3 + V2;
2647  if ((R >> 8) > 0)
2648  R = 255;
2649  else if (R < 0)
2650  R = 0;
2651 
2652  G = Y3 + UV;
2653  if ((G >> 8) > 0)
2654  G = 255;
2655  else if (G < 0)
2656  G = 0;
2657 
2658  B = Y3 + U5;
2659  if ((B >> 8) > 0)
2660  B = 255;
2661  else if (B < 0)
2662  B = 0;
2663 
2664  *rgba++ = (unsigned char)R;
2665  *rgba++ = (unsigned char)G;
2666  *rgba++ = (unsigned char)B;
2667  *rgba = vpRGBa::alpha_default;
2668  rgba = rgba + 4 * width - 15;
2669 
2670  R = Y4 + V2;
2671  if ((R >> 8) > 0)
2672  R = 255;
2673  else if (R < 0)
2674  R = 0;
2675 
2676  G = Y4 + UV;
2677  if ((G >> 8) > 0)
2678  G = 255;
2679  else if (G < 0)
2680  G = 0;
2681 
2682  B = Y4 + U5;
2683  if ((B >> 8) > 0)
2684  B = 255;
2685  else if (B < 0)
2686  B = 0;
2687 
2688  *rgba++ = (unsigned char)R;
2689  *rgba++ = (unsigned char)G;
2690  *rgba++ = (unsigned char)B;
2691  *rgba++ = vpRGBa::alpha_default;
2692 
2693  //---
2694  R = Y5 + V2;
2695  if ((R >> 8) > 0)
2696  R = 255;
2697  else if (R < 0)
2698  R = 0;
2699 
2700  G = Y5 + UV;
2701  if ((G >> 8) > 0)
2702  G = 255;
2703  else if (G < 0)
2704  G = 0;
2705 
2706  B = Y5 + U5;
2707  if ((B >> 8) > 0)
2708  B = 255;
2709  else if (B < 0)
2710  B = 0;
2711 
2712  *rgba++ = (unsigned char)R;
2713  *rgba++ = (unsigned char)G;
2714  *rgba++ = (unsigned char)B;
2715  *rgba++ = vpRGBa::alpha_default;
2716 
2717  //---
2718  R = Y6 + V2;
2719  if ((R >> 8) > 0)
2720  R = 255;
2721  else if (R < 0)
2722  R = 0;
2723 
2724  G = Y6 + UV;
2725  if ((G >> 8) > 0)
2726  G = 255;
2727  else if (G < 0)
2728  G = 0;
2729 
2730  B = Y6 + U5;
2731  if ((B >> 8) > 0)
2732  B = 255;
2733  else if (B < 0)
2734  B = 0;
2735 
2736  *rgba++ = (unsigned char)R;
2737  *rgba++ = (unsigned char)G;
2738  *rgba++ = (unsigned char)B;
2739  *rgba++ = vpRGBa::alpha_default;
2740 
2741  //---
2742  R = Y7 + V2;
2743  if ((R >> 8) > 0)
2744  R = 255;
2745  else if (R < 0)
2746  R = 0;
2747 
2748  G = Y7 + UV;
2749  if ((G >> 8) > 0)
2750  G = 255;
2751  else if (G < 0)
2752  G = 0;
2753 
2754  B = Y7 + U5;
2755  if ((B >> 8) > 0)
2756  B = 255;
2757  else if (B < 0)
2758  B = 0;
2759 
2760  *rgba++ = (unsigned char)R;
2761  *rgba++ = (unsigned char)G;
2762  *rgba++ = (unsigned char)B;
2763  *rgba = vpRGBa::alpha_default;
2764  rgba = rgba + 4 * width - 15;
2765 
2766  R = Y8 + V2;
2767  if ((R >> 8) > 0)
2768  R = 255;
2769  else if (R < 0)
2770  R = 0;
2771 
2772  G = Y8 + UV;
2773  if ((G >> 8) > 0)
2774  G = 255;
2775  else if (G < 0)
2776  G = 0;
2777 
2778  B = Y8 + U5;
2779  if ((B >> 8) > 0)
2780  B = 255;
2781  else if (B < 0)
2782  B = 0;
2783 
2784  *rgba++ = (unsigned char)R;
2785  *rgba++ = (unsigned char)G;
2786  *rgba++ = (unsigned char)B;
2787  *rgba++ = vpRGBa::alpha_default;
2788 
2789  //---
2790  R = Y9 + V2;
2791  if ((R >> 8) > 0)
2792  R = 255;
2793  else if (R < 0)
2794  R = 0;
2795 
2796  G = Y9 + UV;
2797  if ((G >> 8) > 0)
2798  G = 255;
2799  else if (G < 0)
2800  G = 0;
2801 
2802  B = Y9 + U5;
2803  if ((B >> 8) > 0)
2804  B = 255;
2805  else if (B < 0)
2806  B = 0;
2807 
2808  *rgba++ = (unsigned char)R;
2809  *rgba++ = (unsigned char)G;
2810  *rgba++ = (unsigned char)B;
2811  *rgba++ = vpRGBa::alpha_default;
2812 
2813  //---
2814  R = Y10 + V2;
2815  if ((R >> 8) > 0)
2816  R = 255;
2817  else if (R < 0)
2818  R = 0;
2819 
2820  G = Y10 + UV;
2821  if ((G >> 8) > 0)
2822  G = 255;
2823  else if (G < 0)
2824  G = 0;
2825 
2826  B = Y10 + U5;
2827  if ((B >> 8) > 0)
2828  B = 255;
2829  else if (B < 0)
2830  B = 0;
2831 
2832  *rgba++ = (unsigned char)R;
2833  *rgba++ = (unsigned char)G;
2834  *rgba++ = (unsigned char)B;
2835  *rgba++ = vpRGBa::alpha_default;
2836 
2837  //---
2838  R = Y11 + V2;
2839  if ((R >> 8) > 0)
2840  R = 255;
2841  else if (R < 0)
2842  R = 0;
2843 
2844  G = Y11 + UV;
2845  if ((G >> 8) > 0)
2846  G = 255;
2847  else if (G < 0)
2848  G = 0;
2849 
2850  B = Y11 + U5;
2851  if ((B >> 8) > 0)
2852  B = 255;
2853  else if (B < 0)
2854  B = 0;
2855 
2856  *rgba++ = (unsigned char)R;
2857  *rgba++ = (unsigned char)G;
2858  *rgba++ = (unsigned char)B;
2859  *rgba = vpRGBa::alpha_default;
2860  rgba = rgba + 4 * width - 15;
2861 
2862  R = Y12 + V2;
2863  if ((R >> 8) > 0)
2864  R = 255;
2865  else if (R < 0)
2866  R = 0;
2867 
2868  G = Y12 + UV;
2869  if ((G >> 8) > 0)
2870  G = 255;
2871  else if (G < 0)
2872  G = 0;
2873 
2874  B = Y12 + U5;
2875  if ((B >> 8) > 0)
2876  B = 255;
2877  else if (B < 0)
2878  B = 0;
2879 
2880  *rgba++ = (unsigned char)R;
2881  *rgba++ = (unsigned char)G;
2882  *rgba++ = (unsigned char)B;
2883  *rgba++ = vpRGBa::alpha_default;
2884 
2885  //---
2886  R = Y13 + V2;
2887  if ((R >> 8) > 0)
2888  R = 255;
2889  else if (R < 0)
2890  R = 0;
2891 
2892  G = Y13 + UV;
2893  if ((G >> 8) > 0)
2894  G = 255;
2895  else if (G < 0)
2896  G = 0;
2897 
2898  B = Y13 + U5;
2899  if ((B >> 8) > 0)
2900  B = 255;
2901  else if (B < 0)
2902  B = 0;
2903 
2904  *rgba++ = (unsigned char)R;
2905  *rgba++ = (unsigned char)G;
2906  *rgba++ = (unsigned char)B;
2907  *rgba++ = vpRGBa::alpha_default;
2908 
2909  //---
2910  R = Y14 + V2;
2911  if ((R >> 8) > 0)
2912  R = 255;
2913  else if (R < 0)
2914  R = 0;
2915 
2916  G = Y14 + UV;
2917  if ((G >> 8) > 0)
2918  G = 255;
2919  else if (G < 0)
2920  G = 0;
2921 
2922  B = Y14 + U5;
2923  if ((B >> 8) > 0)
2924  B = 255;
2925  else if (B < 0)
2926  B = 0;
2927 
2928  *rgba++ = (unsigned char)R;
2929  *rgba++ = (unsigned char)G;
2930  *rgba++ = (unsigned char)B;
2931  *rgba++ = vpRGBa::alpha_default;
2932 
2933  //---
2934  R = Y15 + V2;
2935  if ((R >> 8) > 0)
2936  R = 255;
2937  else if (R < 0)
2938  R = 0;
2939 
2940  G = Y15 + UV;
2941  if ((G >> 8) > 0)
2942  G = 255;
2943  else if (G < 0)
2944  G = 0;
2945 
2946  B = Y15 + U5;
2947  if ((B >> 8) > 0)
2948  B = 255;
2949  else if (B < 0)
2950  B = 0;
2951 
2952  *rgba++ = (unsigned char)R;
2953  *rgba++ = (unsigned char)G;
2954  *rgba++ = (unsigned char)B;
2955  *rgba = vpRGBa::alpha_default;
2956  rgba = rgba - 12 * width + 1;
2957  }
2958  yuv += 3 * width;
2959  rgba += 12 * width;
2960  }
2961 }
2962 
2970 void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2971 {
2972  // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
2973  int U, V, R, G, B, V2, U5, UV;
2974  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2975  unsigned int size = width * height;
2976  unsigned char *iV = yuv + size;
2977  unsigned char *iU = yuv + 17 * size / 16;
2978  for (unsigned int i = 0; i < height / 4; i++) {
2979  for (unsigned int j = 0; j < width / 4; j++) {
2980  U = (int)((*iU++ - 128) * 0.354);
2981  U5 = 5 * U;
2982  V = (int)((*iV++ - 128) * 0.707);
2983  V2 = 2 * V;
2984  UV = -U - V;
2985  Y0 = *yuv++;
2986  Y1 = *yuv++;
2987  Y2 = *yuv++;
2988  Y3 = *yuv;
2989  yuv = yuv + width - 3;
2990  Y4 = *yuv++;
2991  Y5 = *yuv++;
2992  Y6 = *yuv++;
2993  Y7 = *yuv;
2994  yuv = yuv + width - 3;
2995  Y8 = *yuv++;
2996  Y9 = *yuv++;
2997  Y10 = *yuv++;
2998  Y11 = *yuv;
2999  yuv = yuv + width - 3;
3000  Y12 = *yuv++;
3001  Y13 = *yuv++;
3002  Y14 = *yuv++;
3003  Y15 = *yuv;
3004  yuv = yuv - 3 * width + 1;
3005 
3006  // Original equations
3007  // R = Y + 1.402 V
3008  // G = Y - 0.344 U - 0.714 V
3009  // B = Y + 1.772 U
3010  R = Y0 + V2;
3011  if ((R >> 8) > 0)
3012  R = 255;
3013  else if (R < 0)
3014  R = 0;
3015 
3016  G = Y0 + UV;
3017  if ((G >> 8) > 0)
3018  G = 255;
3019  else if (G < 0)
3020  G = 0;
3021 
3022  B = Y0 + U5;
3023  if ((B >> 8) > 0)
3024  B = 255;
3025  else if (B < 0)
3026  B = 0;
3027 
3028  *rgb++ = (unsigned char)R;
3029  *rgb++ = (unsigned char)G;
3030  *rgb++ = (unsigned char)B;
3031 
3032  //---
3033  R = Y1 + V2;
3034  if ((R >> 8) > 0)
3035  R = 255;
3036  else if (R < 0)
3037  R = 0;
3038 
3039  G = Y1 + UV;
3040  if ((G >> 8) > 0)
3041  G = 255;
3042  else if (G < 0)
3043  G = 0;
3044 
3045  B = Y1 + U5;
3046  if ((B >> 8) > 0)
3047  B = 255;
3048  else if (B < 0)
3049  B = 0;
3050 
3051  *rgb++ = (unsigned char)R;
3052  *rgb++ = (unsigned char)G;
3053  *rgb++ = (unsigned char)B;
3054 
3055  //---
3056  R = Y2 + V2;
3057  if ((R >> 8) > 0)
3058  R = 255;
3059  else if (R < 0)
3060  R = 0;
3061 
3062  G = Y2 + UV;
3063  if ((G >> 8) > 0)
3064  G = 255;
3065  else if (G < 0)
3066  G = 0;
3067 
3068  B = Y2 + U5;
3069  if ((B >> 8) > 0)
3070  B = 255;
3071  else if (B < 0)
3072  B = 0;
3073 
3074  *rgb++ = (unsigned char)R;
3075  *rgb++ = (unsigned char)G;
3076  *rgb++ = (unsigned char)B;
3077 
3078  //---
3079  R = Y3 + V2;
3080  if ((R >> 8) > 0)
3081  R = 255;
3082  else if (R < 0)
3083  R = 0;
3084 
3085  G = Y3 + UV;
3086  if ((G >> 8) > 0)
3087  G = 255;
3088  else if (G < 0)
3089  G = 0;
3090 
3091  B = Y3 + U5;
3092  if ((B >> 8) > 0)
3093  B = 255;
3094  else if (B < 0)
3095  B = 0;
3096 
3097  *rgb++ = (unsigned char)R;
3098  *rgb++ = (unsigned char)G;
3099  *rgb = (unsigned char)B;
3100  rgb = rgb + 3 * width - 11;
3101 
3102  R = Y4 + V2;
3103  if ((R >> 8) > 0)
3104  R = 255;
3105  else if (R < 0)
3106  R = 0;
3107 
3108  G = Y4 + UV;
3109  if ((G >> 8) > 0)
3110  G = 255;
3111  else if (G < 0)
3112  G = 0;
3113 
3114  B = Y4 + U5;
3115  if ((B >> 8) > 0)
3116  B = 255;
3117  else if (B < 0)
3118  B = 0;
3119 
3120  *rgb++ = (unsigned char)R;
3121  *rgb++ = (unsigned char)G;
3122  *rgb++ = (unsigned char)B;
3123 
3124  //---
3125  R = Y5 + V2;
3126  if ((R >> 8) > 0)
3127  R = 255;
3128  else if (R < 0)
3129  R = 0;
3130 
3131  G = Y5 + UV;
3132  if ((G >> 8) > 0)
3133  G = 255;
3134  else if (G < 0)
3135  G = 0;
3136 
3137  B = Y5 + U5;
3138  if ((B >> 8) > 0)
3139  B = 255;
3140  else if (B < 0)
3141  B = 0;
3142 
3143  *rgb++ = (unsigned char)R;
3144  *rgb++ = (unsigned char)G;
3145  *rgb++ = (unsigned char)B;
3146 
3147  //---
3148  R = Y6 + V2;
3149  if ((R >> 8) > 0)
3150  R = 255;
3151  else if (R < 0)
3152  R = 0;
3153 
3154  G = Y6 + UV;
3155  if ((G >> 8) > 0)
3156  G = 255;
3157  else if (G < 0)
3158  G = 0;
3159 
3160  B = Y6 + U5;
3161  if ((B >> 8) > 0)
3162  B = 255;
3163  else if (B < 0)
3164  B = 0;
3165 
3166  *rgb++ = (unsigned char)R;
3167  *rgb++ = (unsigned char)G;
3168  *rgb++ = (unsigned char)B;
3169 
3170  //---
3171  R = Y7 + V2;
3172  if ((R >> 8) > 0)
3173  R = 255;
3174  else if (R < 0)
3175  R = 0;
3176 
3177  G = Y7 + UV;
3178  if ((G >> 8) > 0)
3179  G = 255;
3180  else if (G < 0)
3181  G = 0;
3182 
3183  B = Y7 + U5;
3184  if ((B >> 8) > 0)
3185  B = 255;
3186  else if (B < 0)
3187  B = 0;
3188 
3189  *rgb++ = (unsigned char)R;
3190  *rgb++ = (unsigned char)G;
3191  *rgb = (unsigned char)B;
3192  rgb = rgb + 3 * width - 11;
3193 
3194  R = Y8 + V2;
3195  if ((R >> 8) > 0)
3196  R = 255;
3197  else if (R < 0)
3198  R = 0;
3199 
3200  G = Y8 + UV;
3201  if ((G >> 8) > 0)
3202  G = 255;
3203  else if (G < 0)
3204  G = 0;
3205 
3206  B = Y8 + U5;
3207  if ((B >> 8) > 0)
3208  B = 255;
3209  else if (B < 0)
3210  B = 0;
3211 
3212  *rgb++ = (unsigned char)R;
3213  *rgb++ = (unsigned char)G;
3214  *rgb++ = (unsigned char)B;
3215 
3216  //---
3217  R = Y9 + V2;
3218  if ((R >> 8) > 0)
3219  R = 255;
3220  else if (R < 0)
3221  R = 0;
3222 
3223  G = Y9 + UV;
3224  if ((G >> 8) > 0)
3225  G = 255;
3226  else if (G < 0)
3227  G = 0;
3228 
3229  B = Y9 + U5;
3230  if ((B >> 8) > 0)
3231  B = 255;
3232  else if (B < 0)
3233  B = 0;
3234 
3235  *rgb++ = (unsigned char)R;
3236  *rgb++ = (unsigned char)G;
3237  *rgb++ = (unsigned char)B;
3238 
3239  //---
3240  R = Y10 + V2;
3241  if ((R >> 8) > 0)
3242  R = 255;
3243  else if (R < 0)
3244  R = 0;
3245 
3246  G = Y10 + UV;
3247  if ((G >> 8) > 0)
3248  G = 255;
3249  else if (G < 0)
3250  G = 0;
3251 
3252  B = Y10 + U5;
3253  if ((B >> 8) > 0)
3254  B = 255;
3255  else if (B < 0)
3256  B = 0;
3257 
3258  *rgb++ = (unsigned char)R;
3259  *rgb++ = (unsigned char)G;
3260  *rgb++ = (unsigned char)B;
3261 
3262  //---
3263  R = Y11 + V2;
3264  if ((R >> 8) > 0)
3265  R = 255;
3266  else if (R < 0)
3267  R = 0;
3268 
3269  G = Y11 + UV;
3270  if ((G >> 8) > 0)
3271  G = 255;
3272  else if (G < 0)
3273  G = 0;
3274 
3275  B = Y11 + U5;
3276  if ((B >> 8) > 0)
3277  B = 255;
3278  else if (B < 0)
3279  B = 0;
3280 
3281  *rgb++ = (unsigned char)R;
3282  *rgb++ = (unsigned char)G;
3283  *rgb = (unsigned char)B;
3284  rgb = rgb + 3 * width - 11;
3285 
3286  R = Y12 + V2;
3287  if ((R >> 8) > 0)
3288  R = 255;
3289  else if (R < 0)
3290  R = 0;
3291 
3292  G = Y12 + UV;
3293  if ((G >> 8) > 0)
3294  G = 255;
3295  else if (G < 0)
3296  G = 0;
3297 
3298  B = Y12 + U5;
3299  if ((B >> 8) > 0)
3300  B = 255;
3301  else if (B < 0)
3302  B = 0;
3303 
3304  *rgb++ = (unsigned char)R;
3305  *rgb++ = (unsigned char)G;
3306  *rgb++ = (unsigned char)B;
3307 
3308  //---
3309  R = Y13 + V2;
3310  if ((R >> 8) > 0)
3311  R = 255;
3312  else if (R < 0)
3313  R = 0;
3314 
3315  G = Y13 + UV;
3316  if ((G >> 8) > 0)
3317  G = 255;
3318  else if (G < 0)
3319  G = 0;
3320 
3321  B = Y13 + U5;
3322  if ((B >> 8) > 0)
3323  B = 255;
3324  else if (B < 0)
3325  B = 0;
3326 
3327  *rgb++ = (unsigned char)R;
3328  *rgb++ = (unsigned char)G;
3329  *rgb++ = (unsigned char)B;
3330 
3331  //---
3332  R = Y14 + V2;
3333  if ((R >> 8) > 0)
3334  R = 255;
3335  else if (R < 0)
3336  R = 0;
3337 
3338  G = Y14 + UV;
3339  if ((G >> 8) > 0)
3340  G = 255;
3341  else if (G < 0)
3342  G = 0;
3343 
3344  B = Y14 + U5;
3345  if ((B >> 8) > 0)
3346  B = 255;
3347  else if (B < 0)
3348  B = 0;
3349 
3350  *rgb++ = (unsigned char)R;
3351  *rgb++ = (unsigned char)G;
3352  *rgb++ = (unsigned char)B;
3353 
3354  //---
3355  R = Y15 + V2;
3356  if ((R >> 8) > 0)
3357  R = 255;
3358  else if (R < 0)
3359  R = 0;
3360 
3361  G = Y15 + UV;
3362  if ((G >> 8) > 0)
3363  G = 255;
3364  else if (G < 0)
3365  G = 0;
3366 
3367  B = Y15 + U5;
3368  if ((B >> 8) > 0)
3369  B = 255;
3370  else if (B < 0)
3371  B = 0;
3372 
3373  *rgb++ = (unsigned char)R;
3374  *rgb++ = (unsigned char)G;
3375  *rgb++ = (unsigned char)B;
3376  rgb = rgb - 9 * width + 1;
3377  }
3378  yuv += 3 * width;
3379  rgb += 9 * width;
3380  }
3381 }
3382 
3392 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
3393 {
3394  RGBToRGBa(rgb, rgba, size, 1, false);
3395 }
3396 
3412 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int width, unsigned int height,
3413  bool flip)
3414 {
3415  if (!flip) {
3416  SimdBgrToBgra(rgb, width, height, width * 3, rgba, width * 4, vpRGBa::alpha_default);
3417  } else {
3418  // if we have to flip the image, we start from the end last scanline so the
3419  // step is negative
3420  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3421 
3422  // starting source address = last line if we need to flip the image
3423  unsigned char *src = (flip) ? (rgb + (width * height * 3) + lineStep) : rgb;
3424 
3425  unsigned int j = 0;
3426  unsigned int i = 0;
3427 
3428  for (i = 0; i < height; i++) {
3429  unsigned char *line = src;
3430  for (j = 0; j < width; j++) {
3431  *rgba++ = *(line++);
3432  *rgba++ = *(line++);
3433  *rgba++ = *(line++);
3434  *rgba++ = vpRGBa::alpha_default;
3435  }
3436  // go to the next line
3437  src += lineStep;
3438  }
3439  }
3440 }
3441 
3454 void vpImageConvert::RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
3455 {
3456  SimdBgraToBgr(rgba, size, 1, size * 4, rgb, size * 3);
3457 }
3458 
3471 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
3472 {
3473  RGBToGrey(rgb, grey, size, 1, false);
3474 }
3475 
3489 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height,
3490  bool flip)
3491 {
3492  if (!flip) {
3493  SimdRgbToGray(rgb, width, height, width * 3, grey, width);
3494  } else {
3495  // if we have to flip the image, we start from the end last scanline so
3496  // the step is negative
3497  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3498 
3499  // starting source address = last line if we need to flip the image
3500  unsigned char *src = (flip) ? rgb + (width * height * 3) + lineStep : rgb;
3501 
3502  unsigned int j = 0;
3503  unsigned int i = 0;
3504 
3505  unsigned r, g, b;
3506 
3507  for (i = 0; i < height; i++) {
3508  unsigned char *line = src;
3509  for (j = 0; j < width; j++) {
3510  r = *(line++);
3511  g = *(line++);
3512  b = *(line++);
3513  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3514  }
3515 
3516  // go to the next line
3517  src += lineStep;
3518  }
3519  }
3520 }
3521 
3537 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height,
3538  unsigned int
3539 #if defined _OPENMP
3540  nThreads
3541 #endif
3542 )
3543 {
3544 #if defined _OPENMP
3545  if (nThreads > 0) {
3546  omp_set_num_threads(static_cast<int>(nThreads));
3547  }
3548 #pragma omp parallel for
3549 #endif
3550  for (int i = 0; i < static_cast<int>(height); i++) {
3551  SimdRgbaToGray(rgba + i * width * 4, width, 1, width * 4, grey + i * width, width);
3552  }
3553 }
3554 
3569 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
3570 {
3571  SimdRgbaToGray(rgba, size, 1, size * 4, grey, size);
3572 }
3573 
3585 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
3586 {
3587  SimdGrayToBgra(grey, width, height, width, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3588 }
3589 
3602 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
3603 {
3604  GreyToRGBa(grey, rgba, size, 1);
3605 }
3606 
3617 void vpImageConvert::GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
3618 {
3619  SimdGrayToBgr(grey, size, 1, size, rgb, size * 3);
3620 }
3621 
3637 void vpImageConvert::BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height,
3638  bool flip)
3639 {
3640  if (!flip) {
3641  SimdRgbToBgra(bgr, width, height, width * 3, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3642  } else {
3643  // if we have to flip the image, we start from the end last scanline so the
3644  // step is negative
3645  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3646 
3647  // starting source address = last line if we need to flip the image
3648  unsigned char *src = (flip) ? (bgr + (width * height * 3) + lineStep) : bgr;
3649 
3650  for (unsigned int i = 0; i < height; i++) {
3651  unsigned char *line = src;
3652  for (unsigned int j = 0; j < width; j++) {
3653  *rgba++ = *(line + 2);
3654  *rgba++ = *(line + 1);
3655  *rgba++ = *(line + 0);
3656  *rgba++ = vpRGBa::alpha_default;
3657 
3658  line += 3;
3659  }
3660  // go to the next line
3661  src += lineStep;
3662  }
3663  }
3664 }
3665 
3680 void vpImageConvert::BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height,
3681  bool flip)
3682 {
3683  if (!flip) {
3684  SimdBgraToRgba(bgra, width, height, width * 4, rgba, width * 4);
3685  } else {
3686  // if we have to flip the image, we start from the end last scanline so the
3687  // step is negative
3688  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3689 
3690  // starting source address = last line if we need to flip the image
3691  unsigned char *src = (flip) ? (bgra + (width * height * 4) + lineStep) : bgra;
3692 
3693  for (unsigned int i = 0; i < height; i++) {
3694  unsigned char *line = src;
3695  for (unsigned int j = 0; j < width; j++) {
3696  *rgba++ = *(line + 2);
3697  *rgba++ = *(line + 1);
3698  *rgba++ = *(line + 0);
3699  *rgba++ = *(line + 3);
3700 
3701  line += 4;
3702  }
3703  // go to the next line
3704  src += lineStep;
3705  }
3706  }
3707 }
3708 
3723 void vpImageConvert::BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height,
3724  bool flip,
3725  unsigned int
3726 #if defined _OPENMP
3727  nThreads
3728 #endif
3729 )
3730 {
3731  if (!flip) {
3732 #if defined _OPENMP
3733  if (nThreads > 0) {
3734  omp_set_num_threads(static_cast<int>(nThreads));
3735  }
3736 #pragma omp parallel for
3737 #endif
3738  for (int i = 0; i < static_cast<int>(height); i++) {
3739  SimdBgrToGray(bgr + i * width * 3, width, 1, width * 3, grey + i * width, width);
3740  }
3741  } else {
3742  // if we have to flip the image, we start from the end last scanline so
3743  // the step is negative
3744  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3745 
3746  // starting source address = last line if we need to flip the image
3747  unsigned char *src = (flip) ? bgr + (width * height * 3) + lineStep : bgr;
3748 
3749  for (unsigned int i = 0; i < height; i++) {
3750  unsigned char *line = src;
3751  for (unsigned int j = 0; j < width; j++) {
3752  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3753  line += 3;
3754  }
3755 
3756  // go to the next line
3757  src += lineStep;
3758  }
3759  }
3760 }
3761 
3776 void vpImageConvert::BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height,
3777  bool flip,
3778  unsigned int
3779 #if defined _OPENMP
3780  nThreads
3781 #endif
3782 )
3783 {
3784  if (!flip) {
3785 #if defined _OPENMP
3786  if (nThreads > 0) {
3787  omp_set_num_threads(static_cast<int>(nThreads));
3788  }
3789 #pragma omp parallel for
3790 #endif
3791  for (int i = 0; i < static_cast<int>(height); i++) {
3792  SimdBgraToGray(bgra + i * width * 4, width, 1, width * 4, grey + i * width, width);
3793  }
3794  } else {
3795  // if we have to flip the image, we start from the end last scanline so
3796  // the step is negative
3797  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3798 
3799  // starting source address = last line if we need to flip the image
3800  unsigned char *src = (flip) ? bgra + (width * height * 4) + lineStep : bgra;
3801 
3802  for (unsigned int i = 0; i < height; i++) {
3803  unsigned char *line = src;
3804  for (unsigned int j = 0; j < width; j++) {
3805  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3806  line += 4;
3807  }
3808 
3809  // go to the next line
3810  src += lineStep;
3811  }
3812  }
3813 }
3814 
3818 void vpImageConvert::computeYCbCrLUT()
3819 {
3820  if (YCbCrLUTcomputed == false) {
3821  int index = 256;
3822 
3823  while (index--) {
3824 
3825  int aux = index - 128;
3826  vpImageConvert::vpCrr[index] = (int)(364.6610 * aux) >> 8;
3827  vpImageConvert::vpCgb[index] = (int)(-89.8779 * aux) >> 8;
3828  vpImageConvert::vpCgr[index] = (int)(-185.8154 * aux) >> 8;
3829  vpImageConvert::vpCbb[index] = (int)(460.5724 * aux) >> 8;
3830  }
3831 
3832  YCbCrLUTcomputed = true;
3833  }
3834 }
3835 
3857 void vpImageConvert::YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
3858 {
3859  unsigned char *cbv;
3860  unsigned char *crv;
3861  unsigned char *pt_ycbcr = ycbcr;
3862  unsigned char *pt_rgb = rgb;
3863  cbv = pt_ycbcr + 1;
3864  crv = pt_ycbcr + 3;
3865 
3866  vpImageConvert::computeYCbCrLUT();
3867 
3868  int col = 0;
3869 
3870  while (size--) {
3871  int val_r, val_g, val_b;
3872  if (!(col++ % 2)) {
3873  cbv = pt_ycbcr + 1;
3874  crv = pt_ycbcr + 3;
3875  }
3876 
3877  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3878  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3879  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3880 
3881  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3882 
3883  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3884  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3885  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3886 
3887  pt_ycbcr += 2;
3888  }
3889 }
3890 
3916 void vpImageConvert::YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgba, unsigned int size)
3917 {
3918  unsigned char *cbv;
3919  unsigned char *crv;
3920  unsigned char *pt_ycbcr = ycbcr;
3921  unsigned char *pt_rgba = rgba;
3922  cbv = pt_ycbcr + 1;
3923  crv = pt_ycbcr + 3;
3924 
3925  vpImageConvert::computeYCbCrLUT();
3926 
3927  int col = 0;
3928 
3929  while (size--) {
3930  int val_r, val_g, val_b;
3931  if (!(col++ % 2)) {
3932  cbv = pt_ycbcr + 1;
3933  crv = pt_ycbcr + 3;
3934  }
3935 
3936  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3937  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3938  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3939 
3940  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3941 
3942  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3943  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3944  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3945  *pt_rgba++ = vpRGBa::alpha_default;
3946 
3947  pt_ycbcr += 2;
3948  }
3949 }
3950 
3970 void vpImageConvert::YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
3971 {
3972  unsigned int i = 0, j = 0;
3973 
3974  while (j < size * 2) {
3975  grey[i++] = ycbcr[j];
3976  grey[i++] = ycbcr[j + 2];
3977  j += 4;
3978  }
3979 }
3980 
4002 void vpImageConvert::YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
4003 {
4004  unsigned char *cbv;
4005  unsigned char *crv;
4006  unsigned char *pt_ycbcr = ycrcb;
4007  unsigned char *pt_rgb = rgb;
4008  crv = pt_ycbcr + 1;
4009  cbv = pt_ycbcr + 3;
4010 
4011  vpImageConvert::computeYCbCrLUT();
4012 
4013  int col = 0;
4014 
4015  while (size--) {
4016  int val_r, val_g, val_b;
4017  if (!(col++ % 2)) {
4018  crv = pt_ycbcr + 1;
4019  cbv = pt_ycbcr + 3;
4020  }
4021 
4022  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4023  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4024  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4025 
4026  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4027 
4028  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4029  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4030  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4031 
4032  pt_ycbcr += 2;
4033  }
4034 }
4035 
4060 void vpImageConvert::YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgba, unsigned int size)
4061 {
4062  unsigned char *cbv;
4063  unsigned char *crv;
4064  unsigned char *pt_ycbcr = ycrcb;
4065  unsigned char *pt_rgba = rgba;
4066  crv = pt_ycbcr + 1;
4067  cbv = pt_ycbcr + 3;
4068 
4069  vpImageConvert::computeYCbCrLUT();
4070 
4071  int col = 0;
4072 
4073  while (size--) {
4074  int val_r, val_g, val_b;
4075  if (!(col++ % 2)) {
4076  crv = pt_ycbcr + 1;
4077  cbv = pt_ycbcr + 3;
4078  }
4079 
4080  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4081  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4082  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4083 
4084  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4085 
4086  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4087  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4088  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4089  *pt_rgba++ = vpRGBa::alpha_default;
4090 
4091  pt_ycbcr += 2;
4092  }
4093 }
4094 
4135 {
4136  if (src.getSize() > 0) {
4137  if (pR) {
4138  pR->resize(src.getHeight(), src.getWidth());
4139  }
4140  if (pG) {
4141  pG->resize(src.getHeight(), src.getWidth());
4142  }
4143  if (pB) {
4144  pB->resize(src.getHeight(), src.getWidth());
4145  }
4146  if (pa) {
4147  pa->resize(src.getHeight(), src.getWidth());
4148  }
4149 
4150  unsigned char *ptrR = pR ? pR->bitmap : new unsigned char[src.getSize()];
4151  unsigned char *ptrG = pG ? pG->bitmap : new unsigned char[src.getSize()];
4152  unsigned char *ptrB = pB ? pB->bitmap : new unsigned char[src.getSize()];
4153  unsigned char *ptrA = pa ? pa->bitmap : new unsigned char[src.getSize()];
4154 
4155  SimdDeinterleaveBgra(reinterpret_cast<unsigned char *>(src.bitmap), src.getWidth() * sizeof(vpRGBa), src.getWidth(),
4156  src.getHeight(), ptrR, src.getWidth(), ptrG, src.getWidth(), ptrB, src.getWidth(), ptrA,
4157  src.getWidth());
4158 
4159  if (!pR) {
4160  delete[] ptrR;
4161  }
4162  if (!pG) {
4163  delete[] ptrG;
4164  }
4165  if (!pB) {
4166  delete[] ptrB;
4167  }
4168  if (!pa) {
4169  delete[] ptrA;
4170  }
4171  }
4172 }
4173 
4186 {
4187  // Check if the input channels have all the same dimensions
4188  std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
4189  if (R != NULL) {
4190  mapOfWidths[R->getWidth()]++;
4191  mapOfHeights[R->getHeight()]++;
4192  }
4193 
4194  if (G != NULL) {
4195  mapOfWidths[G->getWidth()]++;
4196  mapOfHeights[G->getHeight()]++;
4197  }
4198 
4199  if (B != NULL) {
4200  mapOfWidths[B->getWidth()]++;
4201  mapOfHeights[B->getHeight()]++;
4202  }
4203 
4204  if (a != NULL) {
4205  mapOfWidths[a->getWidth()]++;
4206  mapOfHeights[a->getHeight()]++;
4207  }
4208 
4209  if (mapOfWidths.size() == 1 && mapOfHeights.size() == 1) {
4210  unsigned int width = mapOfWidths.begin()->first;
4211  unsigned int height = mapOfHeights.begin()->first;
4212 
4213  RGBa.resize(height, width);
4214 
4215  if (R != NULL && G != NULL && B != NULL && a != NULL) {
4216  SimdInterleaveBgra(R->bitmap, width, G->bitmap, width, B->bitmap, width, a->bitmap, width, width, height,
4217  reinterpret_cast<uint8_t *>(RGBa.bitmap), width * sizeof(vpRGBa));
4218  } else {
4219  unsigned int size = width * height;
4220  for (unsigned int i = 0; i < size; i++) {
4221  if (R != NULL) {
4222  RGBa.bitmap[i].R = R->bitmap[i];
4223  }
4224 
4225  if (G != NULL) {
4226  RGBa.bitmap[i].G = G->bitmap[i];
4227  }
4228 
4229  if (B != NULL) {
4230  RGBa.bitmap[i].B = B->bitmap[i];
4231  }
4232 
4233  if (a != NULL) {
4234  RGBa.bitmap[i].A = a->bitmap[i];
4235  }
4236  }
4237  }
4238  } else {
4239  throw vpException(vpException::dimensionError, "Mismatched dimensions!");
4240  }
4241 }
4242 
4253 void vpImageConvert::MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
4254 {
4255  int i = (((int)size) << 1) - 1;
4256  int j = (int)size - 1;
4257 
4258  while (i >= 0) {
4259  int y = grey16[i--];
4260  grey[j--] = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4261  }
4262 }
4263 
4275 void vpImageConvert::MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
4276 {
4277  int i = (((int)size) << 1) - 1;
4278  int j = (int)(size * 4 - 1);
4279 
4280  while (i >= 0) {
4281  int y = grey16[i--];
4282  unsigned char v = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4283  rgba[j--] = vpRGBa::alpha_default;
4284  rgba[j--] = v;
4285  rgba[j--] = v;
4286  rgba[j--] = v;
4287  }
4288 }
4289 
4300 void vpImageConvert::HSV2RGB(const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
4301  unsigned int size, unsigned int step)
4302 {
4303  for (unsigned int i = 0; i < size; i++) {
4304  double hue = hue_[i], saturation = saturation_[i], value = value_[i];
4305 
4306  if (vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
4307  hue = value;
4308  saturation = value;
4309  } else {
4310  double h = hue * 6.0;
4311  double s = saturation;
4312  double v = value;
4313 
4314  if (vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
4315  h = 0.0;
4316  }
4317 
4318  double f = h - (int)h;
4319  double p = v * (1.0 - s);
4320  double q = v * (1.0 - s * f);
4321  double t = v * (1.0 - s * (1.0 - f));
4322 
4323  switch ((int)h) {
4324  case 0:
4325  hue = v;
4326  saturation = t;
4327  value = p;
4328  break;
4329 
4330  case 1:
4331  hue = q;
4332  saturation = v;
4333  value = p;
4334  break;
4335 
4336  case 2:
4337  hue = p;
4338  saturation = v;
4339  value = t;
4340  break;
4341 
4342  case 3:
4343  hue = p;
4344  saturation = q;
4345  value = v;
4346  break;
4347 
4348  case 4:
4349  hue = t;
4350  saturation = p;
4351  value = v;
4352  break;
4353 
4354  default: // case 5:
4355  hue = v;
4356  saturation = p;
4357  value = q;
4358  break;
4359  }
4360  }
4361 
4362  rgb[i * step] = (unsigned char)vpMath::round(hue * 255.0);
4363  rgb[i * step + 1] = (unsigned char)vpMath::round(saturation * 255.0);
4364  rgb[i * step + 2] = (unsigned char)vpMath::round(value * 255.0);
4365  if (step == 4) // alpha
4366  rgb[i * step + 3] = vpRGBa::alpha_default;
4367  }
4368 }
4369 
4380 void vpImageConvert::RGB2HSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4381  unsigned int size, unsigned int step)
4382 {
4383  for (unsigned int i = 0; i < size; i++) {
4384  double red, green, blue;
4385  double h, s, v;
4386  double min, max;
4387 
4388  red = rgb[i * step] / 255.0;
4389  green = rgb[i * step + 1] / 255.0;
4390  blue = rgb[i * step + 2] / 255.0;
4391 
4392  if (red > green) {
4393  max = ((std::max))(red, blue);
4394  min = ((std::min))(green, blue);
4395  } else {
4396  max = ((std::max))(green, blue);
4397  min = ((std::min))(red, blue);
4398  }
4399 
4400  v = max;
4401 
4402  if (!vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
4403  s = (max - min) / max;
4404  } else {
4405  s = 0.0;
4406  }
4407 
4408  if (vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
4409  h = 0.0;
4410  } else {
4411  double delta = max - min;
4412  if (vpMath::equal(delta, 0.0, std::numeric_limits<double>::epsilon())) {
4413  delta = 1.0;
4414  }
4415 
4416  if (vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
4417  h = (green - blue) / delta;
4418  } else if (vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
4419  h = 2 + (blue - red) / delta;
4420  } else {
4421  h = 4 + (red - green) / delta;
4422  }
4423 
4424  h /= 6.0;
4425  if (h < 0.0) {
4426  h += 1.0;
4427  } else if (h > 1.0) {
4428  h -= 1.0;
4429  }
4430  }
4431 
4432  hue[i] = h;
4433  saturation[i] = s;
4434  value[i] = v;
4435  }
4436 }
4437 
4450 void vpImageConvert::HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba,
4451  unsigned int size)
4452 {
4453  vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
4454 }
4455 
4468 void vpImageConvert::HSVToRGBa(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4469  unsigned char *rgba, unsigned int size)
4470 {
4471  for (unsigned int i = 0; i < size; i++) {
4472  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4473 
4474  vpImageConvert::HSVToRGBa(&h, &s, &v, (rgba + i * 4), 1);
4475  }
4476 }
4477 
4490 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value,
4491  unsigned int size)
4492 {
4493  vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
4494 }
4495 
4507 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
4508  unsigned char *value, unsigned int size)
4509 {
4510  for (unsigned int i = 0; i < size; i++) {
4511  double h, s, v;
4512  vpImageConvert::RGBaToHSV((rgba + i * 4), &h, &s, &v, 1);
4513 
4514  hue[i] = (unsigned char)(255.0 * h);
4515  saturation[i] = (unsigned char)(255.0 * s);
4516  value[i] = (unsigned char)(255.0 * v);
4517  }
4518 }
4519 
4530 void vpImageConvert::HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb,
4531  unsigned int size)
4532 {
4533  vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
4534 }
4535 
4546 void vpImageConvert::HSVToRGB(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4547  unsigned char *rgb, unsigned int size)
4548 {
4549  for (unsigned int i = 0; i < size; i++) {
4550  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4551 
4552  vpImageConvert::HSVToRGB(&h, &s, &v, (rgb + i * 3), 1);
4553  }
4554 }
4555 
4567 void vpImageConvert::RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4568  unsigned int size)
4569 {
4570  vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
4571 }
4572 
4583 void vpImageConvert::RGBToHSV(const unsigned char *rgb, unsigned char *hue, unsigned char *saturation,
4584  unsigned char *value, unsigned int size)
4585 {
4586  for (unsigned int i = 0; i < size; i++) {
4587  double h, s, v;
4588 
4589  vpImageConvert::RGBToHSV((rgb + i * 3), &h, &s, &v, 1);
4590 
4591  hue[i] = (unsigned char)(255.0 * h);
4592  saturation[i] = (unsigned char)(255.0 * s);
4593  value[i] = (unsigned char)(255.0 * v);
4594  }
4595 }
4596 
4597 // Bilinear
4598 
4611 void vpImageConvert::demosaicBGGRToRGBaBilinear(const uint8_t *bggr, uint8_t *rgba, unsigned int width,
4612  unsigned int height, unsigned int nThreads)
4613 {
4614  demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
4615 }
4616 
4629 void vpImageConvert::demosaicBGGRToRGBaBilinear(const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4630  unsigned int height, unsigned int nThreads)
4631 {
4632  demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
4633 }
4634 
4647 void vpImageConvert::demosaicGBRGToRGBaBilinear(const uint8_t *gbrg, uint8_t *rgba, unsigned int width,
4648  unsigned int height, unsigned int nThreads)
4649 {
4650  demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
4651 }
4652 
4665 void vpImageConvert::demosaicGBRGToRGBaBilinear(const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4666  unsigned int height, unsigned int nThreads)
4667 {
4668  demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
4669 }
4670 
4683 void vpImageConvert::demosaicGRBGToRGBaBilinear(const uint8_t *grbg, uint8_t *rgba, unsigned int width,
4684  unsigned int height, unsigned int nThreads)
4685 {
4686  demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
4687 }
4688 
4701 void vpImageConvert::demosaicGRBGToRGBaBilinear(const uint16_t *grbg, uint16_t *rgba, unsigned int width,
4702  unsigned int height, unsigned int nThreads)
4703 {
4704  demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
4705 }
4706 
4719 void vpImageConvert::demosaicRGGBToRGBaBilinear(const uint8_t *rggb, uint8_t *rgba, unsigned int width,
4720  unsigned int height, unsigned int nThreads)
4721 {
4722  demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
4723 }
4724 
4737 void vpImageConvert::demosaicRGGBToRGBaBilinear(const uint16_t *rggb, uint16_t *rgba, unsigned int width,
4738  unsigned int height, unsigned int nThreads)
4739 {
4740  demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
4741 }
4742 
4743 // Malvar
4744 
4757 void vpImageConvert::demosaicBGGRToRGBaMalvar(const uint8_t *bggr, uint8_t *rgba, unsigned int width,
4758  unsigned int height, unsigned int nThreads)
4759 {
4760  demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
4761 }
4762 
4775 void vpImageConvert::demosaicBGGRToRGBaMalvar(const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4776  unsigned int height, unsigned int nThreads)
4777 {
4778  demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
4779 }
4780 
4793 void vpImageConvert::demosaicGBRGToRGBaMalvar(const uint8_t *gbrg, uint8_t *rgba, unsigned int width,
4794  unsigned int height, unsigned int nThreads)
4795 {
4796  demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
4797 }
4798 
4811 void vpImageConvert::demosaicGBRGToRGBaMalvar(const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4812  unsigned int height, unsigned int nThreads)
4813 {
4814  demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
4815 }
4816 
4829 void vpImageConvert::demosaicGRBGToRGBaMalvar(const uint8_t *grbg, uint8_t *rgba, unsigned int width,
4830  unsigned int height, unsigned int nThreads)
4831 {
4832  demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
4833 }
4834 
4847 void vpImageConvert::demosaicGRBGToRGBaMalvar(const uint16_t *grbg, uint16_t *rgba, unsigned int width,
4848  unsigned int height, unsigned int nThreads)
4849 {
4850  demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
4851 }
4852 
4865 void vpImageConvert::demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width,
4866  unsigned int height, unsigned int nThreads)
4867 {
4868  demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
4869 }
4870 
4883 void vpImageConvert::demosaicRGGBToRGBaMalvar(const uint16_t *rggb, uint16_t *rgba, unsigned int width,
4884  unsigned int height, unsigned int nThreads)
4885 {
4886  demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
4887 }
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ dimensionError
Bad dimension.
Definition: vpException.h:95
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:246
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:938
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:799
unsigned int getSize() const
Definition: vpImage.h:227
unsigned int getCols() const
Definition: vpImage.h:179
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
unsigned int getHeight() const
Definition: vpImage.h:188
unsigned int getRows() const
Definition: vpImage.h:218
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:364
static int round(double x)
Definition: vpMath.h:318
Definition: vpRGBa.h:67
unsigned char B
Blue component.
Definition: vpRGBa.h:150
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned char G
Green component.
Definition: vpRGBa.h:149
@ alpha_default
Definition: vpRGBa.h:69
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
#define vpDEBUG_TRACE
Definition: vpDebug.h:487