Visual Servoing Platform  version 3.4.0
vpImageConvert.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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 <visp3/core/vpImageConvert.h>
55 #include <Simd/SimdLib.hpp>
56 
57 bool vpImageConvert::YCbCrLUTcomputed = false;
58 int vpImageConvert::vpCrr[256];
59 int vpImageConvert::vpCgb[256];
60 int vpImageConvert::vpCgr[256];
61 int vpImageConvert::vpCbb[256];
62 
72 {
73  dest.resize(src.getHeight(), src.getWidth());
74 
75  GreyToRGBa(src.bitmap, reinterpret_cast<unsigned char*>(dest.bitmap), src.getWidth(), src.getHeight());
76 }
77 
87 void vpImageConvert::convert(const vpImage<vpRGBa> &src, vpImage<unsigned char> &dest, unsigned int nThreads)
88 {
89  dest.resize(src.getHeight(), src.getWidth());
90 
91  RGBaToGrey(reinterpret_cast<unsigned char*>(src.bitmap), dest.bitmap, src.getWidth(),
92  src.getHeight(), nThreads);
93 }
94 
102 {
103  dest.resize(src.getHeight(), src.getWidth());
104  unsigned int max_xy = src.getWidth() * src.getHeight();
105  float min, max;
106 
107  src.getMinMaxValue(min, max);
108 
109  for (unsigned int i = 0; i < max_xy; i++) {
110  float val = 255.f * (src.bitmap[i] - min) / (max - min);
111  if (val < 0)
112  dest.bitmap[i] = 0;
113  else if (val > 255)
114  dest.bitmap[i] = 255;
115  else
116  dest.bitmap[i] = (unsigned char)val;
117  }
118 }
119 
126 {
127  dest.resize(src.getHeight(), src.getWidth());
128  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
129  dest.bitmap[i] = (float)src.bitmap[i];
130 }
131 
139 {
140  dest.resize(src.getHeight(), src.getWidth());
141  unsigned int max_xy = src.getWidth() * src.getHeight();
142  double min, max;
143 
144  src.getMinMaxValue(min, max);
145 
146  for (unsigned int i = 0; i < max_xy; i++) {
147  double val = 255. * (src.bitmap[i] - min) / (max - min);
148  if (val < 0)
149  dest.bitmap[i] = 0;
150  else if (val > 255)
151  dest.bitmap[i] = 255;
152  else
153  dest.bitmap[i] = (unsigned char)val;
154  }
155 }
156 
163 {
164  dest.resize(src.getHeight(), src.getWidth());
165 
166  for (unsigned int i = 0; i < src.getSize(); i++)
167  dest.bitmap[i] = (src.bitmap[i] >> 8);
168 }
169 
176 {
177  dest.resize(src.getHeight(), src.getWidth());
178 
179  for (unsigned int i = 0; i < src.getSize(); i++)
180  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] << 8);
181 }
182 
189 {
190  dest.resize(src.getHeight(), src.getWidth());
191  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
192  dest.bitmap[i] = (double)src.bitmap[i];
193 }
194 
203 {
204  dest_rgba.resize(src_depth.getHeight(), src_depth.getWidth());
205  static uint32_t histogram[0x10000];
206  memset(histogram, 0, sizeof(histogram));
207 
208  for (unsigned int i = 0; i < src_depth.getSize(); ++i)
209  ++histogram[src_depth.bitmap[i]];
210  for (int i = 2; i < 0x10000; ++i)
211  histogram[i] += histogram[i - 1]; // Build a cumulative histogram for the
212  // indices in [1,0xFFFF]
213 
214  for (unsigned int i = 0; i < src_depth.getSize(); ++i) {
215  uint16_t d = src_depth.bitmap[i];
216  if (d) {
217  unsigned char f = (unsigned char)(histogram[d] * 255 / histogram[0xFFFF]); // 0-255 based on histogram location
218  dest_rgba.bitmap[i].R = 255 - f;
219  dest_rgba.bitmap[i].G = 0;
220  dest_rgba.bitmap[i].B = f;
221  dest_rgba.bitmap[i].A = vpRGBa::alpha_default;
222  } else {
223  dest_rgba.bitmap[i].R = 20;
224  dest_rgba.bitmap[i].G = 5;
225  dest_rgba.bitmap[i].B = 0;
226  dest_rgba.bitmap[i].A = vpRGBa::alpha_default;
227  }
228  }
229 }
230 
238 {
239  dest_depth.resize(src_depth.getHeight(), src_depth.getWidth());
240  static uint32_t histogram2[0x10000];
241  memset(histogram2, 0, sizeof(histogram2));
242 
243  for (unsigned int i = 0; i < src_depth.getSize(); ++i)
244  ++histogram2[src_depth.bitmap[i]];
245  for (int i = 2; i < 0x10000; ++i)
246  histogram2[i] += histogram2[i - 1]; // Build a cumulative histogram for
247  // the indices in [1,0xFFFF]
248 
249  for (unsigned int i = 0; i < src_depth.getSize(); ++i) {
250  uint16_t d = src_depth.bitmap[i];
251  if (d) {
252  unsigned char f = static_cast<unsigned char>(histogram2[d] * 255 / histogram2[0xFFFF]); // 0-255 based on histogram location
253  dest_depth.bitmap[i] = f;
254  } else {
255  dest_depth.bitmap[i] = 0;
256  }
257  }
258 }
259 
260 #ifdef VISP_HAVE_OPENCV
261 // Deprecated: will be removed with OpenCV transcient from C to C++ api
307 void vpImageConvert::convert(const IplImage *src, vpImage<vpRGBa> &dest, bool flip)
308 {
309  int nChannel = src->nChannels;
310  int depth = src->depth;
311  int height = src->height;
312  int width = src->width;
313  int widthStep = src->widthStep;
314  int lineStep = (flip) ? 1 : 0;
315 
316  if (nChannel == 3 && depth == 8) {
317  dest.resize((unsigned int)height, (unsigned int)width);
318 
319  // starting source address
320  unsigned char *input = (unsigned char *)src->imageData;
321  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
322 
323  for (int i = 0; i < height; i++) {
324  unsigned char *line = input;
325  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
326  for (int j = 0; j < width; j++) {
327  *(output++) = *(line + 2);
328  *(output++) = *(line + 1);
329  *(output++) = *(line);
330  *(output++) = vpRGBa::alpha_default;
331 
332  line += 3;
333  }
334  // go to the next line
335  input += widthStep;
336  }
337  } else if (nChannel == 1 && depth == 8) {
338  dest.resize((unsigned int)height, (unsigned int)width);
339  // starting source address
340  unsigned char *input = (unsigned char *)src->imageData;
341  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
342 
343  for (int i = 0; i < height; i++) {
344  unsigned char *line = input;
345  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
346  for (int j = 0; j < width; j++) {
347  *output++ = *(line);
348  *output++ = *(line);
349  *output++ = *(line);
350  *output++ = vpRGBa::alpha_default; // alpha
351 
352  line++;
353  }
354  // go to the next line
355  input += widthStep;
356  }
357  }
358 }
359 
402 void vpImageConvert::convert(const IplImage *src, vpImage<unsigned char> &dest, bool flip)
403 {
404  int nChannel = src->nChannels;
405  int depth = src->depth;
406  int height = src->height;
407  int width = src->width;
408  int widthStep = src->widthStep;
409  int lineStep = (flip) ? 1 : 0;
410 
411  if (flip == false) {
412  if (widthStep == width) {
413  if (nChannel == 1 && depth == 8) {
414  dest.resize((unsigned int)height, (unsigned int)width);
415  memcpy(dest.bitmap, src->imageData, (size_t)(height * width));
416  }
417  if (nChannel == 3 && depth == 8) {
418  dest.resize((unsigned int)height, (unsigned int)width);
419  BGRToGrey((unsigned char *)src->imageData, dest.bitmap, (unsigned int)width, (unsigned int)height, false);
420  }
421  } else {
422  if (nChannel == 1 && depth == 8) {
423  dest.resize((unsigned int)height, (unsigned int)width);
424  for (int i = 0; i < height; i++) {
425  memcpy(dest.bitmap + i * width, 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, 1,
432  false);
433  }
434  }
435  }
436  } else {
437  if (nChannel == 1 && depth == 8) {
438  dest.resize((unsigned int)height, (unsigned int)width);
439  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
440  for (int i = 0; i < height; i++) {
441  memcpy(beginOutput + lineStep * (4 * width * (height - 1 - i)), src->imageData + i * widthStep, (size_t)width);
442  }
443  }
444  if (nChannel == 3 && depth == 8) {
445  dest.resize((unsigned int)height, (unsigned int)width);
446  // for (int i = 0 ; i < height ; i++){
447  BGRToGrey((unsigned char *)src->imageData /*+ i*widthStep*/, dest.bitmap /*+ i*width*/, (unsigned int)width,
448  (unsigned int)height /*1*/, true);
449  //}
450  }
451  }
452 }
453 
497 void vpImageConvert::convert(const vpImage<vpRGBa> &src, IplImage *&dest)
498 {
499  int height = (int)src.getHeight();
500  int width = (int)src.getWidth();
501  CvSize size = cvSize(width, height);
502  int depth = 8;
503  int channels = 3;
504  if (dest != NULL) {
505  if (dest->nChannels != channels || dest->depth != depth || dest->height != height || dest->width != width) {
506  if (dest->nChannels != 0)
507  cvReleaseImage(&dest);
508  dest = cvCreateImage(size, depth, channels);
509  }
510  } else
511  dest = cvCreateImage(size, depth, channels);
512 
513  // starting source address
514  unsigned char *input = (unsigned char *)src.bitmap; // rgba image
515  unsigned char *output = (unsigned char *)dest->imageData; // bgr image
516 
517  int j = 0;
518  int i = 0;
519  int widthStep = dest->widthStep;
520 
521  for (i = 0; i < height; i++) {
522  output = (unsigned char *)dest->imageData + i * widthStep;
523  unsigned char *line = input;
524  for (j = 0; j < width; j++) {
525  *output++ = *(line + 2); // B
526  *output++ = *(line + 1); // G
527  *output++ = *(line); // R
528 
529  line += 4;
530  }
531  // go to the next line
532  input += 4 * width;
533  }
534 }
535 
579 void vpImageConvert::convert(const vpImage<unsigned char> &src, IplImage *&dest)
580 {
581  unsigned int height = src.getHeight();
582  unsigned int width = src.getWidth();
583  CvSize size = cvSize((int)width, (int)height);
584  int depth = 8;
585  int channels = 1;
586  if (dest != NULL) {
587  if (dest->nChannels != channels || dest->depth != depth || dest->height != (int)height ||
588  dest->width != (int)width) {
589  if (dest->nChannels != 0)
590  cvReleaseImage(&dest);
591  dest = cvCreateImage(size, depth, channels);
592  }
593  } else
594  dest = cvCreateImage(size, depth, channels);
595 
596  unsigned int widthStep = (unsigned int)dest->widthStep;
597 
598  if (width == widthStep) {
599  memcpy(dest->imageData, src.bitmap, width * height);
600  } else {
601  // copying each line taking account of the widthStep
602  for (unsigned int i = 0; i < height; i++) {
603  memcpy(dest->imageData + i * widthStep, src.bitmap + i * width, width);
604  }
605  }
606 }
607 
608 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
609 
656 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, bool flip)
657 {
658 dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
659 
660  if (src.type() == CV_8UC4) {
661  vpRGBa rgbaVal;
662  for (unsigned int i = 0; i < dest.getRows(); ++i)
663  for (unsigned int j = 0; j < dest.getCols(); ++j) {
664  cv::Vec4b tmp = src.at<cv::Vec4b>((int)i, (int)j);
665  rgbaVal.R = tmp[2];
666  rgbaVal.G = tmp[1];
667  rgbaVal.B = tmp[0];
668  rgbaVal.A = tmp[3];
669  if (flip)
670  dest[dest.getRows() - i - 1][j] = rgbaVal;
671  else
672  dest[i][j] = rgbaVal;
673  }
674  } else if (src.type() == CV_8UC3) {
675  if (src.isContinuous() && !flip) {
676  SimdBgrToRgba(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t*>(dest.bitmap),
677  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
678  } else {
679  vpRGBa rgbaVal;
680  rgbaVal.A = vpRGBa::alpha_default;
681  for (unsigned int i = 0; i < dest.getRows(); ++i) {
682  for (unsigned int j = 0; j < dest.getCols(); ++j) {
683  cv::Vec3b tmp = src.at<cv::Vec3b>((int)i, (int)j);
684  rgbaVal.R = tmp[2];
685  rgbaVal.G = tmp[1];
686  rgbaVal.B = tmp[0];
687  if (flip) {
688  dest[dest.getRows() - i - 1][j] = rgbaVal;
689  } else {
690  dest[i][j] = rgbaVal;
691  }
692  }
693  }
694  }
695  } else if (src.type() == CV_8UC1) {
696  if (src.isContinuous() && !flip) {
697  SimdGrayToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t*>(dest.bitmap),
698  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
699  } else {
700  vpRGBa rgbaVal;
701  for (unsigned int i = 0; i < dest.getRows(); ++i) {
702  for (unsigned int j = 0; j < dest.getCols(); ++j) {
703  rgbaVal = src.at<unsigned char>((int)i, (int)j);
704  if (flip) {
705  dest[dest.getRows() - i - 1][j] = rgbaVal;
706  } else {
707  dest[i][j] = rgbaVal;
708  }
709  }
710  }
711  }
712  }
713 }
714 
757 void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, bool flip,
758  unsigned int nThreads)
759 {
760  if (src.type() == CV_8UC1) {
761  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
762  if (src.isContinuous() && !flip) {
763  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols));
764  } else {
765  if (flip) {
766  for (unsigned int i = 0; i < dest.getRows(); ++i) {
767  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1(), (size_t)src.step);
768  }
769  } else {
770  for (unsigned int i = 0; i < dest.getRows(); ++i) {
771  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1(), (size_t)src.step);
772  }
773  }
774  }
775  } else if (src.type() == CV_8UC3) {
776  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
777  if (src.isContinuous()) {
778  BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows,
779  flip, nThreads);
780  } else {
781  if (flip) {
782  for (unsigned int i = 0; i < dest.getRows(); ++i) {
783  BGRToGrey((unsigned char *)src.data + i * src.step1(),
784  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
785  (unsigned int)dest.getCols(), 1, false);
786  }
787  } else {
788  for (unsigned int i = 0; i < dest.getRows(); ++i) {
789  BGRToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
790  (unsigned int)dest.getCols(), 1, false);
791  }
792  }
793  }
794  }
795  else if (src.type() == CV_8UC4) {
796  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
797  if (src.isContinuous()) {
798  BGRaToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows,
799  flip, nThreads);
800  } else {
801  if (flip) {
802  for (unsigned int i = 0; i < dest.getRows(); ++i) {
803  BGRaToGrey((unsigned char *)src.data + i * src.step1(),
804  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
805  (unsigned int)dest.getCols(), 1, false);
806  }
807  } else {
808  for (unsigned int i = 0; i < dest.getRows(); ++i) {
809  BGRaToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
810  (unsigned int)dest.getCols(), 1, false);
811  }
812  }
813  }
814  }
815 }
816 
853 void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
854 {
855  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_8UC4, (void *)src.bitmap);
856  cv::cvtColor(vpToMat, dest, cv::COLOR_RGBA2BGR);
857 }
858 
897 void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, bool copyData)
898 {
899  if (copyData) {
900  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
901  dest = tmpMap.clone();
902  } else {
903  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
904  }
905 }
906 
907 #endif
908 #endif
909 
910 #ifdef VISP_HAVE_YARP
911 
945 void vpImageConvert::convert(const vpImage<unsigned char> &src, yarp::sig::ImageOf<yarp::sig::PixelMono> *dest,
946  bool copyData)
947 {
948  if (copyData) {
949  dest->resize(src.getWidth(), src.getHeight());
950  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth());
951  } else
952  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
953 }
954 
993 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelMono> *src, vpImage<unsigned char> &dest,
994  bool copyData)
995 {
996  dest.resize(src->height(), src->width());
997  if (copyData)
998  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelMono));
999  else
1000  dest.bitmap = src->getRawImage();
1001 }
1002 
1037 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgba> *dest,
1038  bool copyData)
1039 {
1040  if (copyData) {
1041  dest->resize(src.getWidth(), src.getHeight());
1042  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() * sizeof(vpRGBa));
1043  } else
1044  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
1045 }
1046 
1085 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgba> *src, vpImage<vpRGBa> &dest,
1086  bool copyData)
1087 {
1088  dest.resize(src->height(), src->width());
1089  if (copyData)
1090  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelRgba));
1091  else
1092  dest.bitmap = static_cast<vpRGBa *>(src->getRawImage());
1093 }
1094 
1127 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgb> *dest)
1128 {
1129  dest->resize(src.getWidth(), src.getHeight());
1130  for (unsigned int i = 0; i < src.getRows(); i++) {
1131  for (unsigned int j = 0; j < src.getWidth(); j++) {
1132  dest->pixel(j, i).r = src[i][j].R;
1133  dest->pixel(j, i).g = src[i][j].G;
1134  dest->pixel(j, i).b = src[i][j].B;
1135  }
1136  }
1137 }
1138 
1177 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgb> *src, vpImage<vpRGBa> &dest)
1178 {
1179  dest.resize(src->height(), src->width());
1180  for (int i = 0; i < src->height(); i++) {
1181  for (int j = 0; j < src->width(); j++) {
1182  dest[i][j].R = src->pixel(j, i).r;
1183  dest[i][j].G = src->pixel(j, i).g;
1184  dest[i][j].B = src->pixel(j, i).b;
1185  dest[i][j].A = vpRGBa::alpha_default;
1186  }
1187  }
1188 }
1189 
1190 #endif
1191 
1192 #define vpSAT(c) \
1193  if (c & (~255)) { \
1194  if (c < 0) \
1195  c = 0; \
1196  else \
1197  c = 255; \
1198  }
1199 
1207 void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
1208 {
1209  unsigned char *s;
1210  unsigned char *d;
1211  int w, h;
1212  int r, g, b, cr, cg, cb, y1, y2;
1213 
1214  h = (int)height;
1215  w = (int)width;
1216  s = yuyv;
1217  d = rgba;
1218  while (h--) {
1219  int c = w >> 1;
1220  while (c--) {
1221  y1 = *s++;
1222  cb = ((*s - 128) * 454) >> 8;
1223  cg = (*s++ - 128) * 88;
1224  y2 = *s++;
1225  cr = ((*s - 128) * 359) >> 8;
1226  cg = (cg + (*s++ - 128) * 183) >> 8;
1227 
1228  r = y1 + cr;
1229  b = y1 + cb;
1230  g = y1 - cg;
1231  vpSAT(r);
1232  vpSAT(g);
1233  vpSAT(b);
1234 
1235  *d++ = static_cast<unsigned char>(r);
1236  *d++ = static_cast<unsigned char>(g);
1237  *d++ = static_cast<unsigned char>(b);
1238  *d++ = vpRGBa::alpha_default;
1239 
1240  r = y2 + cr;
1241  b = y2 + cb;
1242  g = y2 - cg;
1243  vpSAT(r);
1244  vpSAT(g);
1245  vpSAT(b);
1246 
1247  *d++ = static_cast<unsigned char>(r);
1248  *d++ = static_cast<unsigned char>(g);
1249  *d++ = static_cast<unsigned char>(b);
1250  *d++ = vpRGBa::alpha_default;
1251  }
1252  }
1253 }
1254 
1261 void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
1262 {
1263  unsigned char *s;
1264  unsigned char *d;
1265  int h, w;
1266  int r, g, b, cr, cg, cb, y1, y2;
1267 
1268  h = (int)height;
1269  w = (int)width;
1270  s = yuyv;
1271  d = rgb;
1272  while (h--) {
1273  int c = w >> 1;
1274  while (c--) {
1275  y1 = *s++;
1276  cb = ((*s - 128) * 454) >> 8;
1277  cg = (*s++ - 128) * 88;
1278  y2 = *s++;
1279  cr = ((*s - 128) * 359) >> 8;
1280  cg = (cg + (*s++ - 128) * 183) >> 8;
1281 
1282  r = y1 + cr;
1283  b = y1 + cb;
1284  g = y1 - cg;
1285  vpSAT(r);
1286  vpSAT(g);
1287  vpSAT(b);
1288 
1289  *d++ = static_cast<unsigned char>(r);
1290  *d++ = static_cast<unsigned char>(g);
1291  *d++ = static_cast<unsigned char>(b);
1292 
1293  r = y2 + cr;
1294  b = y2 + cb;
1295  g = y2 - cg;
1296  vpSAT(r);
1297  vpSAT(g);
1298  vpSAT(b);
1299 
1300  *d++ = static_cast<unsigned char>(r);
1301  *d++ = static_cast<unsigned char>(g);
1302  *d++ = static_cast<unsigned char>(b);
1303  }
1304  }
1305 }
1306 
1313 void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
1314 {
1315  unsigned int i = 0, j = 0;
1316 
1317  while (j < size * 2) {
1318  grey[i++] = yuyv[j];
1319  grey[i++] = yuyv[j + 2];
1320  j += 4;
1321  }
1322 }
1323 
1328 void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1329 {
1330 #if 1
1331  // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1332  for (unsigned int i = size / 4; i; i--) {
1333  int U = (int)((*yuv++ - 128) * 0.354);
1334  int U5 = 5 * U;
1335  int Y0 = *yuv++;
1336  int Y1 = *yuv++;
1337  int V = (int)((*yuv++ - 128) * 0.707);
1338  int V2 = 2 * V;
1339  int Y2 = *yuv++;
1340  int Y3 = *yuv++;
1341  int UV = -U - V;
1342 
1343  // Original equations
1344  // R = Y + 1.402 V
1345  // G = Y - 0.344 U - 0.714 V
1346  // B = Y + 1.772 U
1347  int R = Y0 + V2;
1348  if ((R >> 8) > 0)
1349  R = 255;
1350  else if (R < 0)
1351  R = 0;
1352 
1353  int G = Y0 + UV;
1354  if ((G >> 8) > 0)
1355  G = 255;
1356  else if (G < 0)
1357  G = 0;
1358 
1359  int B = Y0 + U5;
1360  if ((B >> 8) > 0)
1361  B = 255;
1362  else if (B < 0)
1363  B = 0;
1364 
1365  *rgba++ = (unsigned char)R;
1366  *rgba++ = (unsigned char)G;
1367  *rgba++ = (unsigned char)B;
1368  *rgba++ = vpRGBa::alpha_default;
1369 
1370  //---
1371  R = Y1 + V2;
1372  if ((R >> 8) > 0)
1373  R = 255;
1374  else if (R < 0)
1375  R = 0;
1376 
1377  G = Y1 + UV;
1378  if ((G >> 8) > 0)
1379  G = 255;
1380  else if (G < 0)
1381  G = 0;
1382 
1383  B = Y1 + U5;
1384  if ((B >> 8) > 0)
1385  B = 255;
1386  else if (B < 0)
1387  B = 0;
1388 
1389  *rgba++ = (unsigned char)R;
1390  *rgba++ = (unsigned char)G;
1391  *rgba++ = (unsigned char)B;
1392  *rgba++ = vpRGBa::alpha_default;
1393 
1394  //---
1395  R = Y2 + V2;
1396  if ((R >> 8) > 0)
1397  R = 255;
1398  else if (R < 0)
1399  R = 0;
1400 
1401  G = Y2 + UV;
1402  if ((G >> 8) > 0)
1403  G = 255;
1404  else if (G < 0)
1405  G = 0;
1406 
1407  B = Y2 + U5;
1408  if ((B >> 8) > 0)
1409  B = 255;
1410  else if (B < 0)
1411  B = 0;
1412 
1413  *rgba++ = (unsigned char)R;
1414  *rgba++ = (unsigned char)G;
1415  *rgba++ = (unsigned char)B;
1416  *rgba++ = vpRGBa::alpha_default;
1417 
1418  //---
1419  R = Y3 + V2;
1420  if ((R >> 8) > 0)
1421  R = 255;
1422  else if (R < 0)
1423  R = 0;
1424 
1425  G = Y3 + UV;
1426  if ((G >> 8) > 0)
1427  G = 255;
1428  else if (G < 0)
1429  G = 0;
1430 
1431  B = Y3 + U5;
1432  if ((B >> 8) > 0)
1433  B = 255;
1434  else if (B < 0)
1435  B = 0;
1436 
1437  *rgba++ = (unsigned char)R;
1438  *rgba++ = (unsigned char)G;
1439  *rgba++ = (unsigned char)B;
1440  *rgba++ = vpRGBa::alpha_default;
1441  }
1442 #else
1443  // tres tres lent ....
1444  unsigned int i = 0, j = 0;
1445  unsigned char r, g, b;
1446  while (j < numpixels * 3 / 2) {
1447 
1448  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1449  rgba[i] = r;
1450  rgba[i + 1] = g;
1451  rgba[i + 2] = b;
1452  rgba[i + 3] = vpRGBa::alpha_default;
1453  i += 4;
1454 
1455  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1456  rgba[i] = r;
1457  rgba[i + 1] = g;
1458  rgba[i + 2] = b;
1459  rgba[i + 3] = vpRGBa::alpha_default;
1460  i += 4;
1461 
1462  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1463  rgba[i] = r;
1464  rgba[i + 1] = g;
1465  rgba[i + 2] = b;
1466  rgba[i + 3] = vpRGBa::alpha_default;
1467  i += 4;
1468 
1469  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1470  rgba[i] = r;
1471  rgba[i + 1] = g;
1472  rgba[i + 2] = b;
1473  rgba[i + 3] = vpRGBa::alpha_default;
1474  i += 4;
1475 
1476  j += 6;
1477  }
1478 #endif
1479 }
1480 
1489 void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1490 {
1491 
1492 #if 1
1493  // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1494  for (unsigned int i = size / 2; i; i--) {
1495  int U = (int)((*yuv++ - 128) * 0.354);
1496  int U5 = 5 * U;
1497  int Y0 = *yuv++;
1498  int V = (int)((*yuv++ - 128) * 0.707);
1499  int V2 = 2 * V;
1500  int Y1 = *yuv++;
1501  int UV = -U - V;
1502 
1503  //---
1504  int R = Y0 + V2;
1505  if ((R >> 8) > 0)
1506  R = 255;
1507  else if (R < 0)
1508  R = 0;
1509 
1510  int G = Y0 + UV;
1511  if ((G >> 8) > 0)
1512  G = 255;
1513  else if (G < 0)
1514  G = 0;
1515 
1516  int B = Y0 + U5;
1517  if ((B >> 8) > 0)
1518  B = 255;
1519  else if (B < 0)
1520  B = 0;
1521 
1522  *rgba++ = (unsigned char)R;
1523  *rgba++ = (unsigned char)G;
1524  *rgba++ = (unsigned char)B;
1525  *rgba++ = vpRGBa::alpha_default;
1526 
1527  //---
1528  R = Y1 + V2;
1529  if ((R >> 8) > 0)
1530  R = 255;
1531  else if (R < 0)
1532  R = 0;
1533 
1534  G = Y1 + UV;
1535  if ((G >> 8) > 0)
1536  G = 255;
1537  else if (G < 0)
1538  G = 0;
1539 
1540  B = Y1 + U5;
1541  if ((B >> 8) > 0)
1542  B = 255;
1543  else if (B < 0)
1544  B = 0;
1545 
1546  *rgba++ = (unsigned char)R;
1547  *rgba++ = (unsigned char)G;
1548  *rgba++ = (unsigned char)B;
1549  *rgba++ = vpRGBa::alpha_default;
1550  }
1551 
1552 #else
1553  // tres tres lent ....
1554  unsigned int i = 0, j = 0;
1555  unsigned char r, g, b;
1556 
1557  while (j < size * 2) {
1558 
1559  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1560  rgba[i] = r;
1561  rgba[i + 1] = g;
1562  rgba[i + 2] = b;
1563  rgba[i + 3] = vpRGBa::alpha_default;
1564  i += 4;
1565 
1566  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1567  rgba[i] = r;
1568  rgba[i + 1] = g;
1569  rgba[i + 2] = b;
1570  rgba[i + 3] = vpRGBa::alpha_default;
1571  i += 4;
1572  j += 4;
1573  }
1574 #endif
1575 }
1576 
1581 void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1582 {
1583  unsigned int i = 0, j = 0;
1584  while (j < size * 3 / 2) {
1585  grey[i] = yuv[j + 1];
1586  grey[i + 1] = yuv[j + 2];
1587  grey[i + 2] = yuv[j + 4];
1588  grey[i + 3] = yuv[j + 5];
1589 
1590  i += 4;
1591 
1592  j += 6;
1593  }
1594 }
1595 
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 
1691 void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1692 {
1693  unsigned int i = 0, j = 0;
1694 
1695  while (j < size * 2) {
1696  grey[i++] = yuv[j + 1];
1697  grey[i++] = yuv[j + 3];
1698  j += 4;
1699  }
1700 }
1701 
1706 void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1707 {
1708 #if 1
1709  // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1710  for (unsigned int i = size / 4; i; i--) {
1711  int U = (int)((*yuv++ - 128) * 0.354);
1712  int U5 = 5 * U;
1713  int Y0 = *yuv++;
1714  int Y1 = *yuv++;
1715  int V = (int)((*yuv++ - 128) * 0.707);
1716  int V2 = 2 * V;
1717  int Y2 = *yuv++;
1718  int Y3 = *yuv++;
1719  int UV = -U - V;
1720 
1721  // Original equations
1722  // R = Y + 1.402 V
1723  // G = Y - 0.344 U - 0.714 V
1724  // B = Y + 1.772 U
1725  int R = Y0 + V2;
1726  if ((R >> 8) > 0)
1727  R = 255;
1728  else if (R < 0)
1729  R = 0;
1730 
1731  int G = Y0 + UV;
1732  if ((G >> 8) > 0)
1733  G = 255;
1734  else if (G < 0)
1735  G = 0;
1736 
1737  int B = Y0 + U5;
1738  if ((B >> 8) > 0)
1739  B = 255;
1740  else if (B < 0)
1741  B = 0;
1742 
1743  *rgb++ = (unsigned char)R;
1744  *rgb++ = (unsigned char)G;
1745  *rgb++ = (unsigned char)B;
1746 
1747  //---
1748  R = Y1 + V2;
1749  if ((R >> 8) > 0)
1750  R = 255;
1751  else if (R < 0)
1752  R = 0;
1753 
1754  G = Y1 + UV;
1755  if ((G >> 8) > 0)
1756  G = 255;
1757  else if (G < 0)
1758  G = 0;
1759 
1760  B = Y1 + U5;
1761  if ((B >> 8) > 0)
1762  B = 255;
1763  else if (B < 0)
1764  B = 0;
1765 
1766  *rgb++ = (unsigned char)R;
1767  *rgb++ = (unsigned char)G;
1768  *rgb++ = (unsigned char)B;
1769 
1770  //---
1771  R = Y2 + V2;
1772  if ((R >> 8) > 0)
1773  R = 255;
1774  else if (R < 0)
1775  R = 0;
1776 
1777  G = Y2 + UV;
1778  if ((G >> 8) > 0)
1779  G = 255;
1780  else if (G < 0)
1781  G = 0;
1782 
1783  B = Y2 + U5;
1784  if ((B >> 8) > 0)
1785  B = 255;
1786  else if (B < 0)
1787  B = 0;
1788 
1789  *rgb++ = (unsigned char)R;
1790  *rgb++ = (unsigned char)G;
1791  *rgb++ = (unsigned char)B;
1792 
1793  //---
1794  R = Y3 + V2;
1795  if ((R >> 8) > 0)
1796  R = 255;
1797  else if (R < 0)
1798  R = 0;
1799 
1800  G = Y3 + UV;
1801  if ((G >> 8) > 0)
1802  G = 255;
1803  else if (G < 0)
1804  G = 0;
1805 
1806  B = Y3 + U5;
1807  if ((B >> 8) > 0)
1808  B = 255;
1809  else if (B < 0)
1810  B = 0;
1811 
1812  *rgb++ = (unsigned char)R;
1813  *rgb++ = (unsigned char)G;
1814  *rgb++ = (unsigned char)B;
1815  }
1816 #else
1817  // tres tres lent ....
1818 
1819  unsigned int i = 0, j = 0;
1820  unsigned char r, g, b;
1821 
1822  while (j < size * 3 / 2) {
1823  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1824  rgb[i] = r;
1825  rgb[i + 1] = g;
1826  rgb[i + 2] = b;
1827  i += 3;
1828 
1829  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1830  rgb[i] = r;
1831  rgb[i + 1] = g;
1832  rgb[i + 2] = b;
1833  i += 3;
1834 
1835  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1836  rgb[i] = r;
1837  rgb[i + 1] = g;
1838  rgb[i + 2] = b;
1839  i += 3;
1840 
1841  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1842  rgb[i] = r;
1843  rgb[i + 1] = g;
1844  rgb[i + 2] = b;
1845  i += 3;
1846  // TRACE("r= %d g=%d b=%d", r, g, b);
1847 
1848  j += 6;
1849  }
1850 #endif
1851 }
1852 
1858 void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1859 {
1860  // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
1861  int U, V, R, G, B, V2, U5, UV;
1862  int Y0, Y1, Y2, Y3;
1863  unsigned int size = width * height;
1864  unsigned char *iU = yuv + size;
1865  unsigned char *iV = yuv + 5 * size / 4;
1866  for (unsigned int i = 0; i < height / 2; i++) {
1867  for (unsigned int j = 0; j < width / 2; j++) {
1868  U = (int)((*iU++ - 128) * 0.354);
1869  U5 = 5 * U;
1870  V = (int)((*iV++ - 128) * 0.707);
1871  V2 = 2 * V;
1872  UV = -U - V;
1873  Y0 = *yuv++;
1874  Y1 = *yuv;
1875  yuv = yuv + width - 1;
1876  Y2 = *yuv++;
1877  Y3 = *yuv;
1878  yuv = yuv - width + 1;
1879 
1880  // Original equations
1881  // R = Y + 1.402 V
1882  // G = Y - 0.344 U - 0.714 V
1883  // B = Y + 1.772 U
1884  R = Y0 + V2;
1885  if ((R >> 8) > 0)
1886  R = 255;
1887  else if (R < 0)
1888  R = 0;
1889 
1890  G = Y0 + UV;
1891  if ((G >> 8) > 0)
1892  G = 255;
1893  else if (G < 0)
1894  G = 0;
1895 
1896  B = Y0 + U5;
1897  if ((B >> 8) > 0)
1898  B = 255;
1899  else if (B < 0)
1900  B = 0;
1901 
1902  *rgba++ = (unsigned char)R;
1903  *rgba++ = (unsigned char)G;
1904  *rgba++ = (unsigned char)B;
1905  *rgba++ = vpRGBa::alpha_default;
1906 
1907  //---
1908  R = Y1 + V2;
1909  if ((R >> 8) > 0)
1910  R = 255;
1911  else if (R < 0)
1912  R = 0;
1913 
1914  G = Y1 + UV;
1915  if ((G >> 8) > 0)
1916  G = 255;
1917  else if (G < 0)
1918  G = 0;
1919 
1920  B = Y1 + U5;
1921  if ((B >> 8) > 0)
1922  B = 255;
1923  else if (B < 0)
1924  B = 0;
1925 
1926  *rgba++ = (unsigned char)R;
1927  *rgba++ = (unsigned char)G;
1928  *rgba++ = (unsigned char)B;
1929  *rgba = vpRGBa::alpha_default;
1930  rgba = rgba + 4 * width - 7;
1931 
1932  //---
1933  R = Y2 + V2;
1934  if ((R >> 8) > 0)
1935  R = 255;
1936  else if (R < 0)
1937  R = 0;
1938 
1939  G = Y2 + UV;
1940  if ((G >> 8) > 0)
1941  G = 255;
1942  else if (G < 0)
1943  G = 0;
1944 
1945  B = Y2 + U5;
1946  if ((B >> 8) > 0)
1947  B = 255;
1948  else if (B < 0)
1949  B = 0;
1950 
1951  *rgba++ = (unsigned char)R;
1952  *rgba++ = (unsigned char)G;
1953  *rgba++ = (unsigned char)B;
1954  *rgba++ = vpRGBa::alpha_default;
1955 
1956  //---
1957  R = Y3 + V2;
1958  if ((R >> 8) > 0)
1959  R = 255;
1960  else if (R < 0)
1961  R = 0;
1962 
1963  G = Y3 + UV;
1964  if ((G >> 8) > 0)
1965  G = 255;
1966  else if (G < 0)
1967  G = 0;
1968 
1969  B = Y3 + U5;
1970  if ((B >> 8) > 0)
1971  B = 255;
1972  else if (B < 0)
1973  B = 0;
1974 
1975  *rgba++ = (unsigned char)R;
1976  *rgba++ = (unsigned char)G;
1977  *rgba++ = (unsigned char)B;
1978  *rgba = vpRGBa::alpha_default;
1979  rgba = rgba - 4 * width + 1;
1980  }
1981  yuv += width;
1982  rgba += 4 * width;
1983  }
1984 }
1985 
1989 void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
1990 {
1991  // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
1992  int U, V, R, G, B, V2, U5, UV;
1993  int Y0, Y1, Y2, Y3;
1994  unsigned int size = width * height;
1995  unsigned char *iU = yuv + size;
1996  unsigned char *iV = yuv + 5 * size / 4;
1997  for (unsigned int i = 0; i < height / 2; i++) {
1998  for (unsigned int j = 0; j < width / 2; j++) {
1999  U = (int)((*iU++ - 128) * 0.354);
2000  U5 = 5 * U;
2001  V = (int)((*iV++ - 128) * 0.707);
2002  V2 = 2 * V;
2003  UV = -U - V;
2004  Y0 = *yuv++;
2005  Y1 = *yuv;
2006  yuv = yuv + width - 1;
2007  Y2 = *yuv++;
2008  Y3 = *yuv;
2009  yuv = yuv - width + 1;
2010 
2011  // Original equations
2012  // R = Y + 1.402 V
2013  // G = Y - 0.344 U - 0.714 V
2014  // B = Y + 1.772 U
2015  R = Y0 + V2;
2016  if ((R >> 8) > 0)
2017  R = 255;
2018  else if (R < 0)
2019  R = 0;
2020 
2021  G = Y0 + UV;
2022  if ((G >> 8) > 0)
2023  G = 255;
2024  else if (G < 0)
2025  G = 0;
2026 
2027  B = Y0 + U5;
2028  if ((B >> 8) > 0)
2029  B = 255;
2030  else if (B < 0)
2031  B = 0;
2032 
2033  *rgb++ = (unsigned char)R;
2034  *rgb++ = (unsigned char)G;
2035  *rgb++ = (unsigned char)B;
2036 
2037  //---
2038  R = Y1 + V2;
2039  if ((R >> 8) > 0)
2040  R = 255;
2041  else if (R < 0)
2042  R = 0;
2043 
2044  G = Y1 + UV;
2045  if ((G >> 8) > 0)
2046  G = 255;
2047  else if (G < 0)
2048  G = 0;
2049 
2050  B = Y1 + U5;
2051  if ((B >> 8) > 0)
2052  B = 255;
2053  else if (B < 0)
2054  B = 0;
2055 
2056  *rgb++ = (unsigned char)R;
2057  *rgb++ = (unsigned char)G;
2058  *rgb = (unsigned char)B;
2059  rgb = rgb + 3 * width - 5;
2060 
2061  //---
2062  R = Y2 + V2;
2063  if ((R >> 8) > 0)
2064  R = 255;
2065  else if (R < 0)
2066  R = 0;
2067 
2068  G = Y2 + UV;
2069  if ((G >> 8) > 0)
2070  G = 255;
2071  else if (G < 0)
2072  G = 0;
2073 
2074  B = Y2 + U5;
2075  if ((B >> 8) > 0)
2076  B = 255;
2077  else if (B < 0)
2078  B = 0;
2079 
2080  *rgb++ = (unsigned char)R;
2081  *rgb++ = (unsigned char)G;
2082  *rgb++ = (unsigned char)B;
2083 
2084  //---
2085  R = Y3 + V2;
2086  if ((R >> 8) > 0)
2087  R = 255;
2088  else if (R < 0)
2089  R = 0;
2090 
2091  G = Y3 + UV;
2092  if ((G >> 8) > 0)
2093  G = 255;
2094  else if (G < 0)
2095  G = 0;
2096 
2097  B = Y3 + U5;
2098  if ((B >> 8) > 0)
2099  B = 255;
2100  else if (B < 0)
2101  B = 0;
2102 
2103  *rgb++ = (unsigned char)R;
2104  *rgb++ = (unsigned char)G;
2105  *rgb = (unsigned char)B;
2106  rgb = rgb - 3 * width + 1;
2107  }
2108  yuv += width;
2109  rgb += 3 * width;
2110  }
2111 }
2112 
2116 void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2117 {
2118  for (unsigned int i = 0; i < size; i++) {
2119  *grey++ = *yuv++;
2120  }
2121 }
2122 
2128 void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
2129 {
2130  for (unsigned int i = 0; i < size; i++) {
2131  int U = (int)((*yuv++ - 128) * 0.354);
2132  int U5 = 5 * U;
2133  int Y = *yuv++;
2134  int V = (int)((*yuv++ - 128) * 0.707);
2135  int V2 = 2 * V;
2136  int UV = -U - V;
2137 
2138  // Original equations
2139  // R = Y + 1.402 V
2140  // G = Y - 0.344 U - 0.714 V
2141  // B = Y + 1.772 U
2142  int R = Y + V2;
2143  if ((R >> 8) > 0)
2144  R = 255;
2145  else if (R < 0)
2146  R = 0;
2147 
2148  int G = Y + UV;
2149  if ((G >> 8) > 0)
2150  G = 255;
2151  else if (G < 0)
2152  G = 0;
2153 
2154  int B = Y + U5;
2155  if ((B >> 8) > 0)
2156  B = 255;
2157  else if (B < 0)
2158  B = 0;
2159 
2160  *rgba++ = (unsigned char)R;
2161  *rgba++ = (unsigned char)G;
2162  *rgba++ = (unsigned char)B;
2163  *rgba++ = vpRGBa::alpha_default;
2164  }
2165 }
2166 
2170 void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
2171 {
2172  for (unsigned int i = 0; i < size; i++) {
2173  int U = (int)((*yuv++ - 128) * 0.354);
2174  int U5 = 5 * U;
2175  int Y = *yuv++;
2176  int V = (int)((*yuv++ - 128) * 0.707);
2177  int V2 = 2 * V;
2178  int UV = -U - V;
2179 
2180  // Original equations
2181  // R = Y + 1.402 V
2182  // G = Y - 0.344 U - 0.714 V
2183  // B = Y + 1.772 U
2184  int R = Y + V2;
2185  if ((R >> 8) > 0)
2186  R = 255;
2187  else if (R < 0)
2188  R = 0;
2189 
2190  int G = Y + UV;
2191  if ((G >> 8) > 0)
2192  G = 255;
2193  else if (G < 0)
2194  G = 0;
2195 
2196  int B = Y + U5;
2197  if ((B >> 8) > 0)
2198  B = 255;
2199  else if (B < 0)
2200  B = 0;
2201 
2202  *rgb++ = (unsigned char)R;
2203  *rgb++ = (unsigned char)G;
2204  *rgb++ = (unsigned char)B;
2205  }
2206 }
2207 
2211 void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2212 {
2213  yuv++;
2214  for (unsigned int i = 0; i < size; i++) {
2215  *grey++ = *yuv;
2216  yuv = yuv + 3;
2217  }
2218 }
2219 
2225 void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2226 {
2227  // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
2228  int U, V, R, G, B, V2, U5, UV;
2229  int Y0, Y1, Y2, Y3;
2230  unsigned int size = width * height;
2231  unsigned char *iV = yuv + size;
2232  unsigned char *iU = yuv + 5 * size / 4;
2233  for (unsigned int i = 0; i < height / 2; i++) {
2234  for (unsigned int j = 0; j < width / 2; j++) {
2235  U = (int)((*iU++ - 128) * 0.354);
2236  U5 = 5 * U;
2237  V = (int)((*iV++ - 128) * 0.707);
2238  V2 = 2 * V;
2239  UV = -U - V;
2240  Y0 = *yuv++;
2241  Y1 = *yuv;
2242  yuv = yuv + width - 1;
2243  Y2 = *yuv++;
2244  Y3 = *yuv;
2245  yuv = yuv - width + 1;
2246 
2247  // Original equations
2248  // R = Y + 1.402 V
2249  // G = Y - 0.344 U - 0.714 V
2250  // B = Y + 1.772 U
2251  R = Y0 + V2;
2252  if ((R >> 8) > 0)
2253  R = 255;
2254  else if (R < 0)
2255  R = 0;
2256 
2257  G = Y0 + UV;
2258  if ((G >> 8) > 0)
2259  G = 255;
2260  else if (G < 0)
2261  G = 0;
2262 
2263  B = Y0 + U5;
2264  if ((B >> 8) > 0)
2265  B = 255;
2266  else if (B < 0)
2267  B = 0;
2268 
2269  *rgba++ = (unsigned char)R;
2270  *rgba++ = (unsigned char)G;
2271  *rgba++ = (unsigned char)B;
2272  *rgba++ = vpRGBa::alpha_default;
2273 
2274  //---
2275  R = Y1 + V2;
2276  if ((R >> 8) > 0)
2277  R = 255;
2278  else if (R < 0)
2279  R = 0;
2280 
2281  G = Y1 + UV;
2282  if ((G >> 8) > 0)
2283  G = 255;
2284  else if (G < 0)
2285  G = 0;
2286 
2287  B = Y1 + U5;
2288  if ((B >> 8) > 0)
2289  B = 255;
2290  else if (B < 0)
2291  B = 0;
2292 
2293  *rgba++ = (unsigned char)R;
2294  *rgba++ = (unsigned char)G;
2295  *rgba++ = (unsigned char)B;
2296  *rgba = 0;
2297  rgba = rgba + 4 * width - 7;
2298 
2299  //---
2300  R = Y2 + V2;
2301  if ((R >> 8) > 0)
2302  R = 255;
2303  else if (R < 0)
2304  R = 0;
2305 
2306  G = Y2 + UV;
2307  if ((G >> 8) > 0)
2308  G = 255;
2309  else if (G < 0)
2310  G = 0;
2311 
2312  B = Y2 + U5;
2313  if ((B >> 8) > 0)
2314  B = 255;
2315  else if (B < 0)
2316  B = 0;
2317 
2318  *rgba++ = (unsigned char)R;
2319  *rgba++ = (unsigned char)G;
2320  *rgba++ = (unsigned char)B;
2321  *rgba++ = vpRGBa::alpha_default;
2322 
2323  //---
2324  R = Y3 + V2;
2325  if ((R >> 8) > 0)
2326  R = 255;
2327  else if (R < 0)
2328  R = 0;
2329 
2330  G = Y3 + UV;
2331  if ((G >> 8) > 0)
2332  G = 255;
2333  else if (G < 0)
2334  G = 0;
2335 
2336  B = Y3 + U5;
2337  if ((B >> 8) > 0)
2338  B = 255;
2339  else if (B < 0)
2340  B = 0;
2341 
2342  *rgba++ = (unsigned char)R;
2343  *rgba++ = (unsigned char)G;
2344  *rgba++ = (unsigned char)B;
2345  *rgba = vpRGBa::alpha_default;
2346  rgba = rgba - 4 * width + 1;
2347  }
2348  yuv += width;
2349  rgba += 4 * width;
2350  }
2351 }
2352 
2356 void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2357 {
2358  // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2359  int U, V, R, G, B, V2, U5, UV;
2360  int Y0, Y1, Y2, Y3;
2361  unsigned int size = width * height;
2362  unsigned char *iV = yuv + size;
2363  unsigned char *iU = yuv + 5 * size / 4;
2364  for (unsigned int i = 0; i < height / 2; i++) {
2365  for (unsigned int j = 0; j < width / 2; j++) {
2366  U = (int)((*iU++ - 128) * 0.354);
2367  U5 = 5 * U;
2368  V = (int)((*iV++ - 128) * 0.707);
2369  V2 = 2 * V;
2370  UV = -U - V;
2371  Y0 = *yuv++;
2372  Y1 = *yuv;
2373  yuv = yuv + width - 1;
2374  Y2 = *yuv++;
2375  Y3 = *yuv;
2376  yuv = yuv - width + 1;
2377 
2378  // Original equations
2379  // R = Y + 1.402 V
2380  // G = Y - 0.344 U - 0.714 V
2381  // B = Y + 1.772 U
2382  R = Y0 + V2;
2383  if ((R >> 8) > 0)
2384  R = 255;
2385  else if (R < 0)
2386  R = 0;
2387 
2388  G = Y0 + UV;
2389  if ((G >> 8) > 0)
2390  G = 255;
2391  else if (G < 0)
2392  G = 0;
2393 
2394  B = Y0 + U5;
2395  if ((B >> 8) > 0)
2396  B = 255;
2397  else if (B < 0)
2398  B = 0;
2399 
2400  *rgb++ = (unsigned char)R;
2401  *rgb++ = (unsigned char)G;
2402  *rgb++ = (unsigned char)B;
2403 
2404  //---
2405  R = Y1 + V2;
2406  if ((R >> 8) > 0)
2407  R = 255;
2408  else if (R < 0)
2409  R = 0;
2410 
2411  G = Y1 + UV;
2412  if ((G >> 8) > 0)
2413  G = 255;
2414  else if (G < 0)
2415  G = 0;
2416 
2417  B = Y1 + U5;
2418  if ((B >> 8) > 0)
2419  B = 255;
2420  else if (B < 0)
2421  B = 0;
2422 
2423  *rgb++ = (unsigned char)R;
2424  *rgb++ = (unsigned char)G;
2425  *rgb = (unsigned char)B;
2426  rgb = rgb + 3 * width - 5;
2427 
2428  //---
2429  R = Y2 + V2;
2430  if ((R >> 8) > 0)
2431  R = 255;
2432  else if (R < 0)
2433  R = 0;
2434 
2435  G = Y2 + UV;
2436  if ((G >> 8) > 0)
2437  G = 255;
2438  else if (G < 0)
2439  G = 0;
2440 
2441  B = Y2 + U5;
2442  if ((B >> 8) > 0)
2443  B = 255;
2444  else if (B < 0)
2445  B = 0;
2446 
2447  *rgb++ = (unsigned char)R;
2448  *rgb++ = (unsigned char)G;
2449  *rgb++ = (unsigned char)B;
2450 
2451  //---
2452  R = Y3 + V2;
2453  if ((R >> 8) > 0)
2454  R = 255;
2455  else if (R < 0)
2456  R = 0;
2457 
2458  G = Y3 + UV;
2459  if ((G >> 8) > 0)
2460  G = 255;
2461  else if (G < 0)
2462  G = 0;
2463 
2464  B = Y3 + U5;
2465  if ((B >> 8) > 0)
2466  B = 255;
2467  else if (B < 0)
2468  B = 0;
2469 
2470  *rgb++ = (unsigned char)R;
2471  *rgb++ = (unsigned char)G;
2472  *rgb = (unsigned char)B;
2473  rgb = rgb - 3 * width + 1;
2474  }
2475  yuv += width;
2476  rgb += 3 * width;
2477  }
2478 }
2479 
2485 void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2486 {
2487  // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2488  int U, V, R, G, B, V2, U5, UV;
2489  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2490  unsigned int size = width * height;
2491  unsigned char *iV = yuv + size;
2492  unsigned char *iU = yuv + 17 * size / 16;
2493  for (unsigned int i = 0; i < height / 4; i++) {
2494  for (unsigned int j = 0; j < width / 4; j++) {
2495  U = (int)((*iU++ - 128) * 0.354);
2496  U5 = 5 * U;
2497  V = (int)((*iV++ - 128) * 0.707);
2498  V2 = 2 * V;
2499  UV = -U - V;
2500  Y0 = *yuv++;
2501  Y1 = *yuv++;
2502  Y2 = *yuv++;
2503  Y3 = *yuv;
2504  yuv = yuv + width - 3;
2505  Y4 = *yuv++;
2506  Y5 = *yuv++;
2507  Y6 = *yuv++;
2508  Y7 = *yuv;
2509  yuv = yuv + width - 3;
2510  Y8 = *yuv++;
2511  Y9 = *yuv++;
2512  Y10 = *yuv++;
2513  Y11 = *yuv;
2514  yuv = yuv + width - 3;
2515  Y12 = *yuv++;
2516  Y13 = *yuv++;
2517  Y14 = *yuv++;
2518  Y15 = *yuv;
2519  yuv = yuv - 3 * width + 1;
2520 
2521  // Original equations
2522  // R = Y + 1.402 V
2523  // G = Y - 0.344 U - 0.714 V
2524  // B = Y + 1.772 U
2525  R = Y0 + V2;
2526  if ((R >> 8) > 0)
2527  R = 255;
2528  else if (R < 0)
2529  R = 0;
2530 
2531  G = Y0 + UV;
2532  if ((G >> 8) > 0)
2533  G = 255;
2534  else if (G < 0)
2535  G = 0;
2536 
2537  B = Y0 + U5;
2538  if ((B >> 8) > 0)
2539  B = 255;
2540  else if (B < 0)
2541  B = 0;
2542 
2543  *rgba++ = (unsigned char)R;
2544  *rgba++ = (unsigned char)G;
2545  *rgba++ = (unsigned char)B;
2546  *rgba++ = vpRGBa::alpha_default;
2547 
2548  //---
2549  R = Y1 + V2;
2550  if ((R >> 8) > 0)
2551  R = 255;
2552  else if (R < 0)
2553  R = 0;
2554 
2555  G = Y1 + UV;
2556  if ((G >> 8) > 0)
2557  G = 255;
2558  else if (G < 0)
2559  G = 0;
2560 
2561  B = Y1 + U5;
2562  if ((B >> 8) > 0)
2563  B = 255;
2564  else if (B < 0)
2565  B = 0;
2566 
2567  *rgba++ = (unsigned char)R;
2568  *rgba++ = (unsigned char)G;
2569  *rgba++ = (unsigned char)B;
2570  *rgba++ = vpRGBa::alpha_default;
2571 
2572  //---
2573  R = Y2 + V2;
2574  if ((R >> 8) > 0)
2575  R = 255;
2576  else if (R < 0)
2577  R = 0;
2578 
2579  G = Y2 + UV;
2580  if ((G >> 8) > 0)
2581  G = 255;
2582  else if (G < 0)
2583  G = 0;
2584 
2585  B = Y2 + U5;
2586  if ((B >> 8) > 0)
2587  B = 255;
2588  else if (B < 0)
2589  B = 0;
2590 
2591  *rgba++ = (unsigned char)R;
2592  *rgba++ = (unsigned char)G;
2593  *rgba++ = (unsigned char)B;
2594  *rgba++ = vpRGBa::alpha_default;
2595 
2596  //---
2597  R = Y3 + V2;
2598  if ((R >> 8) > 0)
2599  R = 255;
2600  else if (R < 0)
2601  R = 0;
2602 
2603  G = Y3 + UV;
2604  if ((G >> 8) > 0)
2605  G = 255;
2606  else if (G < 0)
2607  G = 0;
2608 
2609  B = Y3 + U5;
2610  if ((B >> 8) > 0)
2611  B = 255;
2612  else if (B < 0)
2613  B = 0;
2614 
2615  *rgba++ = (unsigned char)R;
2616  *rgba++ = (unsigned char)G;
2617  *rgba++ = (unsigned char)B;
2618  *rgba = vpRGBa::alpha_default;
2619  rgba = rgba + 4 * width - 15;
2620 
2621  R = Y4 + V2;
2622  if ((R >> 8) > 0)
2623  R = 255;
2624  else if (R < 0)
2625  R = 0;
2626 
2627  G = Y4 + UV;
2628  if ((G >> 8) > 0)
2629  G = 255;
2630  else if (G < 0)
2631  G = 0;
2632 
2633  B = Y4 + U5;
2634  if ((B >> 8) > 0)
2635  B = 255;
2636  else if (B < 0)
2637  B = 0;
2638 
2639  *rgba++ = (unsigned char)R;
2640  *rgba++ = (unsigned char)G;
2641  *rgba++ = (unsigned char)B;
2642  *rgba++ = vpRGBa::alpha_default;
2643 
2644  //---
2645  R = Y5 + V2;
2646  if ((R >> 8) > 0)
2647  R = 255;
2648  else if (R < 0)
2649  R = 0;
2650 
2651  G = Y5 + UV;
2652  if ((G >> 8) > 0)
2653  G = 255;
2654  else if (G < 0)
2655  G = 0;
2656 
2657  B = Y5 + U5;
2658  if ((B >> 8) > 0)
2659  B = 255;
2660  else if (B < 0)
2661  B = 0;
2662 
2663  *rgba++ = (unsigned char)R;
2664  *rgba++ = (unsigned char)G;
2665  *rgba++ = (unsigned char)B;
2666  *rgba++ = vpRGBa::alpha_default;
2667 
2668  //---
2669  R = Y6 + V2;
2670  if ((R >> 8) > 0)
2671  R = 255;
2672  else if (R < 0)
2673  R = 0;
2674 
2675  G = Y6 + UV;
2676  if ((G >> 8) > 0)
2677  G = 255;
2678  else if (G < 0)
2679  G = 0;
2680 
2681  B = Y6 + U5;
2682  if ((B >> 8) > 0)
2683  B = 255;
2684  else if (B < 0)
2685  B = 0;
2686 
2687  *rgba++ = (unsigned char)R;
2688  *rgba++ = (unsigned char)G;
2689  *rgba++ = (unsigned char)B;
2690  *rgba++ = vpRGBa::alpha_default;
2691 
2692  //---
2693  R = Y7 + V2;
2694  if ((R >> 8) > 0)
2695  R = 255;
2696  else if (R < 0)
2697  R = 0;
2698 
2699  G = Y7 + UV;
2700  if ((G >> 8) > 0)
2701  G = 255;
2702  else if (G < 0)
2703  G = 0;
2704 
2705  B = Y7 + U5;
2706  if ((B >> 8) > 0)
2707  B = 255;
2708  else if (B < 0)
2709  B = 0;
2710 
2711  *rgba++ = (unsigned char)R;
2712  *rgba++ = (unsigned char)G;
2713  *rgba++ = (unsigned char)B;
2714  *rgba = vpRGBa::alpha_default;
2715  rgba = rgba + 4 * width - 15;
2716 
2717  R = Y8 + V2;
2718  if ((R >> 8) > 0)
2719  R = 255;
2720  else if (R < 0)
2721  R = 0;
2722 
2723  G = Y8 + UV;
2724  if ((G >> 8) > 0)
2725  G = 255;
2726  else if (G < 0)
2727  G = 0;
2728 
2729  B = Y8 + U5;
2730  if ((B >> 8) > 0)
2731  B = 255;
2732  else if (B < 0)
2733  B = 0;
2734 
2735  *rgba++ = (unsigned char)R;
2736  *rgba++ = (unsigned char)G;
2737  *rgba++ = (unsigned char)B;
2738  *rgba++ = vpRGBa::alpha_default;
2739 
2740  //---
2741  R = Y9 + V2;
2742  if ((R >> 8) > 0)
2743  R = 255;
2744  else if (R < 0)
2745  R = 0;
2746 
2747  G = Y9 + UV;
2748  if ((G >> 8) > 0)
2749  G = 255;
2750  else if (G < 0)
2751  G = 0;
2752 
2753  B = Y9 + U5;
2754  if ((B >> 8) > 0)
2755  B = 255;
2756  else if (B < 0)
2757  B = 0;
2758 
2759  *rgba++ = (unsigned char)R;
2760  *rgba++ = (unsigned char)G;
2761  *rgba++ = (unsigned char)B;
2762  *rgba++ = vpRGBa::alpha_default;
2763 
2764  //---
2765  R = Y10 + V2;
2766  if ((R >> 8) > 0)
2767  R = 255;
2768  else if (R < 0)
2769  R = 0;
2770 
2771  G = Y10 + UV;
2772  if ((G >> 8) > 0)
2773  G = 255;
2774  else if (G < 0)
2775  G = 0;
2776 
2777  B = Y10 + U5;
2778  if ((B >> 8) > 0)
2779  B = 255;
2780  else if (B < 0)
2781  B = 0;
2782 
2783  *rgba++ = (unsigned char)R;
2784  *rgba++ = (unsigned char)G;
2785  *rgba++ = (unsigned char)B;
2786  *rgba++ = vpRGBa::alpha_default;
2787 
2788  //---
2789  R = Y11 + V2;
2790  if ((R >> 8) > 0)
2791  R = 255;
2792  else if (R < 0)
2793  R = 0;
2794 
2795  G = Y11 + UV;
2796  if ((G >> 8) > 0)
2797  G = 255;
2798  else if (G < 0)
2799  G = 0;
2800 
2801  B = Y11 + U5;
2802  if ((B >> 8) > 0)
2803  B = 255;
2804  else if (B < 0)
2805  B = 0;
2806 
2807  *rgba++ = (unsigned char)R;
2808  *rgba++ = (unsigned char)G;
2809  *rgba++ = (unsigned char)B;
2810  *rgba = vpRGBa::alpha_default;
2811  rgba = rgba + 4 * width - 15;
2812 
2813  R = Y12 + V2;
2814  if ((R >> 8) > 0)
2815  R = 255;
2816  else if (R < 0)
2817  R = 0;
2818 
2819  G = Y12 + UV;
2820  if ((G >> 8) > 0)
2821  G = 255;
2822  else if (G < 0)
2823  G = 0;
2824 
2825  B = Y12 + U5;
2826  if ((B >> 8) > 0)
2827  B = 255;
2828  else if (B < 0)
2829  B = 0;
2830 
2831  *rgba++ = (unsigned char)R;
2832  *rgba++ = (unsigned char)G;
2833  *rgba++ = (unsigned char)B;
2834  *rgba++ = vpRGBa::alpha_default;
2835 
2836  //---
2837  R = Y13 + V2;
2838  if ((R >> 8) > 0)
2839  R = 255;
2840  else if (R < 0)
2841  R = 0;
2842 
2843  G = Y13 + UV;
2844  if ((G >> 8) > 0)
2845  G = 255;
2846  else if (G < 0)
2847  G = 0;
2848 
2849  B = Y13 + U5;
2850  if ((B >> 8) > 0)
2851  B = 255;
2852  else if (B < 0)
2853  B = 0;
2854 
2855  *rgba++ = (unsigned char)R;
2856  *rgba++ = (unsigned char)G;
2857  *rgba++ = (unsigned char)B;
2858  *rgba++ = vpRGBa::alpha_default;
2859 
2860  //---
2861  R = Y14 + V2;
2862  if ((R >> 8) > 0)
2863  R = 255;
2864  else if (R < 0)
2865  R = 0;
2866 
2867  G = Y14 + UV;
2868  if ((G >> 8) > 0)
2869  G = 255;
2870  else if (G < 0)
2871  G = 0;
2872 
2873  B = Y14 + U5;
2874  if ((B >> 8) > 0)
2875  B = 255;
2876  else if (B < 0)
2877  B = 0;
2878 
2879  *rgba++ = (unsigned char)R;
2880  *rgba++ = (unsigned char)G;
2881  *rgba++ = (unsigned char)B;
2882  *rgba++ = vpRGBa::alpha_default;
2883 
2884  //---
2885  R = Y15 + V2;
2886  if ((R >> 8) > 0)
2887  R = 255;
2888  else if (R < 0)
2889  R = 0;
2890 
2891  G = Y15 + UV;
2892  if ((G >> 8) > 0)
2893  G = 255;
2894  else if (G < 0)
2895  G = 0;
2896 
2897  B = Y15 + U5;
2898  if ((B >> 8) > 0)
2899  B = 255;
2900  else if (B < 0)
2901  B = 0;
2902 
2903  *rgba++ = (unsigned char)R;
2904  *rgba++ = (unsigned char)G;
2905  *rgba++ = (unsigned char)B;
2906  *rgba = vpRGBa::alpha_default;
2907  rgba = rgba - 12 * width + 1;
2908  }
2909  yuv += 3 * width;
2910  rgba += 12 * width;
2911  }
2912 }
2913 
2917 void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2918 {
2919  // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
2920  int U, V, R, G, B, V2, U5, UV;
2921  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2922  unsigned int size = width * height;
2923  unsigned char *iV = yuv + size;
2924  unsigned char *iU = yuv + 17 * size / 16;
2925  for (unsigned int i = 0; i < height / 4; i++) {
2926  for (unsigned int j = 0; j < width / 4; j++) {
2927  U = (int)((*iU++ - 128) * 0.354);
2928  U5 = 5 * U;
2929  V = (int)((*iV++ - 128) * 0.707);
2930  V2 = 2 * V;
2931  UV = -U - V;
2932  Y0 = *yuv++;
2933  Y1 = *yuv++;
2934  Y2 = *yuv++;
2935  Y3 = *yuv;
2936  yuv = yuv + width - 3;
2937  Y4 = *yuv++;
2938  Y5 = *yuv++;
2939  Y6 = *yuv++;
2940  Y7 = *yuv;
2941  yuv = yuv + width - 3;
2942  Y8 = *yuv++;
2943  Y9 = *yuv++;
2944  Y10 = *yuv++;
2945  Y11 = *yuv;
2946  yuv = yuv + width - 3;
2947  Y12 = *yuv++;
2948  Y13 = *yuv++;
2949  Y14 = *yuv++;
2950  Y15 = *yuv;
2951  yuv = yuv - 3 * width + 1;
2952 
2953  // Original equations
2954  // R = Y + 1.402 V
2955  // G = Y - 0.344 U - 0.714 V
2956  // B = Y + 1.772 U
2957  R = Y0 + V2;
2958  if ((R >> 8) > 0)
2959  R = 255;
2960  else if (R < 0)
2961  R = 0;
2962 
2963  G = Y0 + UV;
2964  if ((G >> 8) > 0)
2965  G = 255;
2966  else if (G < 0)
2967  G = 0;
2968 
2969  B = Y0 + U5;
2970  if ((B >> 8) > 0)
2971  B = 255;
2972  else if (B < 0)
2973  B = 0;
2974 
2975  *rgb++ = (unsigned char)R;
2976  *rgb++ = (unsigned char)G;
2977  *rgb++ = (unsigned char)B;
2978 
2979  //---
2980  R = Y1 + V2;
2981  if ((R >> 8) > 0)
2982  R = 255;
2983  else if (R < 0)
2984  R = 0;
2985 
2986  G = Y1 + UV;
2987  if ((G >> 8) > 0)
2988  G = 255;
2989  else if (G < 0)
2990  G = 0;
2991 
2992  B = Y1 + U5;
2993  if ((B >> 8) > 0)
2994  B = 255;
2995  else if (B < 0)
2996  B = 0;
2997 
2998  *rgb++ = (unsigned char)R;
2999  *rgb++ = (unsigned char)G;
3000  *rgb++ = (unsigned char)B;
3001 
3002  //---
3003  R = Y2 + V2;
3004  if ((R >> 8) > 0)
3005  R = 255;
3006  else if (R < 0)
3007  R = 0;
3008 
3009  G = Y2 + UV;
3010  if ((G >> 8) > 0)
3011  G = 255;
3012  else if (G < 0)
3013  G = 0;
3014 
3015  B = Y2 + U5;
3016  if ((B >> 8) > 0)
3017  B = 255;
3018  else if (B < 0)
3019  B = 0;
3020 
3021  *rgb++ = (unsigned char)R;
3022  *rgb++ = (unsigned char)G;
3023  *rgb++ = (unsigned char)B;
3024 
3025  //---
3026  R = Y3 + V2;
3027  if ((R >> 8) > 0)
3028  R = 255;
3029  else if (R < 0)
3030  R = 0;
3031 
3032  G = Y3 + UV;
3033  if ((G >> 8) > 0)
3034  G = 255;
3035  else if (G < 0)
3036  G = 0;
3037 
3038  B = Y3 + U5;
3039  if ((B >> 8) > 0)
3040  B = 255;
3041  else if (B < 0)
3042  B = 0;
3043 
3044  *rgb++ = (unsigned char)R;
3045  *rgb++ = (unsigned char)G;
3046  *rgb = (unsigned char)B;
3047  rgb = rgb + 3 * width - 11;
3048 
3049  R = Y4 + V2;
3050  if ((R >> 8) > 0)
3051  R = 255;
3052  else if (R < 0)
3053  R = 0;
3054 
3055  G = Y4 + UV;
3056  if ((G >> 8) > 0)
3057  G = 255;
3058  else if (G < 0)
3059  G = 0;
3060 
3061  B = Y4 + U5;
3062  if ((B >> 8) > 0)
3063  B = 255;
3064  else if (B < 0)
3065  B = 0;
3066 
3067  *rgb++ = (unsigned char)R;
3068  *rgb++ = (unsigned char)G;
3069  *rgb++ = (unsigned char)B;
3070 
3071  //---
3072  R = Y5 + V2;
3073  if ((R >> 8) > 0)
3074  R = 255;
3075  else if (R < 0)
3076  R = 0;
3077 
3078  G = Y5 + UV;
3079  if ((G >> 8) > 0)
3080  G = 255;
3081  else if (G < 0)
3082  G = 0;
3083 
3084  B = Y5 + U5;
3085  if ((B >> 8) > 0)
3086  B = 255;
3087  else if (B < 0)
3088  B = 0;
3089 
3090  *rgb++ = (unsigned char)R;
3091  *rgb++ = (unsigned char)G;
3092  *rgb++ = (unsigned char)B;
3093 
3094  //---
3095  R = Y6 + V2;
3096  if ((R >> 8) > 0)
3097  R = 255;
3098  else if (R < 0)
3099  R = 0;
3100 
3101  G = Y6 + UV;
3102  if ((G >> 8) > 0)
3103  G = 255;
3104  else if (G < 0)
3105  G = 0;
3106 
3107  B = Y6 + U5;
3108  if ((B >> 8) > 0)
3109  B = 255;
3110  else if (B < 0)
3111  B = 0;
3112 
3113  *rgb++ = (unsigned char)R;
3114  *rgb++ = (unsigned char)G;
3115  *rgb++ = (unsigned char)B;
3116 
3117  //---
3118  R = Y7 + V2;
3119  if ((R >> 8) > 0)
3120  R = 255;
3121  else if (R < 0)
3122  R = 0;
3123 
3124  G = Y7 + UV;
3125  if ((G >> 8) > 0)
3126  G = 255;
3127  else if (G < 0)
3128  G = 0;
3129 
3130  B = Y7 + U5;
3131  if ((B >> 8) > 0)
3132  B = 255;
3133  else if (B < 0)
3134  B = 0;
3135 
3136  *rgb++ = (unsigned char)R;
3137  *rgb++ = (unsigned char)G;
3138  *rgb = (unsigned char)B;
3139  rgb = rgb + 3 * width - 11;
3140 
3141  R = Y8 + V2;
3142  if ((R >> 8) > 0)
3143  R = 255;
3144  else if (R < 0)
3145  R = 0;
3146 
3147  G = Y8 + UV;
3148  if ((G >> 8) > 0)
3149  G = 255;
3150  else if (G < 0)
3151  G = 0;
3152 
3153  B = Y8 + U5;
3154  if ((B >> 8) > 0)
3155  B = 255;
3156  else if (B < 0)
3157  B = 0;
3158 
3159  *rgb++ = (unsigned char)R;
3160  *rgb++ = (unsigned char)G;
3161  *rgb++ = (unsigned char)B;
3162 
3163  //---
3164  R = Y9 + V2;
3165  if ((R >> 8) > 0)
3166  R = 255;
3167  else if (R < 0)
3168  R = 0;
3169 
3170  G = Y9 + UV;
3171  if ((G >> 8) > 0)
3172  G = 255;
3173  else if (G < 0)
3174  G = 0;
3175 
3176  B = Y9 + U5;
3177  if ((B >> 8) > 0)
3178  B = 255;
3179  else if (B < 0)
3180  B = 0;
3181 
3182  *rgb++ = (unsigned char)R;
3183  *rgb++ = (unsigned char)G;
3184  *rgb++ = (unsigned char)B;
3185 
3186  //---
3187  R = Y10 + V2;
3188  if ((R >> 8) > 0)
3189  R = 255;
3190  else if (R < 0)
3191  R = 0;
3192 
3193  G = Y10 + UV;
3194  if ((G >> 8) > 0)
3195  G = 255;
3196  else if (G < 0)
3197  G = 0;
3198 
3199  B = Y10 + U5;
3200  if ((B >> 8) > 0)
3201  B = 255;
3202  else if (B < 0)
3203  B = 0;
3204 
3205  *rgb++ = (unsigned char)R;
3206  *rgb++ = (unsigned char)G;
3207  *rgb++ = (unsigned char)B;
3208 
3209  //---
3210  R = Y11 + V2;
3211  if ((R >> 8) > 0)
3212  R = 255;
3213  else if (R < 0)
3214  R = 0;
3215 
3216  G = Y11 + UV;
3217  if ((G >> 8) > 0)
3218  G = 255;
3219  else if (G < 0)
3220  G = 0;
3221 
3222  B = Y11 + U5;
3223  if ((B >> 8) > 0)
3224  B = 255;
3225  else if (B < 0)
3226  B = 0;
3227 
3228  *rgb++ = (unsigned char)R;
3229  *rgb++ = (unsigned char)G;
3230  *rgb = (unsigned char)B;
3231  rgb = rgb + 3 * width - 11;
3232 
3233  R = Y12 + V2;
3234  if ((R >> 8) > 0)
3235  R = 255;
3236  else if (R < 0)
3237  R = 0;
3238 
3239  G = Y12 + UV;
3240  if ((G >> 8) > 0)
3241  G = 255;
3242  else if (G < 0)
3243  G = 0;
3244 
3245  B = Y12 + U5;
3246  if ((B >> 8) > 0)
3247  B = 255;
3248  else if (B < 0)
3249  B = 0;
3250 
3251  *rgb++ = (unsigned char)R;
3252  *rgb++ = (unsigned char)G;
3253  *rgb++ = (unsigned char)B;
3254 
3255  //---
3256  R = Y13 + V2;
3257  if ((R >> 8) > 0)
3258  R = 255;
3259  else if (R < 0)
3260  R = 0;
3261 
3262  G = Y13 + UV;
3263  if ((G >> 8) > 0)
3264  G = 255;
3265  else if (G < 0)
3266  G = 0;
3267 
3268  B = Y13 + U5;
3269  if ((B >> 8) > 0)
3270  B = 255;
3271  else if (B < 0)
3272  B = 0;
3273 
3274  *rgb++ = (unsigned char)R;
3275  *rgb++ = (unsigned char)G;
3276  *rgb++ = (unsigned char)B;
3277 
3278  //---
3279  R = Y14 + V2;
3280  if ((R >> 8) > 0)
3281  R = 255;
3282  else if (R < 0)
3283  R = 0;
3284 
3285  G = Y14 + UV;
3286  if ((G >> 8) > 0)
3287  G = 255;
3288  else if (G < 0)
3289  G = 0;
3290 
3291  B = Y14 + U5;
3292  if ((B >> 8) > 0)
3293  B = 255;
3294  else if (B < 0)
3295  B = 0;
3296 
3297  *rgb++ = (unsigned char)R;
3298  *rgb++ = (unsigned char)G;
3299  *rgb++ = (unsigned char)B;
3300 
3301  //---
3302  R = Y15 + V2;
3303  if ((R >> 8) > 0)
3304  R = 255;
3305  else if (R < 0)
3306  R = 0;
3307 
3308  G = Y15 + UV;
3309  if ((G >> 8) > 0)
3310  G = 255;
3311  else if (G < 0)
3312  G = 0;
3313 
3314  B = Y15 + U5;
3315  if ((B >> 8) > 0)
3316  B = 255;
3317  else if (B < 0)
3318  B = 0;
3319 
3320  *rgb++ = (unsigned char)R;
3321  *rgb++ = (unsigned char)G;
3322  *rgb++ = (unsigned char)B;
3323  rgb = rgb - 9 * width + 1;
3324  }
3325  yuv += 3 * width;
3326  rgb += 9 * width;
3327  }
3328 }
3329 
3335 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
3336 {
3337  RGBToRGBa(rgb, rgba, size, 1, false);
3338 }
3339 
3349 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int width, unsigned int height,
3350  bool flip)
3351 {
3352  if (!flip) {
3353  SimdBgrToBgra(rgb, width, height, width * 3, rgba, width * 4, vpRGBa::alpha_default);
3354  } else {
3355  // if we have to flip the image, we start from the end last scanline so the
3356  // step is negative
3357  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3358 
3359  // starting source address = last line if we need to flip the image
3360  unsigned char *src = (flip) ? (rgb + (width * height * 3) + lineStep) : rgb;
3361 
3362  unsigned int j = 0;
3363  unsigned int i = 0;
3364 
3365  for (i = 0; i < height; i++) {
3366  unsigned char *line = src;
3367  for (j = 0; j < width; j++) {
3368  *rgba++ = *(line++);
3369  *rgba++ = *(line++);
3370  *rgba++ = *(line++);
3371  *rgba++ = vpRGBa::alpha_default;
3372  }
3373  // go to the next line
3374  src += lineStep;
3375  }
3376  }
3377 }
3378 
3386 void vpImageConvert::RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
3387 {
3388  SimdBgraToBgr(rgba, size, 1, size * 4, rgb, size * 3);
3389 }
3390 
3396 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
3397 {
3398  RGBToGrey(rgb, grey, size, 1, false);
3399 }
3400 
3408 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height,
3409  bool flip)
3410 {
3411  if (!flip) {
3412  SimdRgbToGray(rgb, width, height, width * 3, grey, width);
3413  } else {
3414  // if we have to flip the image, we start from the end last scanline so
3415  // the step is negative
3416  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3417 
3418  // starting source address = last line if we need to flip the image
3419  unsigned char *src = (flip) ? rgb + (width * height * 3) + lineStep : rgb;
3420 
3421  unsigned int j = 0;
3422  unsigned int i = 0;
3423 
3424  unsigned r, g, b;
3425 
3426  for (i = 0; i < height; i++) {
3427  unsigned char *line = src;
3428  for (j = 0; j < width; j++) {
3429  r = *(line++);
3430  g = *(line++);
3431  b = *(line++);
3432  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3433  }
3434 
3435  // go to the next line
3436  src += lineStep;
3437  }
3438  }
3439 }
3440 
3448 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height, unsigned int
3449  #if defined _OPENMP
3450  nThreads
3451  #endif
3452  )
3453 {
3454 #if defined _OPENMP
3455  if (nThreads > 0) {
3456  omp_set_num_threads(static_cast<int>(nThreads));
3457  }
3458  #pragma omp parallel for
3459 #endif
3460  for (int i = 0; i < static_cast<int>(height); i++) {
3461  SimdRgbaToGray(rgba + i*width*4, width, 1, width*4, grey + i*width, width);
3462  }
3463 }
3464 
3472 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
3473 {
3474  SimdRgbaToGray(rgba, size, 1, size*4, grey, size);
3475 }
3476 
3483 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
3484 {
3485  SimdGrayToBgra(grey, width, height, width, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3486 }
3487 
3494 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
3495 {
3496  GreyToRGBa(grey, rgba, size, 1);
3497 }
3498 
3504 void vpImageConvert::GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
3505 {
3506  SimdGrayToBgr(grey, size, 1, size, rgb, size * 3);
3507 }
3508 
3518 void vpImageConvert::BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height,
3519  bool flip)
3520 {
3521  if (!flip) {
3522  SimdBgrToRgba(bgr, width, height, width*3, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3523  } else {
3524  // if we have to flip the image, we start from the end last scanline so the
3525  // step is negative
3526  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3527 
3528  // starting source address = last line if we need to flip the image
3529  unsigned char *src = (flip) ? (bgr + (width * height * 3) + lineStep) : bgr;
3530 
3531  for (unsigned int i = 0; i < height; i++) {
3532  unsigned char *line = src;
3533  for (unsigned int j = 0; j < width; j++) {
3534  *rgba++ = *(line + 2);
3535  *rgba++ = *(line + 1);
3536  *rgba++ = *(line + 0);
3537  *rgba++ = vpRGBa::alpha_default;
3538 
3539  line += 3;
3540  }
3541  // go to the next line
3542  src += lineStep;
3543  }
3544  }
3545 }
3546 
3555 void vpImageConvert::BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height,
3556  bool flip)
3557 {
3558  if (!flip) {
3559  SimdBgraToRgba(bgra, width, height, width*4, rgba, width * 4);
3560  } else {
3561  // if we have to flip the image, we start from the end last scanline so the
3562  // step is negative
3563  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3564 
3565  // starting source address = last line if we need to flip the image
3566  unsigned char *src = (flip) ? (bgra + (width * height * 4) + lineStep) : bgra;
3567 
3568  for (unsigned int i = 0; i < height; i++) {
3569  unsigned char *line = src;
3570  for (unsigned int j = 0; j < width; j++) {
3571  *rgba++ = *(line + 2);
3572  *rgba++ = *(line + 1);
3573  *rgba++ = *(line + 0);
3574  *rgba++ = *(line + 3);
3575 
3576  line += 4;
3577  }
3578  // go to the next line
3579  src += lineStep;
3580  }
3581  }
3582 }
3583 
3591 void vpImageConvert::BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height,
3592  bool flip, unsigned int
3593  #if defined _OPENMP
3594  nThreads
3595  #endif
3596  )
3597 {
3598  if (!flip) {
3599 #if defined _OPENMP
3600  if (nThreads > 0) {
3601  omp_set_num_threads(static_cast<int>(nThreads));
3602  }
3603 #pragma omp parallel for
3604 #endif
3605  for (int i = 0; i < static_cast<int>(height); i++) {
3606  SimdBgrToGray(bgr + i*width*3, width, 1, width * 3, grey + i*width, width);
3607  }
3608  } else {
3609  // if we have to flip the image, we start from the end last scanline so
3610  // the step is negative
3611  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3612 
3613  // starting source address = last line if we need to flip the image
3614  unsigned char *src = (flip) ? bgr + (width * height * 3) + lineStep : bgr;
3615 
3616  for (unsigned int i = 0; i < height; i++) {
3617  unsigned char *line = src;
3618  for (unsigned int j = 0; j < width; j++) {
3619  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3620  line += 3;
3621  }
3622 
3623  // go to the next line
3624  src += lineStep;
3625  }
3626  }
3627 }
3628 
3636 void vpImageConvert::BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height,
3637  bool flip, unsigned int
3638  #if defined _OPENMP
3639  nThreads
3640  #endif
3641  )
3642 {
3643  if (!flip) {
3644 #if defined _OPENMP
3645  if (nThreads > 0) {
3646  omp_set_num_threads(static_cast<int>(nThreads));
3647  }
3648 #pragma omp parallel for
3649 #endif
3650  for (int i = 0; i < static_cast<int>(height); i++) {
3651  SimdBgraToGray(bgra + i*width*4, width, 1, width * 4, grey + i*width, width);
3652  }
3653  } else {
3654  // if we have to flip the image, we start from the end last scanline so
3655  // the step is negative
3656  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3657 
3658  // starting source address = last line if we need to flip the image
3659  unsigned char *src = (flip) ? bgra + (width * height * 4) + lineStep : bgra;
3660 
3661  for (unsigned int i = 0; i < height; i++) {
3662  unsigned char *line = src;
3663  for (unsigned int j = 0; j < width; j++) {
3664  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3665  line += 4;
3666  }
3667 
3668  // go to the next line
3669  src += lineStep;
3670  }
3671  }
3672 }
3673 
3677 void vpImageConvert::computeYCbCrLUT()
3678 {
3679  if (YCbCrLUTcomputed == false) {
3680  int index = 256;
3681 
3682  while (index--) {
3683 
3684  int aux = index - 128;
3685  vpImageConvert::vpCrr[index] = (int)(364.6610 * aux) >> 8;
3686  vpImageConvert::vpCgb[index] = (int)(-89.8779 * aux) >> 8;
3687  vpImageConvert::vpCgr[index] = (int)(-185.8154 * aux) >> 8;
3688  vpImageConvert::vpCbb[index] = (int)(460.5724 * aux) >> 8;
3689  }
3690 
3691  YCbCrLUTcomputed = true;
3692  }
3693 }
3694 
3711 void vpImageConvert::YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
3712 {
3713  unsigned char *cbv;
3714  unsigned char *crv;
3715  unsigned char *pt_ycbcr = ycbcr;
3716  unsigned char *pt_rgb = rgb;
3717  cbv = pt_ycbcr + 1;
3718  crv = pt_ycbcr + 3;
3719 
3720  vpImageConvert::computeYCbCrLUT();
3721 
3722  int col = 0;
3723 
3724  while (size--) {
3725  int val_r, val_g, val_b;
3726  if (!(col++ % 2)) {
3727  cbv = pt_ycbcr + 1;
3728  crv = pt_ycbcr + 3;
3729  }
3730 
3731  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3732  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3733  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3734 
3735  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3736 
3737  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3738  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3739  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3740 
3741  pt_ycbcr += 2;
3742  }
3743 }
3744 
3765 void vpImageConvert::YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgba, unsigned int size)
3766 {
3767  unsigned char *cbv;
3768  unsigned char *crv;
3769  unsigned char *pt_ycbcr = ycbcr;
3770  unsigned char *pt_rgba = rgba;
3771  cbv = pt_ycbcr + 1;
3772  crv = pt_ycbcr + 3;
3773 
3774  vpImageConvert::computeYCbCrLUT();
3775 
3776  int col = 0;
3777 
3778  while (size--) {
3779  int val_r, val_g, val_b;
3780  if (!(col++ % 2)) {
3781  cbv = pt_ycbcr + 1;
3782  crv = pt_ycbcr + 3;
3783  }
3784 
3785  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3786  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3787  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3788 
3789  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3790 
3791  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3792  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3793  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3794  *pt_rgba++ = vpRGBa::alpha_default;
3795 
3796  pt_ycbcr += 2;
3797  }
3798 }
3799 
3814 void vpImageConvert::YCbCrToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
3815 {
3816  unsigned int i = 0, j = 0;
3817 
3818  while (j < size * 2) {
3819  grey[i++] = yuv[j];
3820  grey[i++] = yuv[j + 2];
3821  j += 4;
3822  }
3823 }
3824 
3841 void vpImageConvert::YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
3842 {
3843  unsigned char *cbv;
3844  unsigned char *crv;
3845  unsigned char *pt_ycbcr = ycrcb;
3846  unsigned char *pt_rgb = rgb;
3847  crv = pt_ycbcr + 1;
3848  cbv = pt_ycbcr + 3;
3849 
3850  vpImageConvert::computeYCbCrLUT();
3851 
3852  int col = 0;
3853 
3854  while (size--) {
3855  int val_r, val_g, val_b;
3856  if (!(col++ % 2)) {
3857  crv = pt_ycbcr + 1;
3858  cbv = pt_ycbcr + 3;
3859  }
3860 
3861  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3862  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3863  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3864 
3865  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3866 
3867  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3868  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3869  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3870 
3871  pt_ycbcr += 2;
3872  }
3873 }
3874 
3894 void vpImageConvert::YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgba, unsigned int size)
3895 {
3896  unsigned char *cbv;
3897  unsigned char *crv;
3898  unsigned char *pt_ycbcr = ycrcb;
3899  unsigned char *pt_rgba = rgba;
3900  crv = pt_ycbcr + 1;
3901  cbv = pt_ycbcr + 3;
3902 
3903  vpImageConvert::computeYCbCrLUT();
3904 
3905  int col = 0;
3906 
3907  while (size--) {
3908  int val_r, val_g, val_b;
3909  if (!(col++ % 2)) {
3910  crv = pt_ycbcr + 1;
3911  cbv = pt_ycbcr + 3;
3912  }
3913 
3914  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3915  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3916  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3917 
3918  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3919 
3920  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3921  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3922  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3923  *pt_rgba++ = vpRGBa::alpha_default;
3924 
3925  pt_ycbcr += 2;
3926  }
3927 }
3928 
3967 {
3968  if (src.getSize() > 0) {
3969  if (pR) {
3970  pR->resize(src.getHeight(), src.getWidth());
3971  }
3972  if (pG) {
3973  pG->resize(src.getHeight(), src.getWidth());
3974  }
3975  if (pB) {
3976  pB->resize(src.getHeight(), src.getWidth());
3977  }
3978  if (pa) {
3979  pa->resize(src.getHeight(), src.getWidth());
3980  }
3981 
3982  unsigned char *ptrR = pR ? pR->bitmap : new unsigned char[src.getSize()];
3983  unsigned char *ptrG = pG ? pG->bitmap : new unsigned char[src.getSize()];
3984  unsigned char *ptrB = pB ? pB->bitmap : new unsigned char[src.getSize()];
3985  unsigned char *ptrA = pa ? pa->bitmap : new unsigned char[src.getSize()];
3986 
3987  SimdDeinterleaveBgra(reinterpret_cast<unsigned char*>(src.bitmap), src.getWidth()*sizeof(vpRGBa),
3988  src.getWidth(), src.getHeight(),
3989  ptrR, src.getWidth(),
3990  ptrG, src.getWidth(),
3991  ptrB, src.getWidth(),
3992  ptrA, src.getWidth());
3993 
3994  if (!pR) {
3995  delete[] ptrR;
3996  }
3997  if (!pG) {
3998  delete[] ptrG;
3999  }
4000  if (!pB) {
4001  delete[] ptrB;
4002  }
4003  if (!pa) {
4004  delete[] ptrA;
4005  }
4006  }
4007 }
4008 
4021 {
4022  // Check if the input channels have all the same dimensions
4023  std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
4024  if (R != NULL) {
4025  mapOfWidths[R->getWidth()]++;
4026  mapOfHeights[R->getHeight()]++;
4027  }
4028 
4029  if (G != NULL) {
4030  mapOfWidths[G->getWidth()]++;
4031  mapOfHeights[G->getHeight()]++;
4032  }
4033 
4034  if (B != NULL) {
4035  mapOfWidths[B->getWidth()]++;
4036  mapOfHeights[B->getHeight()]++;
4037  }
4038 
4039  if (a != NULL) {
4040  mapOfWidths[a->getWidth()]++;
4041  mapOfHeights[a->getHeight()]++;
4042  }
4043 
4044  if (mapOfWidths.size() == 1 && mapOfHeights.size() == 1) {
4045  unsigned int width = mapOfWidths.begin()->first;
4046  unsigned int height = mapOfHeights.begin()->first;
4047 
4048  RGBa.resize(height, width);
4049 
4050  if (R != NULL && G != NULL && B != NULL && a != NULL) {
4051  SimdInterleaveBgra(R->bitmap, width, G->bitmap, width, B->bitmap, width,
4052  a->bitmap, width, width, height, reinterpret_cast<uint8_t *>(RGBa.bitmap),
4053  width*sizeof(vpRGBa));
4054  } else {
4055  unsigned int size = width * height;
4056  for (unsigned int i = 0; i < size; i++) {
4057  if (R != NULL) {
4058  RGBa.bitmap[i].R = R->bitmap[i];
4059  }
4060 
4061  if (G != NULL) {
4062  RGBa.bitmap[i].G = G->bitmap[i];
4063  }
4064 
4065  if (B != NULL) {
4066  RGBa.bitmap[i].B = B->bitmap[i];
4067  }
4068 
4069  if (a != NULL) {
4070  RGBa.bitmap[i].A = a->bitmap[i];
4071  }
4072  }
4073  }
4074  } else {
4075  throw vpException(vpException::dimensionError, "Mismatched dimensions!");
4076  }
4077 }
4078 
4087 void vpImageConvert::MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
4088 {
4089  int i = (((int)size) << 1) - 1;
4090  int j = (int)size - 1;
4091 
4092  while (i >= 0) {
4093  int y = grey16[i--];
4094  grey[j--] = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4095  }
4096 }
4097 
4108 void vpImageConvert::MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
4109 {
4110  int i = (((int)size) << 1) - 1;
4111  int j = (int)(size * 4 - 1);
4112 
4113  while (i >= 0) {
4114  int y = grey16[i--];
4115  unsigned char v = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4116  rgba[j--] = vpRGBa::alpha_default;
4117  rgba[j--] = v;
4118  rgba[j--] = v;
4119  rgba[j--] = v;
4120  }
4121 }
4122 
4123 void vpImageConvert::HSV2RGB(const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
4124  unsigned int size, unsigned int step)
4125 {
4126  for (unsigned int i = 0; i < size; i++) {
4127  double hue = hue_[i], saturation = saturation_[i], value = value_[i];
4128 
4129  if (vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
4130  hue = value;
4131  saturation = value;
4132  } else {
4133  double h = hue * 6.0;
4134  double s = saturation;
4135  double v = value;
4136 
4137  if (vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
4138  h = 0.0;
4139  }
4140 
4141  double f = h - (int)h;
4142  double p = v * (1.0 - s);
4143  double q = v * (1.0 - s * f);
4144  double t = v * (1.0 - s * (1.0 - f));
4145 
4146  switch ((int)h) {
4147  case 0:
4148  hue = v;
4149  saturation = t;
4150  value = p;
4151  break;
4152 
4153  case 1:
4154  hue = q;
4155  saturation = v;
4156  value = p;
4157  break;
4158 
4159  case 2:
4160  hue = p;
4161  saturation = v;
4162  value = t;
4163  break;
4164 
4165  case 3:
4166  hue = p;
4167  saturation = q;
4168  value = v;
4169  break;
4170 
4171  case 4:
4172  hue = t;
4173  saturation = p;
4174  value = v;
4175  break;
4176 
4177  default: // case 5:
4178  hue = v;
4179  saturation = p;
4180  value = q;
4181  break;
4182  }
4183  }
4184 
4185  rgb[i * step] = (unsigned char)vpMath::round(hue * 255.0);
4186  rgb[i * step + 1] = (unsigned char)vpMath::round(saturation * 255.0);
4187  rgb[i * step + 2] = (unsigned char)vpMath::round(value * 255.0);
4188  if (step == 4) // alpha
4189  rgb[i * step + 3] = vpRGBa::alpha_default;
4190  }
4191 }
4192 
4193 void vpImageConvert::RGB2HSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4194  unsigned int size, unsigned int step)
4195 {
4196  for (unsigned int i = 0; i < size; i++) {
4197  double red, green, blue;
4198  double h, s, v;
4199  double min, max;
4200 
4201  red = rgb[i * step] / 255.0;
4202  green = rgb[i * step + 1] / 255.0;
4203  blue = rgb[i * step + 2] / 255.0;
4204 
4205  if (red > green) {
4206  max = ((std::max))(red, blue);
4207  min = ((std::min))(green, blue);
4208  } else {
4209  max = ((std::max))(green, blue);
4210  min = ((std::min))(red, blue);
4211  }
4212 
4213  v = max;
4214 
4215  if (!vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
4216  s = (max - min) / max;
4217  } else {
4218  s = 0.0;
4219  }
4220 
4221  if (vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
4222  h = 0.0;
4223  } else {
4224  double delta = max - min;
4225  if (vpMath::equal(delta, 0.0, std::numeric_limits<double>::epsilon())) {
4226  delta = 1.0;
4227  }
4228 
4229  if (vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
4230  h = (green - blue) / delta;
4231  } else if (vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
4232  h = 2 + (blue - red) / delta;
4233  } else {
4234  h = 4 + (red - green) / delta;
4235  }
4236 
4237  h /= 6.0;
4238  if (h < 0.0) {
4239  h += 1.0;
4240  } else if (h > 1.0) {
4241  h -= 1.0;
4242  }
4243  }
4244 
4245  hue[i] = h;
4246  saturation[i] = s;
4247  value[i] = v;
4248  }
4249 }
4250 
4263 void vpImageConvert::HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba,
4264  unsigned int size)
4265 {
4266  vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
4267 }
4268 
4281 void vpImageConvert::HSVToRGBa(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4282  unsigned char *rgba, unsigned int size)
4283 {
4284  for (unsigned int i = 0; i < size; i++) {
4285  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4286 
4287  vpImageConvert::HSVToRGBa(&h, &s, &v, (rgba + i * 4), 1);
4288  }
4289 }
4290 
4303 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value,
4304  unsigned int size)
4305 {
4306  vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
4307 }
4308 
4320 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
4321  unsigned char *value, unsigned int size)
4322 {
4323  for (unsigned int i = 0; i < size; i++) {
4324  double h, s, v;
4325  vpImageConvert::RGBaToHSV((rgba + i * 4), &h, &s, &v, 1);
4326 
4327  hue[i] = (unsigned char)(255.0 * h);
4328  saturation[i] = (unsigned char)(255.0 * s);
4329  value[i] = (unsigned char)(255.0 * v);
4330  }
4331 }
4332 
4342 void vpImageConvert::HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb,
4343  unsigned int size)
4344 {
4345  vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
4346 }
4347 
4357 void vpImageConvert::HSVToRGB(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4358  unsigned char *rgb, unsigned int size)
4359 {
4360  for (unsigned int i = 0; i < size; i++) {
4361  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4362 
4363  vpImageConvert::HSVToRGB(&h, &s, &v, (rgb + i * 3), 1);
4364  }
4365 }
4366 
4378 void vpImageConvert::RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4379  unsigned int size)
4380 {
4381  vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
4382 }
4383 
4394 void vpImageConvert::RGBToHSV(const unsigned char *rgb, unsigned char *hue, unsigned char *saturation,
4395  unsigned char *value, unsigned int size)
4396 {
4397  for (unsigned int i = 0; i < size; i++) {
4398  double h, s, v;
4399 
4400  vpImageConvert::RGBToHSV((rgb + i * 3), &h, &s, &v, 1);
4401 
4402  hue[i] = (unsigned char)(255.0 * h);
4403  saturation[i] = (unsigned char)(255.0 * s);
4404  value[i] = (unsigned char)(255.0 * v);
4405  }
4406 }
unsigned int getCols() const
Definition: vpImage.h:179
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
unsigned int getWidth() const
Definition: vpImage.h:246
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:800
static void HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb, unsigned int size)
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:938
unsigned char B
Blue component.
Definition: vpRGBa.h:150
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, unsigned int size)
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
static void MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:293
static void YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
error that can be emited by ViSP classes.
Definition: vpException.h:71
static void YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
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 YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
unsigned char G
Green component.
Definition: vpRGBa.h:149
static void GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
static void RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value, unsigned int size)
Definition: vpRGBa.h:66
static void YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
unsigned int getRows() const
Definition: vpImage.h:218
static void YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
unsigned int getSize() const
Definition: vpImage.h:227
static void YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
static void YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
static void MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, unsigned int size)
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 BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static int round(double x)
Definition: vpMath.h:245
static void YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV444ToRGB(unsigned char *yuv, 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 YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
unsigned char R
Red component.
Definition: vpRGBa.h:148
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
unsigned int getHeight() const
Definition: vpImage.h:188
static void YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
static void YCrCbToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YCrCbToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)