Visual Servoing Platform  version 3.5.1 under development (2023-06-08)
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  *****************************************************************************/
35 
41 #include <map>
42 #include <sstream>
43 
44 #if defined _OPENMP
45 #include <omp.h>
46 #endif
47 
48 // image
49 #include "private/vpBayerConversion.h"
50 #include "private/vpImageConvert_impl.h"
51 #include <Simd/SimdLib.hpp>
52 #include <visp3/core/vpImageConvert.h>
53 
54 bool vpImageConvert::YCbCrLUTcomputed = false;
55 int vpImageConvert::vpCrr[256];
56 int vpImageConvert::vpCgb[256];
57 int vpImageConvert::vpCgr[256];
58 int vpImageConvert::vpCbb[256];
59 
69 {
70  dest.resize(src.getHeight(), src.getWidth());
71 
72  GreyToRGBa(src.bitmap, reinterpret_cast<unsigned char *>(dest.bitmap), src.getWidth(), src.getHeight());
73 }
74 
84 void vpImageConvert::convert(const vpImage<vpRGBa> &src, vpImage<unsigned char> &dest, unsigned int nThreads)
85 {
86  dest.resize(src.getHeight(), src.getWidth());
87 
88  RGBaToGrey(reinterpret_cast<unsigned char *>(src.bitmap), dest.bitmap, src.getWidth(), src.getHeight(), nThreads);
89 }
90 
98 {
99  dest.resize(src.getHeight(), src.getWidth());
100  unsigned int max_xy = src.getWidth() * src.getHeight();
101  float min, max;
102 
103  src.getMinMaxValue(min, max);
104 
105  for (unsigned int i = 0; i < max_xy; i++) {
106  float val = 255.f * (src.bitmap[i] - min) / (max - min);
107  if (val < 0)
108  dest.bitmap[i] = 0;
109  else if (val > 255)
110  dest.bitmap[i] = 255;
111  else
112  dest.bitmap[i] = (unsigned char)val;
113  }
114 }
115 
123 {
124  dest.resize(src.getHeight(), src.getWidth());
125  vpRGBf min, max;
126  src.getMinMaxValue(min, max);
127 
128  for (unsigned int i = 0; i < src.getHeight(); i++) {
129  for (unsigned int j = 0; j < src.getWidth(); j++) {
130  for (unsigned int c = 0; c < 3; c++) {
131  float val = 255.f * (reinterpret_cast<const float *>(&(src[i][j]))[c] - reinterpret_cast<float *>(&min)[c]) /
132  (reinterpret_cast<float *>(&max)[c] - reinterpret_cast<float *>(&min)[c]);
133  if (val < 0)
134  reinterpret_cast<unsigned char *>(&(dest[i][j]))[c] = 0;
135  else if (val > 255)
136  reinterpret_cast<unsigned char *>(&(dest[i][j]))[c] = 255;
137  else
138  reinterpret_cast<unsigned char *>(&(dest[i][j]))[c] = (unsigned char)val;
139  }
140  }
141  }
142 }
143 
150 {
151  dest.resize(src.getHeight(), src.getWidth());
152  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
153  dest.bitmap[i] = (float)src.bitmap[i];
154 }
155 
163 {
164  dest.resize(src.getHeight(), src.getWidth());
165  unsigned int max_xy = src.getWidth() * src.getHeight();
166  double min, max;
167 
168  src.getMinMaxValue(min, max);
169 
170  for (unsigned int i = 0; i < max_xy; i++) {
171  double val = 255. * (src.bitmap[i] - min) / (max - min);
172  if (val < 0)
173  dest.bitmap[i] = 0;
174  else if (val > 255)
175  dest.bitmap[i] = 255;
176  else
177  dest.bitmap[i] = (unsigned char)val;
178  }
179 }
180 
187 void vpImageConvert::convert(const vpImage<uint16_t> &src, vpImage<unsigned char> &dest, unsigned char bitshift)
188 {
189  dest.resize(src.getHeight(), src.getWidth());
190 
191  for (unsigned int i = 0; i < src.getSize(); i++)
192  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] >> bitshift);
193 }
194 
201 void vpImageConvert::convert(const vpImage<unsigned char> &src, vpImage<uint16_t> &dest, unsigned char bitshift)
202 {
203  dest.resize(src.getHeight(), src.getWidth());
204 
205  for (unsigned int i = 0; i < src.getSize(); i++)
206  dest.bitmap[i] = static_cast<unsigned char>(src.bitmap[i] << bitshift);
207 }
208 
215 {
216  dest.resize(src.getHeight(), src.getWidth());
217  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
218  dest.bitmap[i] = (double)src.bitmap[i];
219 }
220 
229 {
230  vp_createDepthHistogram(src_depth, dest_rgba);
231 }
232 
240 {
241  vp_createDepthHistogram(src_depth, dest_depth);
242 }
243 
252 {
253  vp_createDepthHistogram(src_depth, dest_rgba);
254 }
255 
263 {
264  vp_createDepthHistogram(src_depth, dest_depth);
265 }
266 
267 #ifdef VISP_HAVE_OPENCV
268 // Deprecated: will be removed with OpenCV transcient from C to C++ api
314 void vpImageConvert::convert(const IplImage *src, vpImage<vpRGBa> &dest, bool flip)
315 {
316  int nChannel = src->nChannels;
317  int depth = src->depth;
318  int height = src->height;
319  int width = src->width;
320  int widthStep = src->widthStep;
321  int lineStep = (flip) ? 1 : 0;
322 
323  if (nChannel == 3 && depth == 8) {
324  dest.resize((unsigned int)height, (unsigned int)width);
325 
326  // starting source address
327  unsigned char *input = (unsigned char *)src->imageData;
328  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
329 
330  for (int i = 0; i < height; i++) {
331  unsigned char *line = input;
332  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
333  for (int j = 0; j < width; j++) {
334  *(output++) = *(line + 2);
335  *(output++) = *(line + 1);
336  *(output++) = *(line);
337  *(output++) = vpRGBa::alpha_default;
338 
339  line += 3;
340  }
341  // go to the next line
342  input += widthStep;
343  }
344  } else if (nChannel == 1 && depth == 8) {
345  dest.resize((unsigned int)height, (unsigned int)width);
346  // starting source address
347  unsigned char *input = (unsigned char *)src->imageData;
348  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
349 
350  for (int i = 0; i < height; i++) {
351  unsigned char *line = input;
352  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
353  for (int j = 0; j < width; j++) {
354  *output++ = *(line);
355  *output++ = *(line);
356  *output++ = *(line);
357  *output++ = vpRGBa::alpha_default; // alpha
358 
359  line++;
360  }
361  // go to the next line
362  input += widthStep;
363  }
364  }
365 }
366 
409 void vpImageConvert::convert(const IplImage *src, vpImage<unsigned char> &dest, bool flip)
410 {
411  int nChannel = src->nChannels;
412  int depth = src->depth;
413  int height = src->height;
414  int width = src->width;
415  int widthStep = src->widthStep;
416  int lineStep = (flip) ? 1 : 0;
417 
418  if (flip == false) {
419  if (widthStep == width) {
420  if (nChannel == 1 && depth == 8) {
421  dest.resize((unsigned int)height, (unsigned int)width);
422  memcpy(dest.bitmap, src->imageData, (size_t)(height * width));
423  }
424  if (nChannel == 3 && depth == 8) {
425  dest.resize((unsigned int)height, (unsigned int)width);
426  BGRToGrey((unsigned char *)src->imageData, dest.bitmap, (unsigned int)width, (unsigned int)height, false);
427  }
428  } else {
429  if (nChannel == 1 && depth == 8) {
430  dest.resize((unsigned int)height, (unsigned int)width);
431  for (int i = 0; i < height; i++) {
432  memcpy(dest.bitmap + i * width, src->imageData + i * widthStep, (size_t)width);
433  }
434  }
435  if (nChannel == 3 && depth == 8) {
436  dest.resize((unsigned int)height, (unsigned int)width);
437  for (int i = 0; i < height; i++) {
438  BGRToGrey((unsigned char *)src->imageData + i * widthStep, dest.bitmap + i * width, (unsigned int)width, 1,
439  false);
440  }
441  }
442  }
443  } else {
444  if (nChannel == 1 && depth == 8) {
445  dest.resize((unsigned int)height, (unsigned int)width);
446  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
447  for (int i = 0; i < height; i++) {
448  memcpy(beginOutput + lineStep * (4 * width * (height - 1 - i)), src->imageData + i * widthStep, (size_t)width);
449  }
450  }
451  if (nChannel == 3 && depth == 8) {
452  dest.resize((unsigned int)height, (unsigned int)width);
453  // for (int i = 0 ; i < height ; i++){
454  BGRToGrey((unsigned char *)src->imageData /*+ i*widthStep*/, dest.bitmap /*+ i*width*/, (unsigned int)width,
455  (unsigned int)height /*1*/, true);
456  //}
457  }
458  }
459 }
460 
504 void vpImageConvert::convert(const vpImage<vpRGBa> &src, IplImage *&dest)
505 {
506  int height = (int)src.getHeight();
507  int width = (int)src.getWidth();
508  CvSize size = cvSize(width, height);
509  int depth = 8;
510  int channels = 3;
511  if (dest != NULL) {
512  if (dest->nChannels != channels || dest->depth != depth || dest->height != height || dest->width != width) {
513  if (dest->nChannels != 0)
514  cvReleaseImage(&dest);
515  dest = cvCreateImage(size, depth, channels);
516  }
517  } else
518  dest = cvCreateImage(size, depth, channels);
519 
520  // starting source address
521  unsigned char *input = (unsigned char *)src.bitmap; // rgba image
522  unsigned char *output = (unsigned char *)dest->imageData; // bgr image
523 
524  int j = 0;
525  int i = 0;
526  int widthStep = dest->widthStep;
527 
528  for (i = 0; i < height; i++) {
529  output = (unsigned char *)dest->imageData + i * widthStep;
530  unsigned char *line = input;
531  for (j = 0; j < width; j++) {
532  *output++ = *(line + 2); // B
533  *output++ = *(line + 1); // G
534  *output++ = *(line); // R
535 
536  line += 4;
537  }
538  // go to the next line
539  input += 4 * width;
540  }
541 }
542 
586 void vpImageConvert::convert(const vpImage<unsigned char> &src, IplImage *&dest)
587 {
588  unsigned int height = src.getHeight();
589  unsigned int width = src.getWidth();
590  CvSize size = cvSize((int)width, (int)height);
591  int depth = 8;
592  int channels = 1;
593  if (dest != NULL) {
594  if (dest->nChannels != channels || dest->depth != depth || dest->height != (int)height ||
595  dest->width != (int)width) {
596  if (dest->nChannels != 0)
597  cvReleaseImage(&dest);
598  dest = cvCreateImage(size, depth, channels);
599  }
600  } else
601  dest = cvCreateImage(size, depth, channels);
602 
603  unsigned int widthStep = (unsigned int)dest->widthStep;
604 
605  if (width == widthStep) {
606  memcpy(dest->imageData, src.bitmap, width * height);
607  } else {
608  // copying each line taking account of the widthStep
609  for (unsigned int i = 0; i < height; i++) {
610  memcpy(dest->imageData + i * widthStep, src.bitmap + i * width, width);
611  }
612  }
613 }
614 
615 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
663 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, bool flip)
664 {
665  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
666 
667  if (src.type() == CV_8UC4) {
668  vpRGBa rgbaVal;
669  for (unsigned int i = 0; i < dest.getRows(); ++i)
670  for (unsigned int j = 0; j < dest.getCols(); ++j) {
671  cv::Vec4b tmp = src.at<cv::Vec4b>((int)i, (int)j);
672  rgbaVal.R = tmp[2];
673  rgbaVal.G = tmp[1];
674  rgbaVal.B = tmp[0];
675  rgbaVal.A = tmp[3];
676  if (flip)
677  dest[dest.getRows() - i - 1][j] = rgbaVal;
678  else
679  dest[i][j] = rgbaVal;
680  }
681  } else if (src.type() == CV_8UC3) {
682  if (src.isContinuous() && !flip) {
683  SimdRgbToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
684  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
685  } else {
686  vpRGBa rgbaVal;
687  rgbaVal.A = vpRGBa::alpha_default;
688  for (unsigned int i = 0; i < dest.getRows(); ++i) {
689  for (unsigned int j = 0; j < dest.getCols(); ++j) {
690  cv::Vec3b tmp = src.at<cv::Vec3b>((int)i, (int)j);
691  rgbaVal.R = tmp[2];
692  rgbaVal.G = tmp[1];
693  rgbaVal.B = tmp[0];
694  if (flip) {
695  dest[dest.getRows() - i - 1][j] = rgbaVal;
696  } else {
697  dest[i][j] = rgbaVal;
698  }
699  }
700  }
701  }
702  } else if (src.type() == CV_8UC1) {
703  if (src.isContinuous() && !flip) {
704  SimdGrayToBgra(src.data, src.cols, src.rows, src.step[0], reinterpret_cast<uint8_t *>(dest.bitmap),
705  dest.getWidth() * sizeof(vpRGBa), vpRGBa::alpha_default);
706  } else {
707  vpRGBa rgbaVal;
708  for (unsigned int i = 0; i < dest.getRows(); ++i) {
709  for (unsigned int j = 0; j < dest.getCols(); ++j) {
710  rgbaVal = src.at<unsigned char>((int)i, (int)j);
711  if (flip) {
712  dest[dest.getRows() - i - 1][j] = rgbaVal;
713  } else {
714  dest[i][j] = rgbaVal;
715  }
716  }
717  }
718  }
719  }
720 }
721 
764 void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, bool flip, unsigned int nThreads)
765 {
766  if (src.type() == CV_8UC1) {
767  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
768  if (src.isContinuous() && !flip) {
769  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols));
770  } else {
771  if (flip) {
772  for (unsigned int i = 0; i < dest.getRows(); ++i) {
773  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1(), (size_t)src.step);
774  }
775  } else {
776  for (unsigned int i = 0; i < dest.getRows(); ++i) {
777  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1(), (size_t)src.step);
778  }
779  }
780  }
781  } else if (src.type() == CV_8UC3) {
782  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
783  if (src.isContinuous()) {
784  BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows,
785  flip, nThreads);
786  } else {
787  if (flip) {
788  for (unsigned int i = 0; i < dest.getRows(); ++i) {
789  BGRToGrey((unsigned char *)src.data + i * src.step1(),
790  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
791  (unsigned int)dest.getCols(), 1, false);
792  }
793  } else {
794  for (unsigned int i = 0; i < dest.getRows(); ++i) {
795  BGRToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
796  (unsigned int)dest.getCols(), 1, false);
797  }
798  }
799  }
800  } else if (src.type() == CV_8UC4) {
801  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
802  if (src.isContinuous()) {
803  BGRaToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols,
804  (unsigned int)src.rows, flip, nThreads);
805  } else {
806  if (flip) {
807  for (unsigned int i = 0; i < dest.getRows(); ++i) {
808  BGRaToGrey((unsigned char *)src.data + i * src.step1(),
809  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
810  (unsigned int)dest.getCols(), 1, false);
811  }
812  } else {
813  for (unsigned int i = 0; i < dest.getRows(); ++i) {
814  BGRaToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
815  (unsigned int)dest.getCols(), 1, false);
816  }
817  }
818  }
819  }
820 }
821 
829 void vpImageConvert::convert(const cv::Mat &src, vpImage<float> &dest, bool flip)
830 {
831  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
832 
833  if (src.type() == CV_32FC1) {
834  for (unsigned int i = 0; i < dest.getRows(); ++i)
835  for (unsigned int j = 0; j < dest.getCols(); ++j) {
836  if (flip)
837  dest[dest.getRows() - i - 1][j] = src.at<float>((int)i, (int)j);
838  else
839  dest[i][j] = src.at<float>((int)i, (int)j);
840  }
841  } else {
842  throw vpException(vpException::badValue, "cv::Mat type is not supported!");
843  }
844 }
845 
853 void vpImageConvert::convert(const cv::Mat &src, vpImage<uint16_t> &dest, bool flip)
854 {
855  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
856 
857  if (src.type() == CV_16UC1) {
858  if (src.isContinuous()) {
859  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols)*sizeof(uint16_t));
860  } else {
861  if (flip) {
862  for (unsigned int i = 0; i < dest.getRows(); ++i) {
863  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1()*sizeof(uint16_t), (size_t)src.step);
864  }
865  } else {
866  for (unsigned int i = 0; i < dest.getRows(); ++i) {
867  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1()*sizeof(uint16_t), (size_t)src.step);
868  }
869  }
870  }
871  }
872  else {
873  throw(vpException(vpException::fatalError, "cv:Mat format not supported for conversion into vpImage<uint16_t>"));
874  }
875 }
876 
884 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBf> &dest, bool flip)
885 {
886  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
887 
888  if (src.type() == CV_32FC3) {
889  vpRGBf rgbVal;
890  for (unsigned int i = 0; i < dest.getRows(); ++i)
891  for (unsigned int j = 0; j < dest.getCols(); ++j) {
892  cv::Vec3f tmp = src.at<cv::Vec3f>((int)i, (int)j);
893  rgbVal.R = tmp[2];
894  rgbVal.G = tmp[1];
895  rgbVal.B = tmp[0];
896  if (flip)
897  dest[dest.getRows() - i - 1][j] = rgbVal;
898  else
899  dest[i][j] = rgbVal;
900  }
901  } else {
902  throw vpException(vpException::badValue, "cv::Mat type is not supported!");
903  }
904 }
905 
942 void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
943 {
944  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_8UC4, (void *)src.bitmap);
945  cv::cvtColor(vpToMat, dest, cv::COLOR_RGBA2BGR);
946 }
947 
986 void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, bool copyData)
987 {
988  if (copyData) {
989  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
990  dest = tmpMap.clone();
991  } else {
992  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
993  }
994 }
995 
996 void vpImageConvert::convert(const vpImage<float> &src, cv::Mat &dest, bool copyData)
997 {
998  if (copyData) {
999  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_32FC1, (void *)src.bitmap);
1000  dest = tmpMap.clone();
1001  } else {
1002  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_32FC1, (void *)src.bitmap);
1003  }
1004 }
1005 
1006 void vpImageConvert::convert(const vpImage<vpRGBf> &src, cv::Mat &dest)
1007 {
1008  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_32FC3, (void *)src.bitmap);
1009  cv::cvtColor(vpToMat, dest, cv::COLOR_RGB2BGR);
1010 }
1011 
1012 #endif
1013 #endif
1014 
1015 #ifdef VISP_HAVE_YARP
1049 void vpImageConvert::convert(const vpImage<unsigned char> &src, yarp::sig::ImageOf<yarp::sig::PixelMono> *dest,
1050  bool copyData)
1051 {
1052  if (copyData) {
1053  dest->resize(src.getWidth(), src.getHeight());
1054  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth());
1055  } else
1056  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
1057 }
1058 
1097 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelMono> *src, vpImage<unsigned char> &dest,
1098  bool copyData)
1099 {
1100  dest.resize(src->height(), src->width());
1101  if (copyData)
1102  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelMono));
1103  else
1104  dest.bitmap = src->getRawImage();
1105 }
1106 
1141 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgba> *dest, bool copyData)
1142 {
1143  if (copyData) {
1144  dest->resize(src.getWidth(), src.getHeight());
1145  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() * sizeof(vpRGBa));
1146  } else
1147  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
1148 }
1149 
1188 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgba> *src, vpImage<vpRGBa> &dest, bool copyData)
1189 {
1190  dest.resize(src->height(), src->width());
1191  if (copyData)
1192  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelRgba));
1193  else
1194  dest.bitmap = static_cast<vpRGBa *>(src->getRawImage());
1195 }
1196 
1229 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgb> *dest)
1230 {
1231  dest->resize(src.getWidth(), src.getHeight());
1232  for (unsigned int i = 0; i < src.getRows(); i++) {
1233  for (unsigned int j = 0; j < src.getWidth(); j++) {
1234  dest->pixel(j, i).r = src[i][j].R;
1235  dest->pixel(j, i).g = src[i][j].G;
1236  dest->pixel(j, i).b = src[i][j].B;
1237  }
1238  }
1239 }
1240 
1279 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgb> *src, vpImage<vpRGBa> &dest)
1280 {
1281  dest.resize(src->height(), src->width());
1282  for (int i = 0; i < src->height(); i++) {
1283  for (int j = 0; j < src->width(); j++) {
1284  dest[i][j].R = src->pixel(j, i).r;
1285  dest[i][j].G = src->pixel(j, i).g;
1286  dest[i][j].B = src->pixel(j, i).b;
1287  dest[i][j].A = vpRGBa::alpha_default;
1288  }
1289  }
1290 }
1291 
1292 #endif
1293 
1294 #define vpSAT(c) \
1295  if (c & (~255)) { \
1296  if (c < 0) \
1297  c = 0; \
1298  else \
1299  c = 255; \
1300  }
1313 void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
1314 {
1315  unsigned char *s;
1316  unsigned char *d;
1317  int w, h;
1318  int r, g, b, cr, cg, cb, y1, y2;
1319 
1320  h = (int)height;
1321  w = (int)width;
1322  s = yuyv;
1323  d = rgba;
1324  while (h--) {
1325  int c = w >> 1;
1326  while (c--) {
1327  y1 = *s++;
1328  cb = ((*s - 128) * 454) >> 8;
1329  cg = (*s++ - 128) * 88;
1330  y2 = *s++;
1331  cr = ((*s - 128) * 359) >> 8;
1332  cg = (cg + (*s++ - 128) * 183) >> 8;
1333 
1334  r = y1 + cr;
1335  b = y1 + cb;
1336  g = y1 - cg;
1337  vpSAT(r) vpSAT(g) vpSAT(b)
1338 
1339  *d++ = static_cast<unsigned char>(r);
1340  *d++ = static_cast<unsigned char>(g);
1341  *d++ = static_cast<unsigned char>(b);
1342  *d++ = vpRGBa::alpha_default;
1343 
1344  r = y2 + cr;
1345  b = y2 + cb;
1346  g = y2 - cg;
1347  vpSAT(r) vpSAT(g) vpSAT(b)
1348 
1349  *d++ = static_cast<unsigned char>(r);
1350  *d++ = static_cast<unsigned char>(g);
1351  *d++ = static_cast<unsigned char>(b);
1352  *d++ = vpRGBa::alpha_default;
1353  }
1354  }
1355 }
1356 
1367 void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
1368 {
1369  unsigned char *s;
1370  unsigned char *d;
1371  int h, w;
1372  int r, g, b, cr, cg, cb, y1, y2;
1373 
1374  h = (int)height;
1375  w = (int)width;
1376  s = yuyv;
1377  d = rgb;
1378  while (h--) {
1379  int c = w >> 1;
1380  while (c--) {
1381  y1 = *s++;
1382  cb = ((*s - 128) * 454) >> 8;
1383  cg = (*s++ - 128) * 88;
1384  y2 = *s++;
1385  cr = ((*s - 128) * 359) >> 8;
1386  cg = (cg + (*s++ - 128) * 183) >> 8;
1387 
1388  r = y1 + cr;
1389  b = y1 + cb;
1390  g = y1 - cg;
1391  vpSAT(r) vpSAT(g) vpSAT(b)
1392 
1393  *d++ = static_cast<unsigned char>(r);
1394  *d++ = static_cast<unsigned char>(g);
1395  *d++ = static_cast<unsigned char>(b);
1396 
1397  r = y2 + cr;
1398  b = y2 + cb;
1399  g = y2 - cg;
1400  vpSAT(r) vpSAT(g) vpSAT(b)
1401 
1402  *d++ = static_cast<unsigned char>(r);
1403  *d++ = static_cast<unsigned char>(g);
1404  *d++ = static_cast<unsigned char>(b);
1405  }
1406  }
1407 }
1408 
1419 void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
1420 {
1421  unsigned int i = 0, j = 0;
1422 
1423  while (j < size * 2) {
1424  grey[i++] = yuyv[j];
1425  grey[i++] = yuyv[j + 2];
1426  j += 4;
1427  }
1428 }
1429 
1439 void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1440 {
1441 #if 1
1442  // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1443  for (unsigned int i = size / 4; i; i--) {
1444  int U = (int)((*yuv++ - 128) * 0.354);
1445  int U5 = 5 * U;
1446  int Y0 = *yuv++;
1447  int Y1 = *yuv++;
1448  int V = (int)((*yuv++ - 128) * 0.707);
1449  int V2 = 2 * V;
1450  int Y2 = *yuv++;
1451  int Y3 = *yuv++;
1452  int UV = -U - V;
1453 
1454  // Original equations
1455  // R = Y + 1.402 V
1456  // G = Y - 0.344 U - 0.714 V
1457  // B = Y + 1.772 U
1458  int R = Y0 + V2;
1459  if ((R >> 8) > 0)
1460  R = 255;
1461  else if (R < 0)
1462  R = 0;
1463 
1464  int G = Y0 + UV;
1465  if ((G >> 8) > 0)
1466  G = 255;
1467  else if (G < 0)
1468  G = 0;
1469 
1470  int B = Y0 + U5;
1471  if ((B >> 8) > 0)
1472  B = 255;
1473  else if (B < 0)
1474  B = 0;
1475 
1476  *rgba++ = (unsigned char)R;
1477  *rgba++ = (unsigned char)G;
1478  *rgba++ = (unsigned char)B;
1479  *rgba++ = vpRGBa::alpha_default;
1480 
1481  //---
1482  R = Y1 + V2;
1483  if ((R >> 8) > 0)
1484  R = 255;
1485  else if (R < 0)
1486  R = 0;
1487 
1488  G = Y1 + UV;
1489  if ((G >> 8) > 0)
1490  G = 255;
1491  else if (G < 0)
1492  G = 0;
1493 
1494  B = Y1 + U5;
1495  if ((B >> 8) > 0)
1496  B = 255;
1497  else if (B < 0)
1498  B = 0;
1499 
1500  *rgba++ = (unsigned char)R;
1501  *rgba++ = (unsigned char)G;
1502  *rgba++ = (unsigned char)B;
1503  *rgba++ = vpRGBa::alpha_default;
1504 
1505  //---
1506  R = Y2 + V2;
1507  if ((R >> 8) > 0)
1508  R = 255;
1509  else if (R < 0)
1510  R = 0;
1511 
1512  G = Y2 + UV;
1513  if ((G >> 8) > 0)
1514  G = 255;
1515  else if (G < 0)
1516  G = 0;
1517 
1518  B = Y2 + U5;
1519  if ((B >> 8) > 0)
1520  B = 255;
1521  else if (B < 0)
1522  B = 0;
1523 
1524  *rgba++ = (unsigned char)R;
1525  *rgba++ = (unsigned char)G;
1526  *rgba++ = (unsigned char)B;
1527  *rgba++ = vpRGBa::alpha_default;
1528 
1529  //---
1530  R = Y3 + V2;
1531  if ((R >> 8) > 0)
1532  R = 255;
1533  else if (R < 0)
1534  R = 0;
1535 
1536  G = Y3 + UV;
1537  if ((G >> 8) > 0)
1538  G = 255;
1539  else if (G < 0)
1540  G = 0;
1541 
1542  B = Y3 + U5;
1543  if ((B >> 8) > 0)
1544  B = 255;
1545  else if (B < 0)
1546  B = 0;
1547 
1548  *rgba++ = (unsigned char)R;
1549  *rgba++ = (unsigned char)G;
1550  *rgba++ = (unsigned char)B;
1551  *rgba++ = vpRGBa::alpha_default;
1552  }
1553 #else
1554  // tres tres lent ....
1555  unsigned int i = 0, j = 0;
1556  unsigned char r, g, b;
1557  while (j < numpixels * 3 / 2) {
1558 
1559  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], 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 + 2], yuv[j], yuv[j + 3], 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 
1573  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1574  rgba[i] = r;
1575  rgba[i + 1] = g;
1576  rgba[i + 2] = b;
1577  rgba[i + 3] = vpRGBa::alpha_default;
1578  i += 4;
1579 
1580  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1581  rgba[i] = r;
1582  rgba[i + 1] = g;
1583  rgba[i + 2] = b;
1584  rgba[i + 3] = vpRGBa::alpha_default;
1585  i += 4;
1586 
1587  j += 6;
1588  }
1589 #endif
1590 }
1591 
1604 void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1605 {
1606 
1607 #if 1
1608  // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1609  for (unsigned int i = size / 2; i; i--) {
1610  int U = (int)((*yuv++ - 128) * 0.354);
1611  int U5 = 5 * U;
1612  int Y0 = *yuv++;
1613  int V = (int)((*yuv++ - 128) * 0.707);
1614  int V2 = 2 * V;
1615  int Y1 = *yuv++;
1616  int UV = -U - V;
1617 
1618  //---
1619  int R = Y0 + V2;
1620  if ((R >> 8) > 0)
1621  R = 255;
1622  else if (R < 0)
1623  R = 0;
1624 
1625  int G = Y0 + UV;
1626  if ((G >> 8) > 0)
1627  G = 255;
1628  else if (G < 0)
1629  G = 0;
1630 
1631  int B = Y0 + U5;
1632  if ((B >> 8) > 0)
1633  B = 255;
1634  else if (B < 0)
1635  B = 0;
1636 
1637  *rgba++ = (unsigned char)R;
1638  *rgba++ = (unsigned char)G;
1639  *rgba++ = (unsigned char)B;
1640  *rgba++ = vpRGBa::alpha_default;
1641 
1642  //---
1643  R = Y1 + V2;
1644  if ((R >> 8) > 0)
1645  R = 255;
1646  else if (R < 0)
1647  R = 0;
1648 
1649  G = Y1 + UV;
1650  if ((G >> 8) > 0)
1651  G = 255;
1652  else if (G < 0)
1653  G = 0;
1654 
1655  B = Y1 + U5;
1656  if ((B >> 8) > 0)
1657  B = 255;
1658  else if (B < 0)
1659  B = 0;
1660 
1661  *rgba++ = (unsigned char)R;
1662  *rgba++ = (unsigned char)G;
1663  *rgba++ = (unsigned char)B;
1664  *rgba++ = vpRGBa::alpha_default;
1665  }
1666 
1667 #else
1668  // tres tres lent ....
1669  unsigned int i = 0, j = 0;
1670  unsigned char r, g, b;
1671 
1672  while (j < size * 2) {
1673 
1674  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1675  rgba[i] = r;
1676  rgba[i + 1] = g;
1677  rgba[i + 2] = b;
1678  rgba[i + 3] = vpRGBa::alpha_default;
1679  i += 4;
1680 
1681  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1682  rgba[i] = r;
1683  rgba[i + 1] = g;
1684  rgba[i + 2] = b;
1685  rgba[i + 3] = vpRGBa::alpha_default;
1686  i += 4;
1687  j += 4;
1688  }
1689 #endif
1690 }
1691 
1700 void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1701 {
1702  unsigned int i = 0, j = 0;
1703  while (j < size * 3 / 2) {
1704  grey[i] = yuv[j + 1];
1705  grey[i + 1] = yuv[j + 2];
1706  grey[i + 2] = yuv[j + 4];
1707  grey[i + 3] = yuv[j + 5];
1708 
1709  i += 4;
1710 
1711  j += 6;
1712  }
1713 }
1714 
1725 void vpImageConvert::YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1726 {
1727 #if 1
1728  // std::cout << "call optimized convertYUV422ToRGB()" << std::endl;
1729  for (unsigned int i = size / 2; i; i--) {
1730  int U = (int)((*yuv++ - 128) * 0.354);
1731  int U5 = 5 * U;
1732  int Y0 = *yuv++;
1733  int V = (int)((*yuv++ - 128) * 0.707);
1734  int V2 = 2 * V;
1735  int Y1 = *yuv++;
1736  int UV = -U - V;
1737 
1738  //---
1739  int R = Y0 + V2;
1740  if ((R >> 8) > 0)
1741  R = 255;
1742  else if (R < 0)
1743  R = 0;
1744 
1745  int G = Y0 + UV;
1746  if ((G >> 8) > 0)
1747  G = 255;
1748  else if (G < 0)
1749  G = 0;
1750 
1751  int B = Y0 + U5;
1752  if ((B >> 8) > 0)
1753  B = 255;
1754  else if (B < 0)
1755  B = 0;
1756 
1757  *rgb++ = (unsigned char)R;
1758  *rgb++ = (unsigned char)G;
1759  *rgb++ = (unsigned char)B;
1760 
1761  //---
1762  R = Y1 + V2;
1763  if ((R >> 8) > 0)
1764  R = 255;
1765  else if (R < 0)
1766  R = 0;
1767 
1768  G = Y1 + UV;
1769  if ((G >> 8) > 0)
1770  G = 255;
1771  else if (G < 0)
1772  G = 0;
1773 
1774  B = Y1 + U5;
1775  if ((B >> 8) > 0)
1776  B = 255;
1777  else if (B < 0)
1778  B = 0;
1779 
1780  *rgb++ = (unsigned char)R;
1781  *rgb++ = (unsigned char)G;
1782  *rgb++ = (unsigned char)B;
1783  }
1784 
1785 #else
1786  // tres tres lent ....
1787  unsigned int i = 0, j = 0;
1788  unsigned char r, g, b;
1789 
1790  while (j < size * 2) {
1791 
1792  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1793  rgb[i] = r;
1794  rgb[i + 1] = g;
1795  rgb[i + 2] = b;
1796  i += 3;
1797 
1798  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1799  rgb[i] = r;
1800  rgb[i + 1] = g;
1801  rgb[i + 2] = b;
1802  i += 3;
1803  j += 4;
1804  }
1805 #endif
1806 }
1807 
1818 void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1819 {
1820  unsigned int i = 0, j = 0;
1821 
1822  while (j < size * 2) {
1823  grey[i++] = yuv[j + 1];
1824  grey[i++] = yuv[j + 3];
1825  j += 4;
1826  }
1827 }
1828 
1837 void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1838 {
1839 #if 1
1840  // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1841  for (unsigned int i = size / 4; i; i--) {
1842  int U = (int)((*yuv++ - 128) * 0.354);
1843  int U5 = 5 * U;
1844  int Y0 = *yuv++;
1845  int Y1 = *yuv++;
1846  int V = (int)((*yuv++ - 128) * 0.707);
1847  int V2 = 2 * V;
1848  int Y2 = *yuv++;
1849  int Y3 = *yuv++;
1850  int UV = -U - V;
1851 
1852  // Original equations
1853  // R = Y + 1.402 V
1854  // G = Y - 0.344 U - 0.714 V
1855  // B = Y + 1.772 U
1856  int R = Y0 + V2;
1857  if ((R >> 8) > 0)
1858  R = 255;
1859  else if (R < 0)
1860  R = 0;
1861 
1862  int G = Y0 + UV;
1863  if ((G >> 8) > 0)
1864  G = 255;
1865  else if (G < 0)
1866  G = 0;
1867 
1868  int B = Y0 + U5;
1869  if ((B >> 8) > 0)
1870  B = 255;
1871  else if (B < 0)
1872  B = 0;
1873 
1874  *rgb++ = (unsigned char)R;
1875  *rgb++ = (unsigned char)G;
1876  *rgb++ = (unsigned char)B;
1877 
1878  //---
1879  R = Y1 + V2;
1880  if ((R >> 8) > 0)
1881  R = 255;
1882  else if (R < 0)
1883  R = 0;
1884 
1885  G = Y1 + UV;
1886  if ((G >> 8) > 0)
1887  G = 255;
1888  else if (G < 0)
1889  G = 0;
1890 
1891  B = Y1 + U5;
1892  if ((B >> 8) > 0)
1893  B = 255;
1894  else if (B < 0)
1895  B = 0;
1896 
1897  *rgb++ = (unsigned char)R;
1898  *rgb++ = (unsigned char)G;
1899  *rgb++ = (unsigned char)B;
1900 
1901  //---
1902  R = Y2 + V2;
1903  if ((R >> 8) > 0)
1904  R = 255;
1905  else if (R < 0)
1906  R = 0;
1907 
1908  G = Y2 + UV;
1909  if ((G >> 8) > 0)
1910  G = 255;
1911  else if (G < 0)
1912  G = 0;
1913 
1914  B = Y2 + U5;
1915  if ((B >> 8) > 0)
1916  B = 255;
1917  else if (B < 0)
1918  B = 0;
1919 
1920  *rgb++ = (unsigned char)R;
1921  *rgb++ = (unsigned char)G;
1922  *rgb++ = (unsigned char)B;
1923 
1924  //---
1925  R = Y3 + V2;
1926  if ((R >> 8) > 0)
1927  R = 255;
1928  else if (R < 0)
1929  R = 0;
1930 
1931  G = Y3 + UV;
1932  if ((G >> 8) > 0)
1933  G = 255;
1934  else if (G < 0)
1935  G = 0;
1936 
1937  B = Y3 + U5;
1938  if ((B >> 8) > 0)
1939  B = 255;
1940  else if (B < 0)
1941  B = 0;
1942 
1943  *rgb++ = (unsigned char)R;
1944  *rgb++ = (unsigned char)G;
1945  *rgb++ = (unsigned char)B;
1946  }
1947 #else
1948  // tres tres lent ....
1949 
1950  unsigned int i = 0, j = 0;
1951  unsigned char r, g, b;
1952 
1953  while (j < size * 3 / 2) {
1954  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1955  rgb[i] = r;
1956  rgb[i + 1] = g;
1957  rgb[i + 2] = b;
1958  i += 3;
1959 
1960  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1961  rgb[i] = r;
1962  rgb[i + 1] = g;
1963  rgb[i + 2] = b;
1964  i += 3;
1965 
1966  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1967  rgb[i] = r;
1968  rgb[i + 1] = g;
1969  rgb[i + 2] = b;
1970  i += 3;
1971 
1972  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1973  rgb[i] = r;
1974  rgb[i + 1] = g;
1975  rgb[i + 2] = b;
1976  i += 3;
1977  // TRACE("r= %d g=%d b=%d", r, g, b);
1978 
1979  j += 6;
1980  }
1981 #endif
1982 }
1983 
1994 void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1995 {
1996  // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
1997  int U, V, R, G, B, V2, U5, UV;
1998  int Y0, Y1, Y2, Y3;
1999  unsigned int size = width * height;
2000  unsigned char *iU = yuv + size;
2001  unsigned char *iV = yuv + 5 * size / 4;
2002  for (unsigned int i = 0; i < height / 2; i++) {
2003  for (unsigned int j = 0; j < width / 2; j++) {
2004  U = (int)((*iU++ - 128) * 0.354);
2005  U5 = 5 * U;
2006  V = (int)((*iV++ - 128) * 0.707);
2007  V2 = 2 * V;
2008  UV = -U - V;
2009  Y0 = *yuv++;
2010  Y1 = *yuv;
2011  yuv = yuv + width - 1;
2012  Y2 = *yuv++;
2013  Y3 = *yuv;
2014  yuv = yuv - width + 1;
2015 
2016  // Original equations
2017  // R = Y + 1.402 V
2018  // G = Y - 0.344 U - 0.714 V
2019  // B = Y + 1.772 U
2020  R = Y0 + V2;
2021  if ((R >> 8) > 0)
2022  R = 255;
2023  else if (R < 0)
2024  R = 0;
2025 
2026  G = Y0 + UV;
2027  if ((G >> 8) > 0)
2028  G = 255;
2029  else if (G < 0)
2030  G = 0;
2031 
2032  B = Y0 + U5;
2033  if ((B >> 8) > 0)
2034  B = 255;
2035  else if (B < 0)
2036  B = 0;
2037 
2038  *rgba++ = (unsigned char)R;
2039  *rgba++ = (unsigned char)G;
2040  *rgba++ = (unsigned char)B;
2041  *rgba++ = vpRGBa::alpha_default;
2042 
2043  //---
2044  R = Y1 + V2;
2045  if ((R >> 8) > 0)
2046  R = 255;
2047  else if (R < 0)
2048  R = 0;
2049 
2050  G = Y1 + UV;
2051  if ((G >> 8) > 0)
2052  G = 255;
2053  else if (G < 0)
2054  G = 0;
2055 
2056  B = Y1 + U5;
2057  if ((B >> 8) > 0)
2058  B = 255;
2059  else if (B < 0)
2060  B = 0;
2061 
2062  *rgba++ = (unsigned char)R;
2063  *rgba++ = (unsigned char)G;
2064  *rgba++ = (unsigned char)B;
2065  *rgba = vpRGBa::alpha_default;
2066  rgba = rgba + 4 * width - 7;
2067 
2068  //---
2069  R = Y2 + V2;
2070  if ((R >> 8) > 0)
2071  R = 255;
2072  else if (R < 0)
2073  R = 0;
2074 
2075  G = Y2 + UV;
2076  if ((G >> 8) > 0)
2077  G = 255;
2078  else if (G < 0)
2079  G = 0;
2080 
2081  B = Y2 + U5;
2082  if ((B >> 8) > 0)
2083  B = 255;
2084  else if (B < 0)
2085  B = 0;
2086 
2087  *rgba++ = (unsigned char)R;
2088  *rgba++ = (unsigned char)G;
2089  *rgba++ = (unsigned char)B;
2090  *rgba++ = vpRGBa::alpha_default;
2091 
2092  //---
2093  R = Y3 + V2;
2094  if ((R >> 8) > 0)
2095  R = 255;
2096  else if (R < 0)
2097  R = 0;
2098 
2099  G = Y3 + UV;
2100  if ((G >> 8) > 0)
2101  G = 255;
2102  else if (G < 0)
2103  G = 0;
2104 
2105  B = Y3 + U5;
2106  if ((B >> 8) > 0)
2107  B = 255;
2108  else if (B < 0)
2109  B = 0;
2110 
2111  *rgba++ = (unsigned char)R;
2112  *rgba++ = (unsigned char)G;
2113  *rgba++ = (unsigned char)B;
2114  *rgba = vpRGBa::alpha_default;
2115  rgba = rgba - 4 * width + 1;
2116  }
2117  yuv += width;
2118  rgba += 4 * width;
2119  }
2120 }
2121 
2130 void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
2131 {
2132  // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
2133  int U, V, R, G, B, V2, U5, UV;
2134  int Y0, Y1, Y2, Y3;
2135  unsigned int size = width * height;
2136  unsigned char *iU = yuv + size;
2137  unsigned char *iV = yuv + 5 * size / 4;
2138  for (unsigned int i = 0; i < height / 2; i++) {
2139  for (unsigned int j = 0; j < width / 2; j++) {
2140  U = (int)((*iU++ - 128) * 0.354);
2141  U5 = 5 * U;
2142  V = (int)((*iV++ - 128) * 0.707);
2143  V2 = 2 * V;
2144  UV = -U - V;
2145  Y0 = *yuv++;
2146  Y1 = *yuv;
2147  yuv = yuv + width - 1;
2148  Y2 = *yuv++;
2149  Y3 = *yuv;
2150  yuv = yuv - width + 1;
2151 
2152  // Original equations
2153  // R = Y + 1.402 V
2154  // G = Y - 0.344 U - 0.714 V
2155  // B = Y + 1.772 U
2156  R = Y0 + V2;
2157  if ((R >> 8) > 0)
2158  R = 255;
2159  else if (R < 0)
2160  R = 0;
2161 
2162  G = Y0 + UV;
2163  if ((G >> 8) > 0)
2164  G = 255;
2165  else if (G < 0)
2166  G = 0;
2167 
2168  B = Y0 + U5;
2169  if ((B >> 8) > 0)
2170  B = 255;
2171  else if (B < 0)
2172  B = 0;
2173 
2174  *rgb++ = (unsigned char)R;
2175  *rgb++ = (unsigned char)G;
2176  *rgb++ = (unsigned char)B;
2177 
2178  //---
2179  R = Y1 + V2;
2180  if ((R >> 8) > 0)
2181  R = 255;
2182  else if (R < 0)
2183  R = 0;
2184 
2185  G = Y1 + UV;
2186  if ((G >> 8) > 0)
2187  G = 255;
2188  else if (G < 0)
2189  G = 0;
2190 
2191  B = Y1 + U5;
2192  if ((B >> 8) > 0)
2193  B = 255;
2194  else if (B < 0)
2195  B = 0;
2196 
2197  *rgb++ = (unsigned char)R;
2198  *rgb++ = (unsigned char)G;
2199  *rgb = (unsigned char)B;
2200  rgb = rgb + 3 * width - 5;
2201 
2202  //---
2203  R = Y2 + V2;
2204  if ((R >> 8) > 0)
2205  R = 255;
2206  else if (R < 0)
2207  R = 0;
2208 
2209  G = Y2 + UV;
2210  if ((G >> 8) > 0)
2211  G = 255;
2212  else if (G < 0)
2213  G = 0;
2214 
2215  B = Y2 + U5;
2216  if ((B >> 8) > 0)
2217  B = 255;
2218  else if (B < 0)
2219  B = 0;
2220 
2221  *rgb++ = (unsigned char)R;
2222  *rgb++ = (unsigned char)G;
2223  *rgb++ = (unsigned char)B;
2224 
2225  //---
2226  R = Y3 + V2;
2227  if ((R >> 8) > 0)
2228  R = 255;
2229  else if (R < 0)
2230  R = 0;
2231 
2232  G = Y3 + UV;
2233  if ((G >> 8) > 0)
2234  G = 255;
2235  else if (G < 0)
2236  G = 0;
2237 
2238  B = Y3 + U5;
2239  if ((B >> 8) > 0)
2240  B = 255;
2241  else if (B < 0)
2242  B = 0;
2243 
2244  *rgb++ = (unsigned char)R;
2245  *rgb++ = (unsigned char)G;
2246  *rgb = (unsigned char)B;
2247  rgb = rgb - 3 * width + 1;
2248  }
2249  yuv += width;
2250  rgb += 3 * width;
2251  }
2252 }
2253 
2261 void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2262 {
2263  for (unsigned int i = 0; i < size; i++) {
2264  *grey++ = *yuv++;
2265  }
2266 }
2267 
2277 void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
2278 {
2279  for (unsigned int i = 0; i < size; i++) {
2280  int U = (int)((*yuv++ - 128) * 0.354);
2281  int U5 = 5 * U;
2282  int Y = *yuv++;
2283  int V = (int)((*yuv++ - 128) * 0.707);
2284  int V2 = 2 * V;
2285  int UV = -U - V;
2286 
2287  // Original equations
2288  // R = Y + 1.402 V
2289  // G = Y - 0.344 U - 0.714 V
2290  // B = Y + 1.772 U
2291  int R = Y + V2;
2292  if ((R >> 8) > 0)
2293  R = 255;
2294  else if (R < 0)
2295  R = 0;
2296 
2297  int G = Y + UV;
2298  if ((G >> 8) > 0)
2299  G = 255;
2300  else if (G < 0)
2301  G = 0;
2302 
2303  int B = Y + U5;
2304  if ((B >> 8) > 0)
2305  B = 255;
2306  else if (B < 0)
2307  B = 0;
2308 
2309  *rgba++ = (unsigned char)R;
2310  *rgba++ = (unsigned char)G;
2311  *rgba++ = (unsigned char)B;
2312  *rgba++ = vpRGBa::alpha_default;
2313  }
2314 }
2315 
2323 void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
2324 {
2325  for (unsigned int i = 0; i < size; i++) {
2326  int U = (int)((*yuv++ - 128) * 0.354);
2327  int U5 = 5 * U;
2328  int Y = *yuv++;
2329  int V = (int)((*yuv++ - 128) * 0.707);
2330  int V2 = 2 * V;
2331  int UV = -U - V;
2332 
2333  // Original equations
2334  // R = Y + 1.402 V
2335  // G = Y - 0.344 U - 0.714 V
2336  // B = Y + 1.772 U
2337  int R = Y + V2;
2338  if ((R >> 8) > 0)
2339  R = 255;
2340  else if (R < 0)
2341  R = 0;
2342 
2343  int G = Y + UV;
2344  if ((G >> 8) > 0)
2345  G = 255;
2346  else if (G < 0)
2347  G = 0;
2348 
2349  int B = Y + U5;
2350  if ((B >> 8) > 0)
2351  B = 255;
2352  else if (B < 0)
2353  B = 0;
2354 
2355  *rgb++ = (unsigned char)R;
2356  *rgb++ = (unsigned char)G;
2357  *rgb++ = (unsigned char)B;
2358  }
2359 }
2360 
2368 void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2369 {
2370  yuv++;
2371  for (unsigned int i = 0; i < size; i++) {
2372  *grey++ = *yuv;
2373  yuv = yuv + 3;
2374  }
2375 }
2376 
2387 void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2388 {
2389  // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
2390  int U, V, R, G, B, V2, U5, UV;
2391  int Y0, Y1, Y2, Y3;
2392  unsigned int size = width * height;
2393  unsigned char *iV = yuv + size;
2394  unsigned char *iU = yuv + 5 * size / 4;
2395  for (unsigned int i = 0; i < height / 2; i++) {
2396  for (unsigned int j = 0; j < width / 2; j++) {
2397  U = (int)((*iU++ - 128) * 0.354);
2398  U5 = 5 * U;
2399  V = (int)((*iV++ - 128) * 0.707);
2400  V2 = 2 * V;
2401  UV = -U - V;
2402  Y0 = *yuv++;
2403  Y1 = *yuv;
2404  yuv = yuv + width - 1;
2405  Y2 = *yuv++;
2406  Y3 = *yuv;
2407  yuv = yuv - width + 1;
2408 
2409  // Original equations
2410  // R = Y + 1.402 V
2411  // G = Y - 0.344 U - 0.714 V
2412  // B = Y + 1.772 U
2413  R = Y0 + V2;
2414  if ((R >> 8) > 0)
2415  R = 255;
2416  else if (R < 0)
2417  R = 0;
2418 
2419  G = Y0 + UV;
2420  if ((G >> 8) > 0)
2421  G = 255;
2422  else if (G < 0)
2423  G = 0;
2424 
2425  B = Y0 + U5;
2426  if ((B >> 8) > 0)
2427  B = 255;
2428  else if (B < 0)
2429  B = 0;
2430 
2431  *rgba++ = (unsigned char)R;
2432  *rgba++ = (unsigned char)G;
2433  *rgba++ = (unsigned char)B;
2434  *rgba++ = vpRGBa::alpha_default;
2435 
2436  //---
2437  R = Y1 + V2;
2438  if ((R >> 8) > 0)
2439  R = 255;
2440  else if (R < 0)
2441  R = 0;
2442 
2443  G = Y1 + UV;
2444  if ((G >> 8) > 0)
2445  G = 255;
2446  else if (G < 0)
2447  G = 0;
2448 
2449  B = Y1 + U5;
2450  if ((B >> 8) > 0)
2451  B = 255;
2452  else if (B < 0)
2453  B = 0;
2454 
2455  *rgba++ = (unsigned char)R;
2456  *rgba++ = (unsigned char)G;
2457  *rgba++ = (unsigned char)B;
2458  *rgba = 0;
2459  rgba = rgba + 4 * width - 7;
2460 
2461  //---
2462  R = Y2 + V2;
2463  if ((R >> 8) > 0)
2464  R = 255;
2465  else if (R < 0)
2466  R = 0;
2467 
2468  G = Y2 + UV;
2469  if ((G >> 8) > 0)
2470  G = 255;
2471  else if (G < 0)
2472  G = 0;
2473 
2474  B = Y2 + U5;
2475  if ((B >> 8) > 0)
2476  B = 255;
2477  else if (B < 0)
2478  B = 0;
2479 
2480  *rgba++ = (unsigned char)R;
2481  *rgba++ = (unsigned char)G;
2482  *rgba++ = (unsigned char)B;
2483  *rgba++ = vpRGBa::alpha_default;
2484 
2485  //---
2486  R = Y3 + V2;
2487  if ((R >> 8) > 0)
2488  R = 255;
2489  else if (R < 0)
2490  R = 0;
2491 
2492  G = Y3 + UV;
2493  if ((G >> 8) > 0)
2494  G = 255;
2495  else if (G < 0)
2496  G = 0;
2497 
2498  B = Y3 + U5;
2499  if ((B >> 8) > 0)
2500  B = 255;
2501  else if (B < 0)
2502  B = 0;
2503 
2504  *rgba++ = (unsigned char)R;
2505  *rgba++ = (unsigned char)G;
2506  *rgba++ = (unsigned char)B;
2507  *rgba = vpRGBa::alpha_default;
2508  rgba = rgba - 4 * width + 1;
2509  }
2510  yuv += width;
2511  rgba += 4 * width;
2512  }
2513 }
2514 
2523 void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2524 {
2525  // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2526  int U, V, R, G, B, V2, U5, UV;
2527  int Y0, Y1, Y2, Y3;
2528  unsigned int size = width * height;
2529  unsigned char *iV = yuv + size;
2530  unsigned char *iU = yuv + 5 * size / 4;
2531  for (unsigned int i = 0; i < height / 2; i++) {
2532  for (unsigned int j = 0; j < width / 2; j++) {
2533  U = (int)((*iU++ - 128) * 0.354);
2534  U5 = 5 * U;
2535  V = (int)((*iV++ - 128) * 0.707);
2536  V2 = 2 * V;
2537  UV = -U - V;
2538  Y0 = *yuv++;
2539  Y1 = *yuv;
2540  yuv = yuv + width - 1;
2541  Y2 = *yuv++;
2542  Y3 = *yuv;
2543  yuv = yuv - width + 1;
2544 
2545  // Original equations
2546  // R = Y + 1.402 V
2547  // G = Y - 0.344 U - 0.714 V
2548  // B = Y + 1.772 U
2549  R = Y0 + V2;
2550  if ((R >> 8) > 0)
2551  R = 255;
2552  else if (R < 0)
2553  R = 0;
2554 
2555  G = Y0 + UV;
2556  if ((G >> 8) > 0)
2557  G = 255;
2558  else if (G < 0)
2559  G = 0;
2560 
2561  B = Y0 + U5;
2562  if ((B >> 8) > 0)
2563  B = 255;
2564  else if (B < 0)
2565  B = 0;
2566 
2567  *rgb++ = (unsigned char)R;
2568  *rgb++ = (unsigned char)G;
2569  *rgb++ = (unsigned char)B;
2570 
2571  //---
2572  R = Y1 + V2;
2573  if ((R >> 8) > 0)
2574  R = 255;
2575  else if (R < 0)
2576  R = 0;
2577 
2578  G = Y1 + UV;
2579  if ((G >> 8) > 0)
2580  G = 255;
2581  else if (G < 0)
2582  G = 0;
2583 
2584  B = Y1 + U5;
2585  if ((B >> 8) > 0)
2586  B = 255;
2587  else if (B < 0)
2588  B = 0;
2589 
2590  *rgb++ = (unsigned char)R;
2591  *rgb++ = (unsigned char)G;
2592  *rgb = (unsigned char)B;
2593  rgb = rgb + 3 * width - 5;
2594 
2595  //---
2596  R = Y2 + V2;
2597  if ((R >> 8) > 0)
2598  R = 255;
2599  else if (R < 0)
2600  R = 0;
2601 
2602  G = Y2 + UV;
2603  if ((G >> 8) > 0)
2604  G = 255;
2605  else if (G < 0)
2606  G = 0;
2607 
2608  B = Y2 + U5;
2609  if ((B >> 8) > 0)
2610  B = 255;
2611  else if (B < 0)
2612  B = 0;
2613 
2614  *rgb++ = (unsigned char)R;
2615  *rgb++ = (unsigned char)G;
2616  *rgb++ = (unsigned char)B;
2617 
2618  //---
2619  R = Y3 + V2;
2620  if ((R >> 8) > 0)
2621  R = 255;
2622  else if (R < 0)
2623  R = 0;
2624 
2625  G = Y3 + UV;
2626  if ((G >> 8) > 0)
2627  G = 255;
2628  else if (G < 0)
2629  G = 0;
2630 
2631  B = Y3 + U5;
2632  if ((B >> 8) > 0)
2633  B = 255;
2634  else if (B < 0)
2635  B = 0;
2636 
2637  *rgb++ = (unsigned char)R;
2638  *rgb++ = (unsigned char)G;
2639  *rgb = (unsigned char)B;
2640  rgb = rgb - 3 * width + 1;
2641  }
2642  yuv += width;
2643  rgb += 3 * width;
2644  }
2645 }
2646 
2657 void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2658 {
2659  // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2660  int U, V, R, G, B, V2, U5, UV;
2661  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2662  unsigned int size = width * height;
2663  unsigned char *iV = yuv + size;
2664  unsigned char *iU = yuv + 17 * size / 16;
2665  for (unsigned int i = 0; i < height / 4; i++) {
2666  for (unsigned int j = 0; j < width / 4; j++) {
2667  U = (int)((*iU++ - 128) * 0.354);
2668  U5 = 5 * U;
2669  V = (int)((*iV++ - 128) * 0.707);
2670  V2 = 2 * V;
2671  UV = -U - V;
2672  Y0 = *yuv++;
2673  Y1 = *yuv++;
2674  Y2 = *yuv++;
2675  Y3 = *yuv;
2676  yuv = yuv + width - 3;
2677  Y4 = *yuv++;
2678  Y5 = *yuv++;
2679  Y6 = *yuv++;
2680  Y7 = *yuv;
2681  yuv = yuv + width - 3;
2682  Y8 = *yuv++;
2683  Y9 = *yuv++;
2684  Y10 = *yuv++;
2685  Y11 = *yuv;
2686  yuv = yuv + width - 3;
2687  Y12 = *yuv++;
2688  Y13 = *yuv++;
2689  Y14 = *yuv++;
2690  Y15 = *yuv;
2691  yuv = yuv - 3 * width + 1;
2692 
2693  // Original equations
2694  // R = Y + 1.402 V
2695  // G = Y - 0.344 U - 0.714 V
2696  // B = Y + 1.772 U
2697  R = Y0 + V2;
2698  if ((R >> 8) > 0)
2699  R = 255;
2700  else if (R < 0)
2701  R = 0;
2702 
2703  G = Y0 + UV;
2704  if ((G >> 8) > 0)
2705  G = 255;
2706  else if (G < 0)
2707  G = 0;
2708 
2709  B = Y0 + U5;
2710  if ((B >> 8) > 0)
2711  B = 255;
2712  else if (B < 0)
2713  B = 0;
2714 
2715  *rgba++ = (unsigned char)R;
2716  *rgba++ = (unsigned char)G;
2717  *rgba++ = (unsigned char)B;
2718  *rgba++ = vpRGBa::alpha_default;
2719 
2720  //---
2721  R = Y1 + V2;
2722  if ((R >> 8) > 0)
2723  R = 255;
2724  else if (R < 0)
2725  R = 0;
2726 
2727  G = Y1 + UV;
2728  if ((G >> 8) > 0)
2729  G = 255;
2730  else if (G < 0)
2731  G = 0;
2732 
2733  B = Y1 + U5;
2734  if ((B >> 8) > 0)
2735  B = 255;
2736  else if (B < 0)
2737  B = 0;
2738 
2739  *rgba++ = (unsigned char)R;
2740  *rgba++ = (unsigned char)G;
2741  *rgba++ = (unsigned char)B;
2742  *rgba++ = vpRGBa::alpha_default;
2743 
2744  //---
2745  R = Y2 + V2;
2746  if ((R >> 8) > 0)
2747  R = 255;
2748  else if (R < 0)
2749  R = 0;
2750 
2751  G = Y2 + UV;
2752  if ((G >> 8) > 0)
2753  G = 255;
2754  else if (G < 0)
2755  G = 0;
2756 
2757  B = Y2 + U5;
2758  if ((B >> 8) > 0)
2759  B = 255;
2760  else if (B < 0)
2761  B = 0;
2762 
2763  *rgba++ = (unsigned char)R;
2764  *rgba++ = (unsigned char)G;
2765  *rgba++ = (unsigned char)B;
2766  *rgba++ = vpRGBa::alpha_default;
2767 
2768  //---
2769  R = Y3 + V2;
2770  if ((R >> 8) > 0)
2771  R = 255;
2772  else if (R < 0)
2773  R = 0;
2774 
2775  G = Y3 + UV;
2776  if ((G >> 8) > 0)
2777  G = 255;
2778  else if (G < 0)
2779  G = 0;
2780 
2781  B = Y3 + U5;
2782  if ((B >> 8) > 0)
2783  B = 255;
2784  else if (B < 0)
2785  B = 0;
2786 
2787  *rgba++ = (unsigned char)R;
2788  *rgba++ = (unsigned char)G;
2789  *rgba++ = (unsigned char)B;
2790  *rgba = vpRGBa::alpha_default;
2791  rgba = rgba + 4 * width - 15;
2792 
2793  R = Y4 + V2;
2794  if ((R >> 8) > 0)
2795  R = 255;
2796  else if (R < 0)
2797  R = 0;
2798 
2799  G = Y4 + UV;
2800  if ((G >> 8) > 0)
2801  G = 255;
2802  else if (G < 0)
2803  G = 0;
2804 
2805  B = Y4 + U5;
2806  if ((B >> 8) > 0)
2807  B = 255;
2808  else if (B < 0)
2809  B = 0;
2810 
2811  *rgba++ = (unsigned char)R;
2812  *rgba++ = (unsigned char)G;
2813  *rgba++ = (unsigned char)B;
2814  *rgba++ = vpRGBa::alpha_default;
2815 
2816  //---
2817  R = Y5 + V2;
2818  if ((R >> 8) > 0)
2819  R = 255;
2820  else if (R < 0)
2821  R = 0;
2822 
2823  G = Y5 + UV;
2824  if ((G >> 8) > 0)
2825  G = 255;
2826  else if (G < 0)
2827  G = 0;
2828 
2829  B = Y5 + U5;
2830  if ((B >> 8) > 0)
2831  B = 255;
2832  else if (B < 0)
2833  B = 0;
2834 
2835  *rgba++ = (unsigned char)R;
2836  *rgba++ = (unsigned char)G;
2837  *rgba++ = (unsigned char)B;
2838  *rgba++ = vpRGBa::alpha_default;
2839 
2840  //---
2841  R = Y6 + V2;
2842  if ((R >> 8) > 0)
2843  R = 255;
2844  else if (R < 0)
2845  R = 0;
2846 
2847  G = Y6 + UV;
2848  if ((G >> 8) > 0)
2849  G = 255;
2850  else if (G < 0)
2851  G = 0;
2852 
2853  B = Y6 + U5;
2854  if ((B >> 8) > 0)
2855  B = 255;
2856  else if (B < 0)
2857  B = 0;
2858 
2859  *rgba++ = (unsigned char)R;
2860  *rgba++ = (unsigned char)G;
2861  *rgba++ = (unsigned char)B;
2862  *rgba++ = vpRGBa::alpha_default;
2863 
2864  //---
2865  R = Y7 + V2;
2866  if ((R >> 8) > 0)
2867  R = 255;
2868  else if (R < 0)
2869  R = 0;
2870 
2871  G = Y7 + UV;
2872  if ((G >> 8) > 0)
2873  G = 255;
2874  else if (G < 0)
2875  G = 0;
2876 
2877  B = Y7 + U5;
2878  if ((B >> 8) > 0)
2879  B = 255;
2880  else if (B < 0)
2881  B = 0;
2882 
2883  *rgba++ = (unsigned char)R;
2884  *rgba++ = (unsigned char)G;
2885  *rgba++ = (unsigned char)B;
2886  *rgba = vpRGBa::alpha_default;
2887  rgba = rgba + 4 * width - 15;
2888 
2889  R = Y8 + V2;
2890  if ((R >> 8) > 0)
2891  R = 255;
2892  else if (R < 0)
2893  R = 0;
2894 
2895  G = Y8 + UV;
2896  if ((G >> 8) > 0)
2897  G = 255;
2898  else if (G < 0)
2899  G = 0;
2900 
2901  B = Y8 + U5;
2902  if ((B >> 8) > 0)
2903  B = 255;
2904  else if (B < 0)
2905  B = 0;
2906 
2907  *rgba++ = (unsigned char)R;
2908  *rgba++ = (unsigned char)G;
2909  *rgba++ = (unsigned char)B;
2910  *rgba++ = vpRGBa::alpha_default;
2911 
2912  //---
2913  R = Y9 + V2;
2914  if ((R >> 8) > 0)
2915  R = 255;
2916  else if (R < 0)
2917  R = 0;
2918 
2919  G = Y9 + UV;
2920  if ((G >> 8) > 0)
2921  G = 255;
2922  else if (G < 0)
2923  G = 0;
2924 
2925  B = Y9 + U5;
2926  if ((B >> 8) > 0)
2927  B = 255;
2928  else if (B < 0)
2929  B = 0;
2930 
2931  *rgba++ = (unsigned char)R;
2932  *rgba++ = (unsigned char)G;
2933  *rgba++ = (unsigned char)B;
2934  *rgba++ = vpRGBa::alpha_default;
2935 
2936  //---
2937  R = Y10 + V2;
2938  if ((R >> 8) > 0)
2939  R = 255;
2940  else if (R < 0)
2941  R = 0;
2942 
2943  G = Y10 + UV;
2944  if ((G >> 8) > 0)
2945  G = 255;
2946  else if (G < 0)
2947  G = 0;
2948 
2949  B = Y10 + U5;
2950  if ((B >> 8) > 0)
2951  B = 255;
2952  else if (B < 0)
2953  B = 0;
2954 
2955  *rgba++ = (unsigned char)R;
2956  *rgba++ = (unsigned char)G;
2957  *rgba++ = (unsigned char)B;
2958  *rgba++ = vpRGBa::alpha_default;
2959 
2960  //---
2961  R = Y11 + V2;
2962  if ((R >> 8) > 0)
2963  R = 255;
2964  else if (R < 0)
2965  R = 0;
2966 
2967  G = Y11 + UV;
2968  if ((G >> 8) > 0)
2969  G = 255;
2970  else if (G < 0)
2971  G = 0;
2972 
2973  B = Y11 + U5;
2974  if ((B >> 8) > 0)
2975  B = 255;
2976  else if (B < 0)
2977  B = 0;
2978 
2979  *rgba++ = (unsigned char)R;
2980  *rgba++ = (unsigned char)G;
2981  *rgba++ = (unsigned char)B;
2982  *rgba = vpRGBa::alpha_default;
2983  rgba = rgba + 4 * width - 15;
2984 
2985  R = Y12 + V2;
2986  if ((R >> 8) > 0)
2987  R = 255;
2988  else if (R < 0)
2989  R = 0;
2990 
2991  G = Y12 + UV;
2992  if ((G >> 8) > 0)
2993  G = 255;
2994  else if (G < 0)
2995  G = 0;
2996 
2997  B = Y12 + U5;
2998  if ((B >> 8) > 0)
2999  B = 255;
3000  else if (B < 0)
3001  B = 0;
3002 
3003  *rgba++ = (unsigned char)R;
3004  *rgba++ = (unsigned char)G;
3005  *rgba++ = (unsigned char)B;
3006  *rgba++ = vpRGBa::alpha_default;
3007 
3008  //---
3009  R = Y13 + V2;
3010  if ((R >> 8) > 0)
3011  R = 255;
3012  else if (R < 0)
3013  R = 0;
3014 
3015  G = Y13 + UV;
3016  if ((G >> 8) > 0)
3017  G = 255;
3018  else if (G < 0)
3019  G = 0;
3020 
3021  B = Y13 + U5;
3022  if ((B >> 8) > 0)
3023  B = 255;
3024  else if (B < 0)
3025  B = 0;
3026 
3027  *rgba++ = (unsigned char)R;
3028  *rgba++ = (unsigned char)G;
3029  *rgba++ = (unsigned char)B;
3030  *rgba++ = vpRGBa::alpha_default;
3031 
3032  //---
3033  R = Y14 + V2;
3034  if ((R >> 8) > 0)
3035  R = 255;
3036  else if (R < 0)
3037  R = 0;
3038 
3039  G = Y14 + UV;
3040  if ((G >> 8) > 0)
3041  G = 255;
3042  else if (G < 0)
3043  G = 0;
3044 
3045  B = Y14 + U5;
3046  if ((B >> 8) > 0)
3047  B = 255;
3048  else if (B < 0)
3049  B = 0;
3050 
3051  *rgba++ = (unsigned char)R;
3052  *rgba++ = (unsigned char)G;
3053  *rgba++ = (unsigned char)B;
3054  *rgba++ = vpRGBa::alpha_default;
3055 
3056  //---
3057  R = Y15 + V2;
3058  if ((R >> 8) > 0)
3059  R = 255;
3060  else if (R < 0)
3061  R = 0;
3062 
3063  G = Y15 + UV;
3064  if ((G >> 8) > 0)
3065  G = 255;
3066  else if (G < 0)
3067  G = 0;
3068 
3069  B = Y15 + U5;
3070  if ((B >> 8) > 0)
3071  B = 255;
3072  else if (B < 0)
3073  B = 0;
3074 
3075  *rgba++ = (unsigned char)R;
3076  *rgba++ = (unsigned char)G;
3077  *rgba++ = (unsigned char)B;
3078  *rgba = vpRGBa::alpha_default;
3079  rgba = rgba - 12 * width + 1;
3080  }
3081  yuv += 3 * width;
3082  rgba += 12 * width;
3083  }
3084 }
3085 
3093 void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
3094 {
3095  // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
3096  int U, V, R, G, B, V2, U5, UV;
3097  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
3098  unsigned int size = width * height;
3099  unsigned char *iV = yuv + size;
3100  unsigned char *iU = yuv + 17 * size / 16;
3101  for (unsigned int i = 0; i < height / 4; i++) {
3102  for (unsigned int j = 0; j < width / 4; j++) {
3103  U = (int)((*iU++ - 128) * 0.354);
3104  U5 = 5 * U;
3105  V = (int)((*iV++ - 128) * 0.707);
3106  V2 = 2 * V;
3107  UV = -U - V;
3108  Y0 = *yuv++;
3109  Y1 = *yuv++;
3110  Y2 = *yuv++;
3111  Y3 = *yuv;
3112  yuv = yuv + width - 3;
3113  Y4 = *yuv++;
3114  Y5 = *yuv++;
3115  Y6 = *yuv++;
3116  Y7 = *yuv;
3117  yuv = yuv + width - 3;
3118  Y8 = *yuv++;
3119  Y9 = *yuv++;
3120  Y10 = *yuv++;
3121  Y11 = *yuv;
3122  yuv = yuv + width - 3;
3123  Y12 = *yuv++;
3124  Y13 = *yuv++;
3125  Y14 = *yuv++;
3126  Y15 = *yuv;
3127  yuv = yuv - 3 * width + 1;
3128 
3129  // Original equations
3130  // R = Y + 1.402 V
3131  // G = Y - 0.344 U - 0.714 V
3132  // B = Y + 1.772 U
3133  R = Y0 + V2;
3134  if ((R >> 8) > 0)
3135  R = 255;
3136  else if (R < 0)
3137  R = 0;
3138 
3139  G = Y0 + UV;
3140  if ((G >> 8) > 0)
3141  G = 255;
3142  else if (G < 0)
3143  G = 0;
3144 
3145  B = Y0 + U5;
3146  if ((B >> 8) > 0)
3147  B = 255;
3148  else if (B < 0)
3149  B = 0;
3150 
3151  *rgb++ = (unsigned char)R;
3152  *rgb++ = (unsigned char)G;
3153  *rgb++ = (unsigned char)B;
3154 
3155  //---
3156  R = Y1 + V2;
3157  if ((R >> 8) > 0)
3158  R = 255;
3159  else if (R < 0)
3160  R = 0;
3161 
3162  G = Y1 + UV;
3163  if ((G >> 8) > 0)
3164  G = 255;
3165  else if (G < 0)
3166  G = 0;
3167 
3168  B = Y1 + U5;
3169  if ((B >> 8) > 0)
3170  B = 255;
3171  else if (B < 0)
3172  B = 0;
3173 
3174  *rgb++ = (unsigned char)R;
3175  *rgb++ = (unsigned char)G;
3176  *rgb++ = (unsigned char)B;
3177 
3178  //---
3179  R = Y2 + V2;
3180  if ((R >> 8) > 0)
3181  R = 255;
3182  else if (R < 0)
3183  R = 0;
3184 
3185  G = Y2 + UV;
3186  if ((G >> 8) > 0)
3187  G = 255;
3188  else if (G < 0)
3189  G = 0;
3190 
3191  B = Y2 + U5;
3192  if ((B >> 8) > 0)
3193  B = 255;
3194  else if (B < 0)
3195  B = 0;
3196 
3197  *rgb++ = (unsigned char)R;
3198  *rgb++ = (unsigned char)G;
3199  *rgb++ = (unsigned char)B;
3200 
3201  //---
3202  R = Y3 + V2;
3203  if ((R >> 8) > 0)
3204  R = 255;
3205  else if (R < 0)
3206  R = 0;
3207 
3208  G = Y3 + UV;
3209  if ((G >> 8) > 0)
3210  G = 255;
3211  else if (G < 0)
3212  G = 0;
3213 
3214  B = Y3 + U5;
3215  if ((B >> 8) > 0)
3216  B = 255;
3217  else if (B < 0)
3218  B = 0;
3219 
3220  *rgb++ = (unsigned char)R;
3221  *rgb++ = (unsigned char)G;
3222  *rgb = (unsigned char)B;
3223  rgb = rgb + 3 * width - 11;
3224 
3225  R = Y4 + V2;
3226  if ((R >> 8) > 0)
3227  R = 255;
3228  else if (R < 0)
3229  R = 0;
3230 
3231  G = Y4 + UV;
3232  if ((G >> 8) > 0)
3233  G = 255;
3234  else if (G < 0)
3235  G = 0;
3236 
3237  B = Y4 + U5;
3238  if ((B >> 8) > 0)
3239  B = 255;
3240  else if (B < 0)
3241  B = 0;
3242 
3243  *rgb++ = (unsigned char)R;
3244  *rgb++ = (unsigned char)G;
3245  *rgb++ = (unsigned char)B;
3246 
3247  //---
3248  R = Y5 + V2;
3249  if ((R >> 8) > 0)
3250  R = 255;
3251  else if (R < 0)
3252  R = 0;
3253 
3254  G = Y5 + UV;
3255  if ((G >> 8) > 0)
3256  G = 255;
3257  else if (G < 0)
3258  G = 0;
3259 
3260  B = Y5 + U5;
3261  if ((B >> 8) > 0)
3262  B = 255;
3263  else if (B < 0)
3264  B = 0;
3265 
3266  *rgb++ = (unsigned char)R;
3267  *rgb++ = (unsigned char)G;
3268  *rgb++ = (unsigned char)B;
3269 
3270  //---
3271  R = Y6 + V2;
3272  if ((R >> 8) > 0)
3273  R = 255;
3274  else if (R < 0)
3275  R = 0;
3276 
3277  G = Y6 + UV;
3278  if ((G >> 8) > 0)
3279  G = 255;
3280  else if (G < 0)
3281  G = 0;
3282 
3283  B = Y6 + U5;
3284  if ((B >> 8) > 0)
3285  B = 255;
3286  else if (B < 0)
3287  B = 0;
3288 
3289  *rgb++ = (unsigned char)R;
3290  *rgb++ = (unsigned char)G;
3291  *rgb++ = (unsigned char)B;
3292 
3293  //---
3294  R = Y7 + V2;
3295  if ((R >> 8) > 0)
3296  R = 255;
3297  else if (R < 0)
3298  R = 0;
3299 
3300  G = Y7 + UV;
3301  if ((G >> 8) > 0)
3302  G = 255;
3303  else if (G < 0)
3304  G = 0;
3305 
3306  B = Y7 + U5;
3307  if ((B >> 8) > 0)
3308  B = 255;
3309  else if (B < 0)
3310  B = 0;
3311 
3312  *rgb++ = (unsigned char)R;
3313  *rgb++ = (unsigned char)G;
3314  *rgb = (unsigned char)B;
3315  rgb = rgb + 3 * width - 11;
3316 
3317  R = Y8 + V2;
3318  if ((R >> 8) > 0)
3319  R = 255;
3320  else if (R < 0)
3321  R = 0;
3322 
3323  G = Y8 + UV;
3324  if ((G >> 8) > 0)
3325  G = 255;
3326  else if (G < 0)
3327  G = 0;
3328 
3329  B = Y8 + U5;
3330  if ((B >> 8) > 0)
3331  B = 255;
3332  else if (B < 0)
3333  B = 0;
3334 
3335  *rgb++ = (unsigned char)R;
3336  *rgb++ = (unsigned char)G;
3337  *rgb++ = (unsigned char)B;
3338 
3339  //---
3340  R = Y9 + V2;
3341  if ((R >> 8) > 0)
3342  R = 255;
3343  else if (R < 0)
3344  R = 0;
3345 
3346  G = Y9 + UV;
3347  if ((G >> 8) > 0)
3348  G = 255;
3349  else if (G < 0)
3350  G = 0;
3351 
3352  B = Y9 + U5;
3353  if ((B >> 8) > 0)
3354  B = 255;
3355  else if (B < 0)
3356  B = 0;
3357 
3358  *rgb++ = (unsigned char)R;
3359  *rgb++ = (unsigned char)G;
3360  *rgb++ = (unsigned char)B;
3361 
3362  //---
3363  R = Y10 + V2;
3364  if ((R >> 8) > 0)
3365  R = 255;
3366  else if (R < 0)
3367  R = 0;
3368 
3369  G = Y10 + UV;
3370  if ((G >> 8) > 0)
3371  G = 255;
3372  else if (G < 0)
3373  G = 0;
3374 
3375  B = Y10 + U5;
3376  if ((B >> 8) > 0)
3377  B = 255;
3378  else if (B < 0)
3379  B = 0;
3380 
3381  *rgb++ = (unsigned char)R;
3382  *rgb++ = (unsigned char)G;
3383  *rgb++ = (unsigned char)B;
3384 
3385  //---
3386  R = Y11 + V2;
3387  if ((R >> 8) > 0)
3388  R = 255;
3389  else if (R < 0)
3390  R = 0;
3391 
3392  G = Y11 + UV;
3393  if ((G >> 8) > 0)
3394  G = 255;
3395  else if (G < 0)
3396  G = 0;
3397 
3398  B = Y11 + U5;
3399  if ((B >> 8) > 0)
3400  B = 255;
3401  else if (B < 0)
3402  B = 0;
3403 
3404  *rgb++ = (unsigned char)R;
3405  *rgb++ = (unsigned char)G;
3406  *rgb = (unsigned char)B;
3407  rgb = rgb + 3 * width - 11;
3408 
3409  R = Y12 + V2;
3410  if ((R >> 8) > 0)
3411  R = 255;
3412  else if (R < 0)
3413  R = 0;
3414 
3415  G = Y12 + UV;
3416  if ((G >> 8) > 0)
3417  G = 255;
3418  else if (G < 0)
3419  G = 0;
3420 
3421  B = Y12 + U5;
3422  if ((B >> 8) > 0)
3423  B = 255;
3424  else if (B < 0)
3425  B = 0;
3426 
3427  *rgb++ = (unsigned char)R;
3428  *rgb++ = (unsigned char)G;
3429  *rgb++ = (unsigned char)B;
3430 
3431  //---
3432  R = Y13 + V2;
3433  if ((R >> 8) > 0)
3434  R = 255;
3435  else if (R < 0)
3436  R = 0;
3437 
3438  G = Y13 + UV;
3439  if ((G >> 8) > 0)
3440  G = 255;
3441  else if (G < 0)
3442  G = 0;
3443 
3444  B = Y13 + U5;
3445  if ((B >> 8) > 0)
3446  B = 255;
3447  else if (B < 0)
3448  B = 0;
3449 
3450  *rgb++ = (unsigned char)R;
3451  *rgb++ = (unsigned char)G;
3452  *rgb++ = (unsigned char)B;
3453 
3454  //---
3455  R = Y14 + V2;
3456  if ((R >> 8) > 0)
3457  R = 255;
3458  else if (R < 0)
3459  R = 0;
3460 
3461  G = Y14 + UV;
3462  if ((G >> 8) > 0)
3463  G = 255;
3464  else if (G < 0)
3465  G = 0;
3466 
3467  B = Y14 + U5;
3468  if ((B >> 8) > 0)
3469  B = 255;
3470  else if (B < 0)
3471  B = 0;
3472 
3473  *rgb++ = (unsigned char)R;
3474  *rgb++ = (unsigned char)G;
3475  *rgb++ = (unsigned char)B;
3476 
3477  //---
3478  R = Y15 + V2;
3479  if ((R >> 8) > 0)
3480  R = 255;
3481  else if (R < 0)
3482  R = 0;
3483 
3484  G = Y15 + UV;
3485  if ((G >> 8) > 0)
3486  G = 255;
3487  else if (G < 0)
3488  G = 0;
3489 
3490  B = Y15 + U5;
3491  if ((B >> 8) > 0)
3492  B = 255;
3493  else if (B < 0)
3494  B = 0;
3495 
3496  *rgb++ = (unsigned char)R;
3497  *rgb++ = (unsigned char)G;
3498  *rgb++ = (unsigned char)B;
3499  rgb = rgb - 9 * width + 1;
3500  }
3501  yuv += 3 * width;
3502  rgb += 9 * width;
3503  }
3504 }
3505 
3515 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
3516 {
3517  RGBToRGBa(rgb, rgba, size, 1, false);
3518 }
3519 
3535 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int width, unsigned int height,
3536  bool flip)
3537 {
3538  if (!flip) {
3539  SimdBgrToBgra(rgb, width, height, width * 3, rgba, width * 4, vpRGBa::alpha_default);
3540  } else {
3541  // if we have to flip the image, we start from the end last scanline so the
3542  // step is negative
3543  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3544 
3545  // starting source address = last line if we need to flip the image
3546  unsigned char *src = (flip) ? (rgb + (width * height * 3) + lineStep) : rgb;
3547 
3548  unsigned int j = 0;
3549  unsigned int i = 0;
3550 
3551  for (i = 0; i < height; i++) {
3552  unsigned char *line = src;
3553  for (j = 0; j < width; j++) {
3554  *rgba++ = *(line++);
3555  *rgba++ = *(line++);
3556  *rgba++ = *(line++);
3557  *rgba++ = vpRGBa::alpha_default;
3558  }
3559  // go to the next line
3560  src += lineStep;
3561  }
3562  }
3563 }
3564 
3577 void vpImageConvert::RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
3578 {
3579  SimdBgraToBgr(rgba, size, 1, size * 4, rgb, size * 3);
3580 }
3581 
3594 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
3595 {
3596  RGBToGrey(rgb, grey, size, 1, false);
3597 }
3598 
3612 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height,
3613  bool flip)
3614 {
3615  if (!flip) {
3616  SimdRgbToGray(rgb, width, height, width * 3, grey, width);
3617  } else {
3618  // if we have to flip the image, we start from the end last scanline so
3619  // the step is negative
3620  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3621 
3622  // starting source address = last line if we need to flip the image
3623  unsigned char *src = (flip) ? rgb + (width * height * 3) + lineStep : rgb;
3624 
3625  unsigned int j = 0;
3626  unsigned int i = 0;
3627 
3628  unsigned r, g, b;
3629 
3630  for (i = 0; i < height; i++) {
3631  unsigned char *line = src;
3632  for (j = 0; j < width; j++) {
3633  r = *(line++);
3634  g = *(line++);
3635  b = *(line++);
3636  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3637  }
3638 
3639  // go to the next line
3640  src += lineStep;
3641  }
3642  }
3643 }
3644 
3660 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height,
3661  unsigned int
3662 #if defined _OPENMP
3663  nThreads
3664 #endif
3665 )
3666 {
3667 #if defined _OPENMP
3668  if (nThreads > 0) {
3669  omp_set_num_threads(static_cast<int>(nThreads));
3670  }
3671 #pragma omp parallel for
3672 #endif
3673  for (int i = 0; i < static_cast<int>(height); i++) {
3674  SimdRgbaToGray(rgba + i * width * 4, width, 1, width * 4, grey + i * width, width);
3675  }
3676 }
3677 
3692 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
3693 {
3694  SimdRgbaToGray(rgba, size, 1, size * 4, grey, size);
3695 }
3696 
3708 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
3709 {
3710  SimdGrayToBgra(grey, width, height, width, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3711 }
3712 
3725 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
3726 {
3727  GreyToRGBa(grey, rgba, size, 1);
3728 }
3729 
3740 void vpImageConvert::GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
3741 {
3742  SimdGrayToBgr(grey, size, 1, size, rgb, size * 3);
3743 }
3744 
3760 void vpImageConvert::BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height,
3761  bool flip)
3762 {
3763  if (!flip) {
3764  SimdRgbToBgra(bgr, width, height, width * 3, rgba, width * sizeof(vpRGBa), vpRGBa::alpha_default);
3765  } else {
3766  // if we have to flip the image, we start from the end last scanline so the
3767  // step is negative
3768  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3769 
3770  // starting source address = last line if we need to flip the image
3771  unsigned char *src = (flip) ? (bgr + (width * height * 3) + lineStep) : bgr;
3772 
3773  for (unsigned int i = 0; i < height; i++) {
3774  unsigned char *line = src;
3775  for (unsigned int j = 0; j < width; j++) {
3776  *rgba++ = *(line + 2);
3777  *rgba++ = *(line + 1);
3778  *rgba++ = *(line + 0);
3779  *rgba++ = vpRGBa::alpha_default;
3780 
3781  line += 3;
3782  }
3783  // go to the next line
3784  src += lineStep;
3785  }
3786  }
3787 }
3788 
3803 void vpImageConvert::BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height,
3804  bool flip)
3805 {
3806  if (!flip) {
3807  SimdBgraToRgba(bgra, width, height, width * 4, rgba, width * 4);
3808  } else {
3809  // if we have to flip the image, we start from the end last scanline so the
3810  // step is negative
3811  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3812 
3813  // starting source address = last line if we need to flip the image
3814  unsigned char *src = (flip) ? (bgra + (width * height * 4) + lineStep) : bgra;
3815 
3816  for (unsigned int i = 0; i < height; i++) {
3817  unsigned char *line = src;
3818  for (unsigned int j = 0; j < width; j++) {
3819  *rgba++ = *(line + 2);
3820  *rgba++ = *(line + 1);
3821  *rgba++ = *(line + 0);
3822  *rgba++ = *(line + 3);
3823 
3824  line += 4;
3825  }
3826  // go to the next line
3827  src += lineStep;
3828  }
3829  }
3830 }
3831 
3846 void vpImageConvert::BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height,
3847  bool flip,
3848  unsigned int
3849 #if defined _OPENMP
3850  nThreads
3851 #endif
3852 )
3853 {
3854  if (!flip) {
3855 #if defined _OPENMP
3856  if (nThreads > 0) {
3857  omp_set_num_threads(static_cast<int>(nThreads));
3858  }
3859 #pragma omp parallel for
3860 #endif
3861  for (int i = 0; i < static_cast<int>(height); i++) {
3862  SimdBgrToGray(bgr + i * width * 3, width, 1, width * 3, grey + i * width, width);
3863  }
3864  } else {
3865  // if we have to flip the image, we start from the end last scanline so
3866  // the step is negative
3867  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3868 
3869  // starting source address = last line if we need to flip the image
3870  unsigned char *src = (flip) ? bgr + (width * height * 3) + lineStep : bgr;
3871 
3872  for (unsigned int i = 0; i < height; i++) {
3873  unsigned char *line = src;
3874  for (unsigned int j = 0; j < width; j++) {
3875  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3876  line += 3;
3877  }
3878 
3879  // go to the next line
3880  src += lineStep;
3881  }
3882  }
3883 }
3884 
3899 void vpImageConvert::BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height,
3900  bool flip,
3901  unsigned int
3902 #if defined _OPENMP
3903  nThreads
3904 #endif
3905 )
3906 {
3907  if (!flip) {
3908 #if defined _OPENMP
3909  if (nThreads > 0) {
3910  omp_set_num_threads(static_cast<int>(nThreads));
3911  }
3912 #pragma omp parallel for
3913 #endif
3914  for (int i = 0; i < static_cast<int>(height); i++) {
3915  SimdBgraToGray(bgra + i * width * 4, width, 1, width * 4, grey + i * width, width);
3916  }
3917  } else {
3918  // if we have to flip the image, we start from the end last scanline so
3919  // the step is negative
3920  int lineStep = (flip) ? -(int)(width * 4) : (int)(width * 4);
3921 
3922  // starting source address = last line if we need to flip the image
3923  unsigned char *src = (flip) ? bgra + (width * height * 4) + lineStep : bgra;
3924 
3925  for (unsigned int i = 0; i < height; i++) {
3926  unsigned char *line = src;
3927  for (unsigned int j = 0; j < width; j++) {
3928  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3929  line += 4;
3930  }
3931 
3932  // go to the next line
3933  src += lineStep;
3934  }
3935  }
3936 }
3937 
3941 void vpImageConvert::computeYCbCrLUT()
3942 {
3943  if (YCbCrLUTcomputed == false) {
3944  int index = 256;
3945 
3946  while (index--) {
3947 
3948  int aux = index - 128;
3949  vpImageConvert::vpCrr[index] = (int)(364.6610 * aux) >> 8;
3950  vpImageConvert::vpCgb[index] = (int)(-89.8779 * aux) >> 8;
3951  vpImageConvert::vpCgr[index] = (int)(-185.8154 * aux) >> 8;
3952  vpImageConvert::vpCbb[index] = (int)(460.5724 * aux) >> 8;
3953  }
3954 
3955  YCbCrLUTcomputed = true;
3956  }
3957 }
3958 
3980 void vpImageConvert::YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
3981 {
3982  unsigned char *cbv;
3983  unsigned char *crv;
3984  unsigned char *pt_ycbcr = ycbcr;
3985  unsigned char *pt_rgb = rgb;
3986  cbv = pt_ycbcr + 1;
3987  crv = pt_ycbcr + 3;
3988 
3989  vpImageConvert::computeYCbCrLUT();
3990 
3991  int col = 0;
3992 
3993  while (size--) {
3994  int val_r, val_g, val_b;
3995  if (!(col++ % 2)) {
3996  cbv = pt_ycbcr + 1;
3997  crv = pt_ycbcr + 3;
3998  }
3999 
4000  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4001  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4002  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4003 
4004  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4005 
4006  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4007  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4008  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4009 
4010  pt_ycbcr += 2;
4011  }
4012 }
4013 
4039 void vpImageConvert::YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgba, unsigned int size)
4040 {
4041  unsigned char *cbv;
4042  unsigned char *crv;
4043  unsigned char *pt_ycbcr = ycbcr;
4044  unsigned char *pt_rgba = rgba;
4045  cbv = pt_ycbcr + 1;
4046  crv = pt_ycbcr + 3;
4047 
4048  vpImageConvert::computeYCbCrLUT();
4049 
4050  int col = 0;
4051 
4052  while (size--) {
4053  int val_r, val_g, val_b;
4054  if (!(col++ % 2)) {
4055  cbv = pt_ycbcr + 1;
4056  crv = pt_ycbcr + 3;
4057  }
4058 
4059  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4060  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4061  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4062 
4063  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4064 
4065  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4066  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4067  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4068  *pt_rgba++ = vpRGBa::alpha_default;
4069 
4070  pt_ycbcr += 2;
4071  }
4072 }
4073 
4093 void vpImageConvert::YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
4094 {
4095  unsigned int i = 0, j = 0;
4096 
4097  while (j < size * 2) {
4098  grey[i++] = ycbcr[j];
4099  grey[i++] = ycbcr[j + 2];
4100  j += 4;
4101  }
4102 }
4103 
4125 void vpImageConvert::YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
4126 {
4127  unsigned char *cbv;
4128  unsigned char *crv;
4129  unsigned char *pt_ycbcr = ycrcb;
4130  unsigned char *pt_rgb = rgb;
4131  crv = pt_ycbcr + 1;
4132  cbv = pt_ycbcr + 3;
4133 
4134  vpImageConvert::computeYCbCrLUT();
4135 
4136  int col = 0;
4137 
4138  while (size--) {
4139  int val_r, val_g, val_b;
4140  if (!(col++ % 2)) {
4141  crv = pt_ycbcr + 1;
4142  cbv = pt_ycbcr + 3;
4143  }
4144 
4145  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4146  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4147  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4148 
4149  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4150 
4151  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4152  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4153  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4154 
4155  pt_ycbcr += 2;
4156  }
4157 }
4158 
4183 void vpImageConvert::YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgba, unsigned int size)
4184 {
4185  unsigned char *cbv;
4186  unsigned char *crv;
4187  unsigned char *pt_ycbcr = ycrcb;
4188  unsigned char *pt_rgba = rgba;
4189  crv = pt_ycbcr + 1;
4190  cbv = pt_ycbcr + 3;
4191 
4192  vpImageConvert::computeYCbCrLUT();
4193 
4194  int col = 0;
4195 
4196  while (size--) {
4197  int val_r, val_g, val_b;
4198  if (!(col++ % 2)) {
4199  crv = pt_ycbcr + 1;
4200  cbv = pt_ycbcr + 3;
4201  }
4202 
4203  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4204  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4205  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4206 
4207  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4208 
4209  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4210  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4211  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4212  *pt_rgba++ = vpRGBa::alpha_default;
4213 
4214  pt_ycbcr += 2;
4215  }
4216 }
4217 
4258 {
4259  if (src.getSize() > 0) {
4260  if (pR) {
4261  pR->resize(src.getHeight(), src.getWidth());
4262  }
4263  if (pG) {
4264  pG->resize(src.getHeight(), src.getWidth());
4265  }
4266  if (pB) {
4267  pB->resize(src.getHeight(), src.getWidth());
4268  }
4269  if (pa) {
4270  pa->resize(src.getHeight(), src.getWidth());
4271  }
4272 
4273  unsigned char *ptrR = pR ? pR->bitmap : new unsigned char[src.getSize()];
4274  unsigned char *ptrG = pG ? pG->bitmap : new unsigned char[src.getSize()];
4275  unsigned char *ptrB = pB ? pB->bitmap : new unsigned char[src.getSize()];
4276  unsigned char *ptrA = pa ? pa->bitmap : new unsigned char[src.getSize()];
4277 
4278  SimdDeinterleaveBgra(reinterpret_cast<unsigned char *>(src.bitmap), src.getWidth() * sizeof(vpRGBa), src.getWidth(),
4279  src.getHeight(), ptrR, src.getWidth(), ptrG, src.getWidth(), ptrB, src.getWidth(), ptrA,
4280  src.getWidth());
4281 
4282  if (!pR) {
4283  delete[] ptrR;
4284  }
4285  if (!pG) {
4286  delete[] ptrG;
4287  }
4288  if (!pB) {
4289  delete[] ptrB;
4290  }
4291  if (!pa) {
4292  delete[] ptrA;
4293  }
4294  }
4295 }
4296 
4309 {
4310  // Check if the input channels have all the same dimensions
4311  std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
4312  if (R != NULL) {
4313  mapOfWidths[R->getWidth()]++;
4314  mapOfHeights[R->getHeight()]++;
4315  }
4316 
4317  if (G != NULL) {
4318  mapOfWidths[G->getWidth()]++;
4319  mapOfHeights[G->getHeight()]++;
4320  }
4321 
4322  if (B != NULL) {
4323  mapOfWidths[B->getWidth()]++;
4324  mapOfHeights[B->getHeight()]++;
4325  }
4326 
4327  if (a != NULL) {
4328  mapOfWidths[a->getWidth()]++;
4329  mapOfHeights[a->getHeight()]++;
4330  }
4331 
4332  if (mapOfWidths.size() == 1 && mapOfHeights.size() == 1) {
4333  unsigned int width = mapOfWidths.begin()->first;
4334  unsigned int height = mapOfHeights.begin()->first;
4335 
4336  RGBa.resize(height, width);
4337 
4338  if (R != NULL && G != NULL && B != NULL && a != NULL) {
4339  SimdInterleaveBgra(R->bitmap, width, G->bitmap, width, B->bitmap, width, a->bitmap, width, width, height,
4340  reinterpret_cast<uint8_t *>(RGBa.bitmap), width * sizeof(vpRGBa));
4341  } else {
4342  unsigned int size = width * height;
4343  for (unsigned int i = 0; i < size; i++) {
4344  if (R != NULL) {
4345  RGBa.bitmap[i].R = R->bitmap[i];
4346  }
4347 
4348  if (G != NULL) {
4349  RGBa.bitmap[i].G = G->bitmap[i];
4350  }
4351 
4352  if (B != NULL) {
4353  RGBa.bitmap[i].B = B->bitmap[i];
4354  }
4355 
4356  if (a != NULL) {
4357  RGBa.bitmap[i].A = a->bitmap[i];
4358  }
4359  }
4360  }
4361  } else {
4362  throw vpException(vpException::dimensionError, "Mismatched dimensions!");
4363  }
4364 }
4365 
4376 void vpImageConvert::MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
4377 {
4378  int i = (((int)size) << 1) - 1;
4379  int j = (int)size - 1;
4380 
4381  while (i >= 0) {
4382  int y = grey16[i--];
4383  grey[j--] = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4384  }
4385 }
4386 
4398 void vpImageConvert::MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
4399 {
4400  int i = (((int)size) << 1) - 1;
4401  int j = (int)(size * 4 - 1);
4402 
4403  while (i >= 0) {
4404  int y = grey16[i--];
4405  unsigned char v = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4406  rgba[j--] = vpRGBa::alpha_default;
4407  rgba[j--] = v;
4408  rgba[j--] = v;
4409  rgba[j--] = v;
4410  }
4411 }
4412 
4423 void vpImageConvert::HSV2RGB(const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
4424  unsigned int size, unsigned int step)
4425 {
4426  for (unsigned int i = 0; i < size; i++) {
4427  double hue = hue_[i], saturation = saturation_[i], value = value_[i];
4428 
4429  if (vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
4430  hue = value;
4431  saturation = value;
4432  } else {
4433  double h = hue * 6.0;
4434  double s = saturation;
4435  double v = value;
4436 
4437  if (vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
4438  h = 0.0;
4439  }
4440 
4441  double f = h - (int)h;
4442  double p = v * (1.0 - s);
4443  double q = v * (1.0 - s * f);
4444  double t = v * (1.0 - s * (1.0 - f));
4445 
4446  switch ((int)h) {
4447  case 0:
4448  hue = v;
4449  saturation = t;
4450  value = p;
4451  break;
4452 
4453  case 1:
4454  hue = q;
4455  saturation = v;
4456  value = p;
4457  break;
4458 
4459  case 2:
4460  hue = p;
4461  saturation = v;
4462  value = t;
4463  break;
4464 
4465  case 3:
4466  hue = p;
4467  saturation = q;
4468  value = v;
4469  break;
4470 
4471  case 4:
4472  hue = t;
4473  saturation = p;
4474  value = v;
4475  break;
4476 
4477  default: // case 5:
4478  hue = v;
4479  saturation = p;
4480  value = q;
4481  break;
4482  }
4483  }
4484 
4485  rgb[i * step] = (unsigned char)vpMath::round(hue * 255.0);
4486  rgb[i * step + 1] = (unsigned char)vpMath::round(saturation * 255.0);
4487  rgb[i * step + 2] = (unsigned char)vpMath::round(value * 255.0);
4488  if (step == 4) // alpha
4489  rgb[i * step + 3] = vpRGBa::alpha_default;
4490  }
4491 }
4492 
4503 void vpImageConvert::RGB2HSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4504  unsigned int size, unsigned int step)
4505 {
4506  for (unsigned int i = 0; i < size; i++) {
4507  double red, green, blue;
4508  double h, s, v;
4509  double min, max;
4510 
4511  red = rgb[i * step] / 255.0;
4512  green = rgb[i * step + 1] / 255.0;
4513  blue = rgb[i * step + 2] / 255.0;
4514 
4515  if (red > green) {
4516  max = ((std::max))(red, blue);
4517  min = ((std::min))(green, blue);
4518  } else {
4519  max = ((std::max))(green, blue);
4520  min = ((std::min))(red, blue);
4521  }
4522 
4523  v = max;
4524 
4525  if (!vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
4526  s = (max - min) / max;
4527  } else {
4528  s = 0.0;
4529  }
4530 
4531  if (vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
4532  h = 0.0;
4533  } else {
4534  double delta = max - min;
4535  if (vpMath::equal(delta, 0.0, std::numeric_limits<double>::epsilon())) {
4536  delta = 1.0;
4537  }
4538 
4539  if (vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
4540  h = (green - blue) / delta;
4541  } else if (vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
4542  h = 2 + (blue - red) / delta;
4543  } else {
4544  h = 4 + (red - green) / delta;
4545  }
4546 
4547  h /= 6.0;
4548  if (h < 0.0) {
4549  h += 1.0;
4550  } else if (h > 1.0) {
4551  h -= 1.0;
4552  }
4553  }
4554 
4555  hue[i] = h;
4556  saturation[i] = s;
4557  value[i] = v;
4558  }
4559 }
4560 
4573 void vpImageConvert::HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba,
4574  unsigned int size)
4575 {
4576  vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
4577 }
4578 
4591 void vpImageConvert::HSVToRGBa(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4592  unsigned char *rgba, unsigned int size)
4593 {
4594  for (unsigned int i = 0; i < size; i++) {
4595  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4596 
4597  vpImageConvert::HSVToRGBa(&h, &s, &v, (rgba + i * 4), 1);
4598  }
4599 }
4600 
4613 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value,
4614  unsigned int size)
4615 {
4616  vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
4617 }
4618 
4630 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
4631  unsigned char *value, unsigned int size)
4632 {
4633  for (unsigned int i = 0; i < size; i++) {
4634  double h, s, v;
4635  vpImageConvert::RGBaToHSV((rgba + i * 4), &h, &s, &v, 1);
4636 
4637  hue[i] = (unsigned char)(255.0 * h);
4638  saturation[i] = (unsigned char)(255.0 * s);
4639  value[i] = (unsigned char)(255.0 * v);
4640  }
4641 }
4642 
4653 void vpImageConvert::HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb,
4654  unsigned int size)
4655 {
4656  vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
4657 }
4658 
4669 void vpImageConvert::HSVToRGB(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4670  unsigned char *rgb, unsigned int size)
4671 {
4672  for (unsigned int i = 0; i < size; i++) {
4673  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4674 
4675  vpImageConvert::HSVToRGB(&h, &s, &v, (rgb + i * 3), 1);
4676  }
4677 }
4678 
4690 void vpImageConvert::RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4691  unsigned int size)
4692 {
4693  vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
4694 }
4695 
4706 void vpImageConvert::RGBToHSV(const unsigned char *rgb, unsigned char *hue, unsigned char *saturation,
4707  unsigned char *value, unsigned int size)
4708 {
4709  for (unsigned int i = 0; i < size; i++) {
4710  double h, s, v;
4711 
4712  vpImageConvert::RGBToHSV((rgb + i * 3), &h, &s, &v, 1);
4713 
4714  hue[i] = (unsigned char)(255.0 * h);
4715  saturation[i] = (unsigned char)(255.0 * s);
4716  value[i] = (unsigned char)(255.0 * v);
4717  }
4718 }
4719 
4720 // Bilinear
4721 
4734 void vpImageConvert::demosaicBGGRToRGBaBilinear(const uint8_t *bggr, uint8_t *rgba, unsigned int width,
4735  unsigned int height, unsigned int nThreads)
4736 {
4737  demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
4738 }
4739 
4752 void vpImageConvert::demosaicBGGRToRGBaBilinear(const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4753  unsigned int height, unsigned int nThreads)
4754 {
4755  demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
4756 }
4757 
4770 void vpImageConvert::demosaicGBRGToRGBaBilinear(const uint8_t *gbrg, uint8_t *rgba, unsigned int width,
4771  unsigned int height, unsigned int nThreads)
4772 {
4773  demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
4774 }
4775 
4788 void vpImageConvert::demosaicGBRGToRGBaBilinear(const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4789  unsigned int height, unsigned int nThreads)
4790 {
4791  demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
4792 }
4793 
4806 void vpImageConvert::demosaicGRBGToRGBaBilinear(const uint8_t *grbg, uint8_t *rgba, unsigned int width,
4807  unsigned int height, unsigned int nThreads)
4808 {
4809  demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
4810 }
4811 
4824 void vpImageConvert::demosaicGRBGToRGBaBilinear(const uint16_t *grbg, uint16_t *rgba, unsigned int width,
4825  unsigned int height, unsigned int nThreads)
4826 {
4827  demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
4828 }
4829 
4842 void vpImageConvert::demosaicRGGBToRGBaBilinear(const uint8_t *rggb, uint8_t *rgba, unsigned int width,
4843  unsigned int height, unsigned int nThreads)
4844 {
4845  demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
4846 }
4847 
4860 void vpImageConvert::demosaicRGGBToRGBaBilinear(const uint16_t *rggb, uint16_t *rgba, unsigned int width,
4861  unsigned int height, unsigned int nThreads)
4862 {
4863  demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
4864 }
4865 
4866 // Malvar
4867 
4880 void vpImageConvert::demosaicBGGRToRGBaMalvar(const uint8_t *bggr, uint8_t *rgba, unsigned int width,
4881  unsigned int height, unsigned int nThreads)
4882 {
4883  demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
4884 }
4885 
4898 void vpImageConvert::demosaicBGGRToRGBaMalvar(const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4899  unsigned int height, unsigned int nThreads)
4900 {
4901  demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
4902 }
4903 
4916 void vpImageConvert::demosaicGBRGToRGBaMalvar(const uint8_t *gbrg, uint8_t *rgba, unsigned int width,
4917  unsigned int height, unsigned int nThreads)
4918 {
4919  demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
4920 }
4921 
4934 void vpImageConvert::demosaicGBRGToRGBaMalvar(const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4935  unsigned int height, unsigned int nThreads)
4936 {
4937  demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
4938 }
4939 
4952 void vpImageConvert::demosaicGRBGToRGBaMalvar(const uint8_t *grbg, uint8_t *rgba, unsigned int width,
4953  unsigned int height, unsigned int nThreads)
4954 {
4955  demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
4956 }
4957 
4970 void vpImageConvert::demosaicGRBGToRGBaMalvar(const uint16_t *grbg, uint16_t *rgba, unsigned int width,
4971  unsigned int height, unsigned int nThreads)
4972 {
4973  demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
4974 }
4975 
4988 void vpImageConvert::demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width,
4989  unsigned int height, unsigned int nThreads)
4990 {
4991  demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
4992 }
4993 
5006 void vpImageConvert::demosaicRGGBToRGBaMalvar(const uint16_t *rggb, uint16_t *rgba, unsigned int width,
5007  unsigned int height, unsigned int nThreads)
5008 {
5009  demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
5010 }
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
@ dimensionError
Bad dimension.
Definition: vpException.h:95
@ fatalError
Fatal error.
Definition: vpException.h:96
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:247
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:800
unsigned int getSize() const
Definition: vpImage.h:228
unsigned int getCols() const
Definition: vpImage.h:180
Type * bitmap
points toward the bitmap
Definition: vpImage.h:144
unsigned int getHeight() const
Definition: vpImage.h:189
unsigned int getRows() const
Definition: vpImage.h:219
void getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal=true) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:1055
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:367
static int round(double x)
Definition: vpMath.h:321
Definition: vpRGBa.h:67
unsigned char B
Blue component.
Definition: vpRGBa.h:146
unsigned char R
Red component.
Definition: vpRGBa.h:144
unsigned char G
Green component.
Definition: vpRGBa.h:145
@ alpha_default
Definition: vpRGBa.h:69
unsigned char A
Additionnal component.
Definition: vpRGBa.h:147
Definition: vpRGBf.h:59
float B
Blue component.
Definition: vpRGBf.h:129
float G
Green component.
Definition: vpRGBf.h:128
float R
Red component.
Definition: vpRGBf.h:127
#define vpDEBUG_TRACE
Definition: vpDebug.h:487