Visual Servoing Platform  version 3.1.0
vpImageConvert.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Convert image types.
33  *
34  * Authors:
35  * Eric Marchand
36  * Fabien Spindler
37  * Anthony Saunier
38  *
39  *****************************************************************************/
40 
46 #include <map>
47 #include <sstream>
48 
49 // image
50 #include <visp3/core/vpCPUFeatures.h>
51 #include <visp3/core/vpImageConvert.h>
52 
53 #if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
54 #include <emmintrin.h>
55 #define VISP_HAVE_SSE2 1
56 
57 #if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
58 #include <pmmintrin.h>
59 #define VISP_HAVE_SSE3 1
60 #endif
61 #if defined __SSSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
62 #include <tmmintrin.h>
63 #define VISP_HAVE_SSSE3 1
64 #endif
65 #endif
66 
67 bool vpImageConvert::YCbCrLUTcomputed = false;
68 int vpImageConvert::vpCrr[256];
69 int vpImageConvert::vpCgb[256];
70 int vpImageConvert::vpCgr[256];
71 int vpImageConvert::vpCbb[256];
72 
80 {
81  dest.resize(src.getHeight(), src.getWidth());
82 
83  GreyToRGBa(src.bitmap, (unsigned char *)dest.bitmap, src.getHeight() * src.getWidth());
84 }
85 
92 {
93  dest.resize(src.getHeight(), src.getWidth());
94 
95  RGBaToGrey((unsigned char *)src.bitmap, dest.bitmap, src.getHeight() * src.getWidth());
96 }
97 
103 {
104  dest.resize(src.getHeight(), src.getWidth());
105  unsigned int max_xy = src.getWidth() * src.getHeight();
106  float min, max;
107 
108  src.getMinMaxValue(min, max);
109 
110  for (unsigned int i = 0; i < max_xy; i++) {
111  float val = 255.f * (src.bitmap[i] - min) / (max - min);
112  if (val < 0)
113  dest.bitmap[i] = 0;
114  else if (val > 255)
115  dest.bitmap[i] = 255;
116  else
117  dest.bitmap[i] = (unsigned char)val;
118  }
119 }
120 
127 {
128  dest.resize(src.getHeight(), src.getWidth());
129  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
130  dest.bitmap[i] = (float)src.bitmap[i];
131 }
132 
138 {
139  dest.resize(src.getHeight(), src.getWidth());
140  unsigned int max_xy = src.getWidth() * src.getHeight();
141  double min, max;
142 
143  src.getMinMaxValue(min, max);
144 
145  for (unsigned int i = 0; i < max_xy; i++) {
146  double val = 255. * (src.bitmap[i] - min) / (max - min);
147  if (val < 0)
148  dest.bitmap[i] = 0;
149  else if (val > 255)
150  dest.bitmap[i] = 255;
151  else
152  dest.bitmap[i] = (unsigned char)val;
153  }
154 }
155 
162 {
163  dest.resize(src.getHeight(), src.getWidth());
164 
165  for (unsigned int i = 0; i < src.getSize(); i++)
166  dest.bitmap[i] = (src.bitmap[i] >> 8);
167 }
168 
175 {
176  dest.resize(src.getHeight(), src.getWidth());
177 
178  for (unsigned int i = 0; i < src.getSize(); i++)
179  dest.bitmap[i] = (src.bitmap[i] << 8);
180 }
181 
188 {
189  dest.resize(src.getHeight(), src.getWidth());
190  for (unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++)
191  dest.bitmap[i] = (double)src.bitmap[i];
192 }
193 
202 {
203  dest_rgba.resize(src_depth.getHeight(), src_depth.getWidth());
204  static uint32_t histogram[0x10000];
205  memset(histogram, 0, sizeof(histogram));
206 
207  for (unsigned int i = 0; i < src_depth.getSize(); ++i)
208  ++histogram[src_depth.bitmap[i]];
209  for (int i = 2; i < 0x10000; ++i)
210  histogram[i] += histogram[i - 1]; // Build a cumulative histogram for the
211  // indices in [1,0xFFFF]
212 
213  for (unsigned int i = 0; i < src_depth.getSize(); ++i) {
214  uint16_t d = src_depth.bitmap[i];
215  if (d) {
216  int f = (int)(histogram[d] * 255 / histogram[0xFFFF]); // 0-255 based on histogram location
217  dest_rgba.bitmap[i].R = 255 - f;
218  dest_rgba.bitmap[i].G = 0;
219  dest_rgba.bitmap[i].B = f;
220  dest_rgba.bitmap[i].A = vpRGBa::alpha_default;
221  } else {
222  dest_rgba.bitmap[i].R = 20;
223  dest_rgba.bitmap[i].G = 5;
224  dest_rgba.bitmap[i].B = 0;
225  dest_rgba.bitmap[i].A = vpRGBa::alpha_default;
226  }
227  }
228 }
229 
237 {
238  dest_depth.resize(src_depth.getHeight(), src_depth.getWidth());
239  static uint32_t histogram2[0x10000];
240  memset(histogram2, 0, sizeof(histogram2));
241 
242  for (unsigned int i = 0; i < src_depth.getSize(); ++i)
243  ++histogram2[src_depth.bitmap[i]];
244  for (int i = 2; i < 0x10000; ++i)
245  histogram2[i] += histogram2[i - 1]; // Build a cumulative histogram for
246  // the indices in [1,0xFFFF]
247 
248  for (unsigned int i = 0; i < src_depth.getSize(); ++i) {
249  uint16_t d = src_depth.bitmap[i];
250  if (d) {
251  int f = (int)(histogram2[d] * 255 / histogram2[0xFFFF]); // 0-255 based on histogram location
252  dest_depth.bitmap[i] = f;
253  } else {
254  dest_depth.bitmap[i] = 0;
255  }
256  }
257 }
258 
259 #ifdef VISP_HAVE_OPENCV
260 // Deprecated: will be removed with OpenCV transcient from C to C++ api
307 void vpImageConvert::convert(const IplImage *src, vpImage<vpRGBa> &dest, bool flip)
308 {
309  int nChannel = src->nChannels;
310  int depth = src->depth;
311  int height = src->height;
312  int width = src->width;
313  int widthStep = src->widthStep;
314  int lineStep = (flip) ? 1 : 0;
315 
316  if (nChannel == 3 && depth == 8) {
317  dest.resize((unsigned int)height, (unsigned int)width);
318 
319  // starting source address
320  unsigned char *input = (unsigned char *)src->imageData;
321  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
322 
323  for (int i = 0; i < height; i++) {
324  unsigned char *line = input;
325  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
326  for (int j = 0; j < width; j++) {
327  *(output++) = *(line + 2);
328  *(output++) = *(line + 1);
329  *(output++) = *(line);
330  *(output++) = vpRGBa::alpha_default;
331 
332  line += 3;
333  }
334  // go to the next line
335  input += widthStep;
336  }
337  } else if (nChannel == 1 && depth == 8) {
338  dest.resize((unsigned int)height, (unsigned int)width);
339  // starting source address
340  unsigned char *input = (unsigned char *)src->imageData;
341  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
342 
343  for (int i = 0; i < height; i++) {
344  unsigned char *line = input;
345  unsigned char *output = beginOutput + lineStep * (4 * width * (height - 1 - i)) + (1 - lineStep) * 4 * width * i;
346  for (int j = 0; j < width; j++) {
347  *output++ = *(line);
348  *output++ = *(line);
349  *output++ = *(line);
350  *output++ = vpRGBa::alpha_default; // alpha
351 
352  line++;
353  }
354  // go to the next line
355  input += widthStep;
356  }
357  }
358 }
359 
403 void vpImageConvert::convert(const IplImage *src, vpImage<unsigned char> &dest, bool flip)
404 {
405  int nChannel = src->nChannels;
406  int depth = src->depth;
407  int height = src->height;
408  int width = src->width;
409  int widthStep = src->widthStep;
410  int lineStep = (flip) ? 1 : 0;
411 
412  if (flip == false) {
413  if (widthStep == width) {
414  if (nChannel == 1 && depth == 8) {
415  dest.resize((unsigned int)height, (unsigned int)width);
416  memcpy(dest.bitmap, src->imageData, (size_t)(height * width));
417  }
418  if (nChannel == 3 && depth == 8) {
419  dest.resize((unsigned int)height, (unsigned int)width);
420  BGRToGrey((unsigned char *)src->imageData, dest.bitmap, (unsigned int)width, (unsigned int)height, false);
421  }
422  } else {
423  if (nChannel == 1 && depth == 8) {
424  dest.resize((unsigned int)height, (unsigned int)width);
425  for (int i = 0; i < height; i++) {
426  memcpy(dest.bitmap + i * width, src->imageData + i * widthStep, (size_t)width);
427  }
428  }
429  if (nChannel == 3 && depth == 8) {
430  dest.resize((unsigned int)height, (unsigned int)width);
431  for (int i = 0; i < height; i++) {
432  BGRToGrey((unsigned char *)src->imageData + i * widthStep, dest.bitmap + i * width, (unsigned int)width, 1,
433  false);
434  }
435  }
436  }
437  } else {
438  if (nChannel == 1 && depth == 8) {
439  dest.resize((unsigned int)height, (unsigned int)width);
440  unsigned char *beginOutput = (unsigned char *)dest.bitmap;
441  for (int i = 0; i < height; i++) {
442  memcpy(beginOutput + lineStep * (4 * width * (height - 1 - i)), src->imageData + i * widthStep, (size_t)width);
443  }
444  }
445  if (nChannel == 3 && depth == 8) {
446  dest.resize((unsigned int)height, (unsigned int)width);
447  // for (int i = 0 ; i < height ; i++){
448  BGRToGrey((unsigned char *)src->imageData /*+ i*widthStep*/, dest.bitmap /*+ i*width*/, (unsigned int)width,
449  (unsigned int)height /*1*/, true);
450  //}
451  }
452  }
453 }
454 
499 void vpImageConvert::convert(const vpImage<vpRGBa> &src, IplImage *&dest)
500 {
501  int height = (int)src.getHeight();
502  int width = (int)src.getWidth();
503  CvSize size = cvSize(width, height);
504  int depth = 8;
505  int channels = 3;
506  if (dest != NULL) {
507  if (dest->nChannels != channels || dest->depth != depth || dest->height != height || dest->width != width) {
508  if (dest->nChannels != 0)
509  cvReleaseImage(&dest);
510  dest = cvCreateImage(size, depth, channels);
511  }
512  } else
513  dest = cvCreateImage(size, depth, channels);
514 
515  // starting source address
516  unsigned char *input = (unsigned char *)src.bitmap; // rgba image
517  unsigned char *output = (unsigned char *)dest->imageData; // bgr image
518 
519  int j = 0;
520  int i = 0;
521  int widthStep = dest->widthStep;
522 
523  for (i = 0; i < height; i++) {
524  output = (unsigned char *)dest->imageData + i * widthStep;
525  unsigned char *line = input;
526  for (j = 0; j < width; j++) {
527  *output++ = *(line + 2); // B
528  *output++ = *(line + 1); // G
529  *output++ = *(line); // R
530 
531  line += 4;
532  }
533  // go to the next line
534  input += 4 * width;
535  }
536 }
537 
582 void vpImageConvert::convert(const vpImage<unsigned char> &src, IplImage *&dest)
583 {
584  unsigned int height = src.getHeight();
585  unsigned int width = src.getWidth();
586  CvSize size = cvSize((int)width, (int)height);
587  int depth = 8;
588  int channels = 1;
589  if (dest != NULL) {
590  if (dest->nChannels != channels || dest->depth != depth || dest->height != (int)height ||
591  dest->width != (int)width) {
592  if (dest->nChannels != 0)
593  cvReleaseImage(&dest);
594  dest = cvCreateImage(size, depth, channels);
595  }
596  } else
597  dest = cvCreateImage(size, depth, channels);
598 
599  unsigned int widthStep = (unsigned int)dest->widthStep;
600 
601  if (width == widthStep) {
602  memcpy(dest->imageData, src.bitmap, width * height);
603  } else {
604  // copying each line taking account of the widthStep
605  for (unsigned int i = 0; i < height; i++) {
606  memcpy(dest->imageData + i * widthStep, src.bitmap + i * width, width);
607  }
608  }
609 }
610 
611 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
612 
657 void vpImageConvert::convert(const cv::Mat &src, vpImage<vpRGBa> &dest, const bool flip)
658 {
659  if (src.type() == CV_8UC4) {
660  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
661  vpRGBa rgbaVal;
662  for (unsigned int i = 0; i < dest.getRows(); ++i)
663  for (unsigned int j = 0; j < dest.getCols(); ++j) {
664  cv::Vec4b tmp = src.at<cv::Vec4b>((int)i, (int)j);
665  rgbaVal.R = tmp[2];
666  rgbaVal.G = tmp[1];
667  rgbaVal.B = tmp[0];
668  rgbaVal.A = tmp[3];
669  if (flip)
670  dest[dest.getRows() - i - 1][j] = rgbaVal;
671  else
672  dest[i][j] = rgbaVal;
673  }
674  } else if (src.type() == CV_8UC3) {
675  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
676  vpRGBa rgbaVal;
677  rgbaVal.A = vpRGBa::alpha_default;
678  for (unsigned int i = 0; i < dest.getRows(); ++i) {
679  for (unsigned int j = 0; j < dest.getCols(); ++j) {
680  cv::Vec3b tmp = src.at<cv::Vec3b>((int)i, (int)j);
681  rgbaVal.R = tmp[2];
682  rgbaVal.G = tmp[1];
683  rgbaVal.B = tmp[0];
684  if (flip) {
685  dest[dest.getRows() - i - 1][j] = rgbaVal;
686  } else {
687  dest[i][j] = rgbaVal;
688  }
689  }
690  }
691  } else if (src.type() == CV_8UC1) {
692  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
693  vpRGBa rgbaVal;
694  for (unsigned int i = 0; i < dest.getRows(); ++i) {
695  for (unsigned int j = 0; j < dest.getCols(); ++j) {
696  rgbaVal = src.at<unsigned char>((int)i, (int)j);
697  if (flip) {
698  dest[dest.getRows() - i - 1][j] = rgbaVal;
699  } else {
700  dest[i][j] = rgbaVal;
701  }
702  }
703  }
704  }
705 }
706 
749 void vpImageConvert::convert(const cv::Mat &src, vpImage<unsigned char> &dest, const bool flip)
750 {
751  if (src.type() == CV_8UC1) {
752  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
753  if (src.isContinuous() && !flip) {
754  memcpy(dest.bitmap, src.data, (size_t)(src.rows * src.cols));
755  } else {
756  if (flip) {
757  for (unsigned int i = 0; i < dest.getRows(); ++i) {
758  memcpy(dest.bitmap + i * dest.getCols(), src.data + (dest.getRows() - i - 1) * src.step1(), (size_t)src.step);
759  }
760  } else {
761  for (unsigned int i = 0; i < dest.getRows(); ++i) {
762  memcpy(dest.bitmap + i * dest.getCols(), src.data + i * src.step1(), (size_t)src.step);
763  }
764  }
765  }
766  } else if (src.type() == CV_8UC3) {
767  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
768  if (src.isContinuous() /*&& !flip*/) {
769  BGRToGrey((unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows,
770  flip);
771  } else {
772  if (flip) {
773  for (unsigned int i = 0; i < dest.getRows(); ++i) {
774  BGRToGrey((unsigned char *)src.data + i * src.step1(),
775  (unsigned char *)dest.bitmap + (dest.getRows() - i - 1) * dest.getCols(),
776  (unsigned int)dest.getCols(), 1, false);
777  }
778  } else {
779  for (unsigned int i = 0; i < dest.getRows(); ++i) {
780  BGRToGrey((unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
781  (unsigned int)dest.getCols(), 1, false);
782  }
783  }
784  }
785  }
786 }
787 
827 void vpImageConvert::convert(const vpImage<vpRGBa> &src, cv::Mat &dest)
828 {
829  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_8UC4, (void *)src.bitmap);
830 
831  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC3);
832  cv::Mat alpha((int)src.getRows(), (int)src.getCols(), CV_8UC1);
833 
834  cv::Mat out[] = {dest, alpha};
835  int from_to[] = {0, 2, 1, 1, 2, 0, 3, 3};
836  cv::mixChannels(&vpToMat, 1, out, 2, from_to, 4);
837 }
838 
880 void vpImageConvert::convert(const vpImage<unsigned char> &src, cv::Mat &dest, const bool copyData)
881 {
882  if (copyData) {
883  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
884  dest = tmpMap.clone();
885  } else {
886  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap);
887  }
888 }
889 
890 #endif
891 #endif
892 
893 #ifdef VISP_HAVE_YARP
894 
929 void vpImageConvert::convert(const vpImage<unsigned char> &src, yarp::sig::ImageOf<yarp::sig::PixelMono> *dest,
930  const bool copyData)
931 {
932  if (copyData) {
933  dest->resize(src.getWidth(), src.getHeight());
934  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth());
935  } else
936  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
937 }
938 
978 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelMono> *src, vpImage<unsigned char> &dest,
979  const bool copyData)
980 {
981  dest.resize(src->height(), src->width());
982  if (copyData)
983  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelMono));
984  else
985  dest.bitmap = src->getRawImage();
986 }
987 
1023 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgba> *dest,
1024  const bool copyData)
1025 {
1026  if (copyData) {
1027  dest->resize(src.getWidth(), src.getHeight());
1028  memcpy(dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() * sizeof(vpRGBa));
1029  } else
1030  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
1031 }
1032 
1072 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgba> *src, vpImage<vpRGBa> &dest,
1073  const bool copyData)
1074 {
1075  dest.resize(src->height(), src->width());
1076  if (copyData)
1077  memcpy(dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof(yarp::sig::PixelRgba));
1078  else
1079  dest.bitmap = static_cast<vpRGBa *>(src->getRawImage());
1080 }
1081 
1115 void vpImageConvert::convert(const vpImage<vpRGBa> &src, yarp::sig::ImageOf<yarp::sig::PixelRgb> *dest)
1116 {
1117  dest->resize(src.getWidth(), src.getHeight());
1118  for (unsigned int i = 0; i < src.getRows(); i++) {
1119  for (unsigned int j = 0; j < src.getWidth(); j++) {
1120  dest->pixel(j, i).r = src[i][j].R;
1121  dest->pixel(j, i).g = src[i][j].G;
1122  dest->pixel(j, i).b = src[i][j].B;
1123  }
1124  }
1125 }
1126 
1166 void vpImageConvert::convert(const yarp::sig::ImageOf<yarp::sig::PixelRgb> *src, vpImage<vpRGBa> &dest)
1167 {
1168  dest.resize(src->height(), src->width());
1169  for (int i = 0; i < src->height(); i++) {
1170  for (int j = 0; j < src->width(); j++) {
1171  dest[i][j].R = src->pixel(j, i).r;
1172  dest[i][j].G = src->pixel(j, i).g;
1173  dest[i][j].B = src->pixel(j, i).b;
1174  dest[i][j].A = vpRGBa::alpha_default;
1175  }
1176  }
1177 }
1178 
1179 #endif
1180 
1181 #define vpSAT(c) \
1182  if (c & (~255)) { \
1183  if (c < 0) \
1184  c = 0; \
1185  else \
1186  c = 255; \
1187  }
1188 
1196 void vpImageConvert::YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
1197 {
1198  unsigned char *s;
1199  unsigned char *d;
1200  int w, h;
1201  int r, g, b, cr, cg, cb, y1, y2;
1202 
1203  h = (int)height;
1204  w = (int)width;
1205  s = yuyv;
1206  d = rgba;
1207  while (h--) {
1208  int c = w >> 1;
1209  while (c--) {
1210  y1 = *s++;
1211  cb = ((*s - 128) * 454) >> 8;
1212  cg = (*s++ - 128) * 88;
1213  y2 = *s++;
1214  cr = ((*s - 128) * 359) >> 8;
1215  cg = (cg + (*s++ - 128) * 183) >> 8;
1216 
1217  r = y1 + cr;
1218  b = y1 + cb;
1219  g = y1 - cg;
1220  vpSAT(r);
1221  vpSAT(g);
1222  vpSAT(b);
1223 
1224  *d++ = static_cast<unsigned char>(r);
1225  *d++ = static_cast<unsigned char>(g);
1226  *d++ = static_cast<unsigned char>(b);
1227  *d++ = vpRGBa::alpha_default;
1228 
1229  r = y2 + cr;
1230  b = y2 + cb;
1231  g = y2 - cg;
1232  vpSAT(r);
1233  vpSAT(g);
1234  vpSAT(b);
1235 
1236  *d++ = static_cast<unsigned char>(r);
1237  *d++ = static_cast<unsigned char>(g);
1238  *d++ = static_cast<unsigned char>(b);
1239  *d++ = vpRGBa::alpha_default;
1240  }
1241  }
1242 }
1243 
1251 void vpImageConvert::YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
1252 {
1253  unsigned char *s;
1254  unsigned char *d;
1255  int h, w;
1256  int r, g, b, cr, cg, cb, y1, y2;
1257 
1258  h = (int)height;
1259  w = (int)width;
1260  s = yuyv;
1261  d = rgb;
1262  while (h--) {
1263  int c = w >> 1;
1264  while (c--) {
1265  y1 = *s++;
1266  cb = ((*s - 128) * 454) >> 8;
1267  cg = (*s++ - 128) * 88;
1268  y2 = *s++;
1269  cr = ((*s - 128) * 359) >> 8;
1270  cg = (cg + (*s++ - 128) * 183) >> 8;
1271 
1272  r = y1 + cr;
1273  b = y1 + cb;
1274  g = y1 - cg;
1275  vpSAT(r);
1276  vpSAT(g);
1277  vpSAT(b);
1278 
1279  *d++ = static_cast<unsigned char>(r);
1280  *d++ = static_cast<unsigned char>(g);
1281  *d++ = static_cast<unsigned char>(b);
1282 
1283  r = y2 + cr;
1284  b = y2 + cb;
1285  g = y2 - cg;
1286  vpSAT(r);
1287  vpSAT(g);
1288  vpSAT(b);
1289 
1290  *d++ = static_cast<unsigned char>(r);
1291  *d++ = static_cast<unsigned char>(g);
1292  *d++ = static_cast<unsigned char>(b);
1293  }
1294  }
1295 }
1303 void vpImageConvert::YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
1304 {
1305  unsigned int i = 0, j = 0;
1306 
1307  while (j < size * 2) {
1308  grey[i++] = yuyv[j];
1309  grey[i++] = yuyv[j + 2];
1310  j += 4;
1311  }
1312 }
1313 
1320 void vpImageConvert::YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1321 {
1322 #if 1
1323  // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1324  for (unsigned int i = size / 4; i; i--) {
1325  int U = (int)((*yuv++ - 128) * 0.354);
1326  int U5 = 5 * U;
1327  int Y0 = *yuv++;
1328  int Y1 = *yuv++;
1329  int V = (int)((*yuv++ - 128) * 0.707);
1330  int V2 = 2 * V;
1331  int Y2 = *yuv++;
1332  int Y3 = *yuv++;
1333  int UV = -U - V;
1334 
1335  // Original equations
1336  // R = Y + 1.402 V
1337  // G = Y - 0.344 U - 0.714 V
1338  // B = Y + 1.772 U
1339  int R = Y0 + V2;
1340  if ((R >> 8) > 0)
1341  R = 255;
1342  else if (R < 0)
1343  R = 0;
1344 
1345  int G = Y0 + UV;
1346  if ((G >> 8) > 0)
1347  G = 255;
1348  else if (G < 0)
1349  G = 0;
1350 
1351  int B = Y0 + U5;
1352  if ((B >> 8) > 0)
1353  B = 255;
1354  else if (B < 0)
1355  B = 0;
1356 
1357  *rgba++ = (unsigned char)R;
1358  *rgba++ = (unsigned char)G;
1359  *rgba++ = (unsigned char)B;
1360  *rgba++ = vpRGBa::alpha_default;
1361 
1362  //---
1363  R = Y1 + V2;
1364  if ((R >> 8) > 0)
1365  R = 255;
1366  else if (R < 0)
1367  R = 0;
1368 
1369  G = Y1 + UV;
1370  if ((G >> 8) > 0)
1371  G = 255;
1372  else if (G < 0)
1373  G = 0;
1374 
1375  B = Y1 + U5;
1376  if ((B >> 8) > 0)
1377  B = 255;
1378  else if (B < 0)
1379  B = 0;
1380 
1381  *rgba++ = (unsigned char)R;
1382  *rgba++ = (unsigned char)G;
1383  *rgba++ = (unsigned char)B;
1384  *rgba++ = vpRGBa::alpha_default;
1385 
1386  //---
1387  R = Y2 + V2;
1388  if ((R >> 8) > 0)
1389  R = 255;
1390  else if (R < 0)
1391  R = 0;
1392 
1393  G = Y2 + UV;
1394  if ((G >> 8) > 0)
1395  G = 255;
1396  else if (G < 0)
1397  G = 0;
1398 
1399  B = Y2 + U5;
1400  if ((B >> 8) > 0)
1401  B = 255;
1402  else if (B < 0)
1403  B = 0;
1404 
1405  *rgba++ = (unsigned char)R;
1406  *rgba++ = (unsigned char)G;
1407  *rgba++ = (unsigned char)B;
1408  *rgba++ = vpRGBa::alpha_default;
1409 
1410  //---
1411  R = Y3 + V2;
1412  if ((R >> 8) > 0)
1413  R = 255;
1414  else if (R < 0)
1415  R = 0;
1416 
1417  G = Y3 + UV;
1418  if ((G >> 8) > 0)
1419  G = 255;
1420  else if (G < 0)
1421  G = 0;
1422 
1423  B = Y3 + U5;
1424  if ((B >> 8) > 0)
1425  B = 255;
1426  else if (B < 0)
1427  B = 0;
1428 
1429  *rgba++ = (unsigned char)R;
1430  *rgba++ = (unsigned char)G;
1431  *rgba++ = (unsigned char)B;
1432  *rgba++ = vpRGBa::alpha_default;
1433  }
1434 #else
1435  // tres tres lent ....
1436  unsigned int i = 0, j = 0;
1437  unsigned char r, g, b;
1438  while (j < numpixels * 3 / 2) {
1439 
1440  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1441  rgba[i] = r;
1442  rgba[i + 1] = g;
1443  rgba[i + 2] = b;
1444  rgba[i + 3] = vpRGBa::alpha_default;
1445  i += 4;
1446 
1447  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1448  rgba[i] = r;
1449  rgba[i + 1] = g;
1450  rgba[i + 2] = b;
1451  rgba[i + 3] = vpRGBa::alpha_default;
1452  i += 4;
1453 
1454  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1455  rgba[i] = r;
1456  rgba[i + 1] = g;
1457  rgba[i + 2] = b;
1458  rgba[i + 3] = vpRGBa::alpha_default;
1459  i += 4;
1460 
1461  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1462  rgba[i] = r;
1463  rgba[i + 1] = g;
1464  rgba[i + 2] = b;
1465  rgba[i + 3] = vpRGBa::alpha_default;
1466  i += 4;
1467 
1468  j += 6;
1469  }
1470 #endif
1471 }
1472 
1481 void vpImageConvert::YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
1482 {
1483 
1484 #if 1
1485  // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1486  for (unsigned int i = size / 2; i; i--) {
1487  int U = (int)((*yuv++ - 128) * 0.354);
1488  int U5 = 5 * U;
1489  int Y0 = *yuv++;
1490  int V = (int)((*yuv++ - 128) * 0.707);
1491  int V2 = 2 * V;
1492  int Y1 = *yuv++;
1493  int UV = -U - V;
1494 
1495  //---
1496  int R = Y0 + V2;
1497  if ((R >> 8) > 0)
1498  R = 255;
1499  else if (R < 0)
1500  R = 0;
1501 
1502  int G = Y0 + UV;
1503  if ((G >> 8) > 0)
1504  G = 255;
1505  else if (G < 0)
1506  G = 0;
1507 
1508  int B = Y0 + U5;
1509  if ((B >> 8) > 0)
1510  B = 255;
1511  else if (B < 0)
1512  B = 0;
1513 
1514  *rgba++ = (unsigned char)R;
1515  *rgba++ = (unsigned char)G;
1516  *rgba++ = (unsigned char)B;
1517  *rgba++ = vpRGBa::alpha_default;
1518 
1519  //---
1520  R = Y1 + V2;
1521  if ((R >> 8) > 0)
1522  R = 255;
1523  else if (R < 0)
1524  R = 0;
1525 
1526  G = Y1 + UV;
1527  if ((G >> 8) > 0)
1528  G = 255;
1529  else if (G < 0)
1530  G = 0;
1531 
1532  B = Y1 + U5;
1533  if ((B >> 8) > 0)
1534  B = 255;
1535  else if (B < 0)
1536  B = 0;
1537 
1538  *rgba++ = (unsigned char)R;
1539  *rgba++ = (unsigned char)G;
1540  *rgba++ = (unsigned char)B;
1541  *rgba++ = vpRGBa::alpha_default;
1542  }
1543 
1544 #else
1545  // tres tres lent ....
1546  unsigned int i = 0, j = 0;
1547  unsigned char r, g, b;
1548 
1549  while (j < size * 2) {
1550 
1551  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1552  rgba[i] = r;
1553  rgba[i + 1] = g;
1554  rgba[i + 2] = b;
1555  rgba[i + 3] = vpRGBa::alpha_default;
1556  i += 4;
1557 
1558  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1559  rgba[i] = r;
1560  rgba[i + 1] = g;
1561  rgba[i + 2] = b;
1562  rgba[i + 3] = vpRGBa::alpha_default;
1563  i += 4;
1564  j += 4;
1565  }
1566 #endif
1567 }
1568 
1575 void vpImageConvert::YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1576 {
1577  unsigned int i = 0, j = 0;
1578  while (j < size * 3 / 2) {
1579  grey[i] = yuv[j + 1];
1580  grey[i + 1] = yuv[j + 2];
1581  grey[i + 2] = yuv[j + 4];
1582  grey[i + 3] = yuv[j + 5];
1583 
1584  i += 4;
1585 
1586  j += 6;
1587  }
1588 }
1589 
1598 void vpImageConvert::YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1599 {
1600 #if 1
1601  // std::cout << "call optimized convertYUV422ToRGB()" << std::endl;
1602  for (unsigned int i = size / 2; i; i--) {
1603  int U = (int)((*yuv++ - 128) * 0.354);
1604  int U5 = 5 * U;
1605  int Y0 = *yuv++;
1606  int V = (int)((*yuv++ - 128) * 0.707);
1607  int V2 = 2 * V;
1608  int Y1 = *yuv++;
1609  int UV = -U - V;
1610 
1611  //---
1612  int R = Y0 + V2;
1613  if ((R >> 8) > 0)
1614  R = 255;
1615  else if (R < 0)
1616  R = 0;
1617 
1618  int G = Y0 + UV;
1619  if ((G >> 8) > 0)
1620  G = 255;
1621  else if (G < 0)
1622  G = 0;
1623 
1624  int B = Y0 + U5;
1625  if ((B >> 8) > 0)
1626  B = 255;
1627  else if (B < 0)
1628  B = 0;
1629 
1630  *rgb++ = (unsigned char)R;
1631  *rgb++ = (unsigned char)G;
1632  *rgb++ = (unsigned char)B;
1633 
1634  //---
1635  R = Y1 + V2;
1636  if ((R >> 8) > 0)
1637  R = 255;
1638  else if (R < 0)
1639  R = 0;
1640 
1641  G = Y1 + UV;
1642  if ((G >> 8) > 0)
1643  G = 255;
1644  else if (G < 0)
1645  G = 0;
1646 
1647  B = Y1 + U5;
1648  if ((B >> 8) > 0)
1649  B = 255;
1650  else if (B < 0)
1651  B = 0;
1652 
1653  *rgb++ = (unsigned char)R;
1654  *rgb++ = (unsigned char)G;
1655  *rgb++ = (unsigned char)B;
1656  }
1657 
1658 #else
1659  // tres tres lent ....
1660  unsigned int i = 0, j = 0;
1661  unsigned char r, g, b;
1662 
1663  while (j < size * 2) {
1664 
1665  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 2], r, g, b);
1666  rgb[i] = r;
1667  rgb[i + 1] = g;
1668  rgb[i + 2] = b;
1669  i += 3;
1670 
1671  YUVToRGB(yuv[j + 3], yuv[j], yuv[j + 2], r, g, b);
1672  rgb[i] = r;
1673  rgb[i + 1] = g;
1674  rgb[i + 2] = b;
1675  i += 3;
1676  j += 4;
1677  }
1678 #endif
1679 }
1680 
1689 void vpImageConvert::YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
1690 {
1691  unsigned int i = 0, j = 0;
1692 
1693  while (j < size * 2) {
1694  grey[i++] = yuv[j + 1];
1695  grey[i++] = yuv[j + 3];
1696  j += 4;
1697  }
1698 }
1699 
1706 void vpImageConvert::YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
1707 {
1708 #if 1
1709  // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1710  for (unsigned int i = size / 4; i; i--) {
1711  int U = (int)((*yuv++ - 128) * 0.354);
1712  int U5 = 5 * U;
1713  int Y0 = *yuv++;
1714  int Y1 = *yuv++;
1715  int V = (int)((*yuv++ - 128) * 0.707);
1716  int V2 = 2 * V;
1717  int Y2 = *yuv++;
1718  int Y3 = *yuv++;
1719  int UV = -U - V;
1720 
1721  // Original equations
1722  // R = Y + 1.402 V
1723  // G = Y - 0.344 U - 0.714 V
1724  // B = Y + 1.772 U
1725  int R = Y0 + V2;
1726  if ((R >> 8) > 0)
1727  R = 255;
1728  else if (R < 0)
1729  R = 0;
1730 
1731  int G = Y0 + UV;
1732  if ((G >> 8) > 0)
1733  G = 255;
1734  else if (G < 0)
1735  G = 0;
1736 
1737  int B = Y0 + U5;
1738  if ((B >> 8) > 0)
1739  B = 255;
1740  else if (B < 0)
1741  B = 0;
1742 
1743  *rgb++ = (unsigned char)R;
1744  *rgb++ = (unsigned char)G;
1745  *rgb++ = (unsigned char)B;
1746 
1747  //---
1748  R = Y1 + V2;
1749  if ((R >> 8) > 0)
1750  R = 255;
1751  else if (R < 0)
1752  R = 0;
1753 
1754  G = Y1 + UV;
1755  if ((G >> 8) > 0)
1756  G = 255;
1757  else if (G < 0)
1758  G = 0;
1759 
1760  B = Y1 + U5;
1761  if ((B >> 8) > 0)
1762  B = 255;
1763  else if (B < 0)
1764  B = 0;
1765 
1766  *rgb++ = (unsigned char)R;
1767  *rgb++ = (unsigned char)G;
1768  *rgb++ = (unsigned char)B;
1769 
1770  //---
1771  R = Y2 + V2;
1772  if ((R >> 8) > 0)
1773  R = 255;
1774  else if (R < 0)
1775  R = 0;
1776 
1777  G = Y2 + UV;
1778  if ((G >> 8) > 0)
1779  G = 255;
1780  else if (G < 0)
1781  G = 0;
1782 
1783  B = Y2 + U5;
1784  if ((B >> 8) > 0)
1785  B = 255;
1786  else if (B < 0)
1787  B = 0;
1788 
1789  *rgb++ = (unsigned char)R;
1790  *rgb++ = (unsigned char)G;
1791  *rgb++ = (unsigned char)B;
1792 
1793  //---
1794  R = Y3 + V2;
1795  if ((R >> 8) > 0)
1796  R = 255;
1797  else if (R < 0)
1798  R = 0;
1799 
1800  G = Y3 + UV;
1801  if ((G >> 8) > 0)
1802  G = 255;
1803  else if (G < 0)
1804  G = 0;
1805 
1806  B = Y3 + U5;
1807  if ((B >> 8) > 0)
1808  B = 255;
1809  else if (B < 0)
1810  B = 0;
1811 
1812  *rgb++ = (unsigned char)R;
1813  *rgb++ = (unsigned char)G;
1814  *rgb++ = (unsigned char)B;
1815  }
1816 #else
1817  // tres tres lent ....
1818 
1819  unsigned int i = 0, j = 0;
1820  unsigned char r, g, b;
1821 
1822  while (j < size * 3 / 2) {
1823  YUVToRGB(yuv[j + 1], yuv[j], yuv[j + 3], r, g, b);
1824  rgb[i] = r;
1825  rgb[i + 1] = g;
1826  rgb[i + 2] = b;
1827  i += 3;
1828 
1829  YUVToRGB(yuv[j + 2], yuv[j], yuv[j + 3], r, g, b);
1830  rgb[i] = r;
1831  rgb[i + 1] = g;
1832  rgb[i + 2] = b;
1833  i += 3;
1834 
1835  YUVToRGB(yuv[j + 4], yuv[j], yuv[j + 3], r, g, b);
1836  rgb[i] = r;
1837  rgb[i + 1] = g;
1838  rgb[i + 2] = b;
1839  i += 3;
1840 
1841  YUVToRGB(yuv[j + 5], yuv[j], yuv[j + 3], r, g, b);
1842  rgb[i] = r;
1843  rgb[i + 1] = g;
1844  rgb[i + 2] = b;
1845  i += 3;
1846  // TRACE("r= %d g=%d b=%d", r, g, b);
1847 
1848  j += 6;
1849  }
1850 #endif
1851 }
1852 
1860 void vpImageConvert::YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
1861 {
1862  // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
1863  int U, V, R, G, B, V2, U5, UV;
1864  int Y0, Y1, Y2, Y3;
1865  unsigned int size = width * height;
1866  unsigned char *iU = yuv + size;
1867  unsigned char *iV = yuv + 5 * size / 4;
1868  for (unsigned int i = 0; i < height / 2; i++) {
1869  for (unsigned int j = 0; j < width / 2; j++) {
1870  U = (int)((*iU++ - 128) * 0.354);
1871  U5 = 5 * U;
1872  V = (int)((*iV++ - 128) * 0.707);
1873  V2 = 2 * V;
1874  UV = -U - V;
1875  Y0 = *yuv++;
1876  Y1 = *yuv;
1877  yuv = yuv + width - 1;
1878  Y2 = *yuv++;
1879  Y3 = *yuv;
1880  yuv = yuv - width + 1;
1881 
1882  // Original equations
1883  // R = Y + 1.402 V
1884  // G = Y - 0.344 U - 0.714 V
1885  // B = Y + 1.772 U
1886  R = Y0 + V2;
1887  if ((R >> 8) > 0)
1888  R = 255;
1889  else if (R < 0)
1890  R = 0;
1891 
1892  G = Y0 + UV;
1893  if ((G >> 8) > 0)
1894  G = 255;
1895  else if (G < 0)
1896  G = 0;
1897 
1898  B = Y0 + U5;
1899  if ((B >> 8) > 0)
1900  B = 255;
1901  else if (B < 0)
1902  B = 0;
1903 
1904  *rgba++ = (unsigned char)R;
1905  *rgba++ = (unsigned char)G;
1906  *rgba++ = (unsigned char)B;
1907  *rgba++ = vpRGBa::alpha_default;
1908 
1909  //---
1910  R = Y1 + V2;
1911  if ((R >> 8) > 0)
1912  R = 255;
1913  else if (R < 0)
1914  R = 0;
1915 
1916  G = Y1 + UV;
1917  if ((G >> 8) > 0)
1918  G = 255;
1919  else if (G < 0)
1920  G = 0;
1921 
1922  B = Y1 + U5;
1923  if ((B >> 8) > 0)
1924  B = 255;
1925  else if (B < 0)
1926  B = 0;
1927 
1928  *rgba++ = (unsigned char)R;
1929  *rgba++ = (unsigned char)G;
1930  *rgba++ = (unsigned char)B;
1931  *rgba = vpRGBa::alpha_default;
1932  rgba = rgba + 4 * width - 7;
1933 
1934  //---
1935  R = Y2 + V2;
1936  if ((R >> 8) > 0)
1937  R = 255;
1938  else if (R < 0)
1939  R = 0;
1940 
1941  G = Y2 + UV;
1942  if ((G >> 8) > 0)
1943  G = 255;
1944  else if (G < 0)
1945  G = 0;
1946 
1947  B = Y2 + U5;
1948  if ((B >> 8) > 0)
1949  B = 255;
1950  else if (B < 0)
1951  B = 0;
1952 
1953  *rgba++ = (unsigned char)R;
1954  *rgba++ = (unsigned char)G;
1955  *rgba++ = (unsigned char)B;
1956  *rgba++ = vpRGBa::alpha_default;
1957 
1958  //---
1959  R = Y3 + V2;
1960  if ((R >> 8) > 0)
1961  R = 255;
1962  else if (R < 0)
1963  R = 0;
1964 
1965  G = Y3 + UV;
1966  if ((G >> 8) > 0)
1967  G = 255;
1968  else if (G < 0)
1969  G = 0;
1970 
1971  B = Y3 + U5;
1972  if ((B >> 8) > 0)
1973  B = 255;
1974  else if (B < 0)
1975  B = 0;
1976 
1977  *rgba++ = (unsigned char)R;
1978  *rgba++ = (unsigned char)G;
1979  *rgba++ = (unsigned char)B;
1980  *rgba = vpRGBa::alpha_default;
1981  rgba = rgba - 4 * width + 1;
1982  }
1983  yuv += width;
1984  rgba += 4 * width;
1985  }
1986 }
1992 void vpImageConvert::YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
1993 {
1994  // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
1995  int U, V, R, G, B, V2, U5, UV;
1996  int Y0, Y1, Y2, Y3;
1997  unsigned int size = width * height;
1998  unsigned char *iU = yuv + size;
1999  unsigned char *iV = yuv + 5 * size / 4;
2000  for (unsigned int i = 0; i < height / 2; i++) {
2001  for (unsigned int j = 0; j < width / 2; j++) {
2002  U = (int)((*iU++ - 128) * 0.354);
2003  U5 = 5 * U;
2004  V = (int)((*iV++ - 128) * 0.707);
2005  V2 = 2 * V;
2006  UV = -U - V;
2007  Y0 = *yuv++;
2008  Y1 = *yuv;
2009  yuv = yuv + width - 1;
2010  Y2 = *yuv++;
2011  Y3 = *yuv;
2012  yuv = yuv - width + 1;
2013 
2014  // Original equations
2015  // R = Y + 1.402 V
2016  // G = Y - 0.344 U - 0.714 V
2017  // B = Y + 1.772 U
2018  R = Y0 + V2;
2019  if ((R >> 8) > 0)
2020  R = 255;
2021  else if (R < 0)
2022  R = 0;
2023 
2024  G = Y0 + UV;
2025  if ((G >> 8) > 0)
2026  G = 255;
2027  else if (G < 0)
2028  G = 0;
2029 
2030  B = Y0 + U5;
2031  if ((B >> 8) > 0)
2032  B = 255;
2033  else if (B < 0)
2034  B = 0;
2035 
2036  *rgb++ = (unsigned char)R;
2037  *rgb++ = (unsigned char)G;
2038  *rgb++ = (unsigned char)B;
2039 
2040  //---
2041  R = Y1 + V2;
2042  if ((R >> 8) > 0)
2043  R = 255;
2044  else if (R < 0)
2045  R = 0;
2046 
2047  G = Y1 + UV;
2048  if ((G >> 8) > 0)
2049  G = 255;
2050  else if (G < 0)
2051  G = 0;
2052 
2053  B = Y1 + U5;
2054  if ((B >> 8) > 0)
2055  B = 255;
2056  else if (B < 0)
2057  B = 0;
2058 
2059  *rgb++ = (unsigned char)R;
2060  *rgb++ = (unsigned char)G;
2061  *rgb = (unsigned char)B;
2062  rgb = rgb + 3 * width - 5;
2063 
2064  //---
2065  R = Y2 + V2;
2066  if ((R >> 8) > 0)
2067  R = 255;
2068  else if (R < 0)
2069  R = 0;
2070 
2071  G = Y2 + UV;
2072  if ((G >> 8) > 0)
2073  G = 255;
2074  else if (G < 0)
2075  G = 0;
2076 
2077  B = Y2 + U5;
2078  if ((B >> 8) > 0)
2079  B = 255;
2080  else if (B < 0)
2081  B = 0;
2082 
2083  *rgb++ = (unsigned char)R;
2084  *rgb++ = (unsigned char)G;
2085  *rgb++ = (unsigned char)B;
2086 
2087  //---
2088  R = Y3 + V2;
2089  if ((R >> 8) > 0)
2090  R = 255;
2091  else if (R < 0)
2092  R = 0;
2093 
2094  G = Y3 + UV;
2095  if ((G >> 8) > 0)
2096  G = 255;
2097  else if (G < 0)
2098  G = 0;
2099 
2100  B = Y3 + U5;
2101  if ((B >> 8) > 0)
2102  B = 255;
2103  else if (B < 0)
2104  B = 0;
2105 
2106  *rgb++ = (unsigned char)R;
2107  *rgb++ = (unsigned char)G;
2108  *rgb = (unsigned char)B;
2109  rgb = rgb - 3 * width + 1;
2110  }
2111  yuv += width;
2112  rgb += 3 * width;
2113  }
2114 }
2115 
2121 void vpImageConvert::YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2122 {
2123  for (unsigned int i = 0; i < size; i++) {
2124  *grey++ = *yuv++;
2125  }
2126 }
2134 void vpImageConvert::YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
2135 {
2136  for (unsigned int i = 0; i < size; i++) {
2137  int U = (int)((*yuv++ - 128) * 0.354);
2138  int U5 = 5 * U;
2139  int Y = *yuv++;
2140  int V = (int)((*yuv++ - 128) * 0.707);
2141  int V2 = 2 * V;
2142  int UV = -U - V;
2143 
2144  // Original equations
2145  // R = Y + 1.402 V
2146  // G = Y - 0.344 U - 0.714 V
2147  // B = Y + 1.772 U
2148  int R = Y + V2;
2149  if ((R >> 8) > 0)
2150  R = 255;
2151  else if (R < 0)
2152  R = 0;
2153 
2154  int G = Y + UV;
2155  if ((G >> 8) > 0)
2156  G = 255;
2157  else if (G < 0)
2158  G = 0;
2159 
2160  int B = Y + U5;
2161  if ((B >> 8) > 0)
2162  B = 255;
2163  else if (B < 0)
2164  B = 0;
2165 
2166  *rgba++ = (unsigned char)R;
2167  *rgba++ = (unsigned char)G;
2168  *rgba++ = (unsigned char)B;
2169  *rgba++ = vpRGBa::alpha_default;
2170  }
2171 }
2177 void vpImageConvert::YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
2178 {
2179  for (unsigned int i = 0; i < size; i++) {
2180  int U = (int)((*yuv++ - 128) * 0.354);
2181  int U5 = 5 * U;
2182  int Y = *yuv++;
2183  int V = (int)((*yuv++ - 128) * 0.707);
2184  int V2 = 2 * V;
2185  int UV = -U - V;
2186 
2187  // Original equations
2188  // R = Y + 1.402 V
2189  // G = Y - 0.344 U - 0.714 V
2190  // B = Y + 1.772 U
2191  int R = Y + V2;
2192  if ((R >> 8) > 0)
2193  R = 255;
2194  else if (R < 0)
2195  R = 0;
2196 
2197  int G = Y + UV;
2198  if ((G >> 8) > 0)
2199  G = 255;
2200  else if (G < 0)
2201  G = 0;
2202 
2203  int B = Y + U5;
2204  if ((B >> 8) > 0)
2205  B = 255;
2206  else if (B < 0)
2207  B = 0;
2208 
2209  *rgb++ = (unsigned char)R;
2210  *rgb++ = (unsigned char)G;
2211  *rgb++ = (unsigned char)B;
2212  }
2213 }
2214 
2220 void vpImageConvert::YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
2221 {
2222  yuv++;
2223  for (unsigned int i = 0; i < size; i++) {
2224  *grey++ = *yuv;
2225  yuv = yuv + 3;
2226  }
2227 }
2228 
2236 void vpImageConvert::YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2237 {
2238  // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
2239  int U, V, R, G, B, V2, U5, UV;
2240  int Y0, Y1, Y2, Y3;
2241  unsigned int size = width * height;
2242  unsigned char *iV = yuv + size;
2243  unsigned char *iU = yuv + 5 * size / 4;
2244  for (unsigned int i = 0; i < height / 2; i++) {
2245  for (unsigned int j = 0; j < width / 2; j++) {
2246  U = (int)((*iU++ - 128) * 0.354);
2247  U5 = 5 * U;
2248  V = (int)((*iV++ - 128) * 0.707);
2249  V2 = 2 * V;
2250  UV = -U - V;
2251  Y0 = *yuv++;
2252  Y1 = *yuv;
2253  yuv = yuv + width - 1;
2254  Y2 = *yuv++;
2255  Y3 = *yuv;
2256  yuv = yuv - width + 1;
2257 
2258  // Original equations
2259  // R = Y + 1.402 V
2260  // G = Y - 0.344 U - 0.714 V
2261  // B = Y + 1.772 U
2262  R = Y0 + V2;
2263  if ((R >> 8) > 0)
2264  R = 255;
2265  else if (R < 0)
2266  R = 0;
2267 
2268  G = Y0 + UV;
2269  if ((G >> 8) > 0)
2270  G = 255;
2271  else if (G < 0)
2272  G = 0;
2273 
2274  B = Y0 + U5;
2275  if ((B >> 8) > 0)
2276  B = 255;
2277  else if (B < 0)
2278  B = 0;
2279 
2280  *rgba++ = (unsigned char)R;
2281  *rgba++ = (unsigned char)G;
2282  *rgba++ = (unsigned char)B;
2283  *rgba++ = vpRGBa::alpha_default;
2284 
2285  //---
2286  R = Y1 + V2;
2287  if ((R >> 8) > 0)
2288  R = 255;
2289  else if (R < 0)
2290  R = 0;
2291 
2292  G = Y1 + UV;
2293  if ((G >> 8) > 0)
2294  G = 255;
2295  else if (G < 0)
2296  G = 0;
2297 
2298  B = Y1 + U5;
2299  if ((B >> 8) > 0)
2300  B = 255;
2301  else if (B < 0)
2302  B = 0;
2303 
2304  *rgba++ = (unsigned char)R;
2305  *rgba++ = (unsigned char)G;
2306  *rgba++ = (unsigned char)B;
2307  *rgba = 0;
2308  rgba = rgba + 4 * width - 7;
2309 
2310  //---
2311  R = Y2 + V2;
2312  if ((R >> 8) > 0)
2313  R = 255;
2314  else if (R < 0)
2315  R = 0;
2316 
2317  G = Y2 + UV;
2318  if ((G >> 8) > 0)
2319  G = 255;
2320  else if (G < 0)
2321  G = 0;
2322 
2323  B = Y2 + U5;
2324  if ((B >> 8) > 0)
2325  B = 255;
2326  else if (B < 0)
2327  B = 0;
2328 
2329  *rgba++ = (unsigned char)R;
2330  *rgba++ = (unsigned char)G;
2331  *rgba++ = (unsigned char)B;
2332  *rgba++ = vpRGBa::alpha_default;
2333 
2334  //---
2335  R = Y3 + V2;
2336  if ((R >> 8) > 0)
2337  R = 255;
2338  else if (R < 0)
2339  R = 0;
2340 
2341  G = Y3 + UV;
2342  if ((G >> 8) > 0)
2343  G = 255;
2344  else if (G < 0)
2345  G = 0;
2346 
2347  B = Y3 + U5;
2348  if ((B >> 8) > 0)
2349  B = 255;
2350  else if (B < 0)
2351  B = 0;
2352 
2353  *rgba++ = (unsigned char)R;
2354  *rgba++ = (unsigned char)G;
2355  *rgba++ = (unsigned char)B;
2356  *rgba = vpRGBa::alpha_default;
2357  rgba = rgba - 4 * width + 1;
2358  }
2359  yuv += width;
2360  rgba += 4 * width;
2361  }
2362 }
2368 void vpImageConvert::YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2369 {
2370  // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2371  int U, V, R, G, B, V2, U5, UV;
2372  int Y0, Y1, Y2, Y3;
2373  unsigned int size = width * height;
2374  unsigned char *iV = yuv + size;
2375  unsigned char *iU = yuv + 5 * size / 4;
2376  for (unsigned int i = 0; i < height / 2; i++) {
2377  for (unsigned int j = 0; j < width / 2; j++) {
2378  U = (int)((*iU++ - 128) * 0.354);
2379  U5 = 5 * U;
2380  V = (int)((*iV++ - 128) * 0.707);
2381  V2 = 2 * V;
2382  UV = -U - V;
2383  Y0 = *yuv++;
2384  Y1 = *yuv;
2385  yuv = yuv + width - 1;
2386  Y2 = *yuv++;
2387  Y3 = *yuv;
2388  yuv = yuv - width + 1;
2389 
2390  // Original equations
2391  // R = Y + 1.402 V
2392  // G = Y - 0.344 U - 0.714 V
2393  // B = Y + 1.772 U
2394  R = Y0 + V2;
2395  if ((R >> 8) > 0)
2396  R = 255;
2397  else if (R < 0)
2398  R = 0;
2399 
2400  G = Y0 + UV;
2401  if ((G >> 8) > 0)
2402  G = 255;
2403  else if (G < 0)
2404  G = 0;
2405 
2406  B = Y0 + U5;
2407  if ((B >> 8) > 0)
2408  B = 255;
2409  else if (B < 0)
2410  B = 0;
2411 
2412  *rgb++ = (unsigned char)R;
2413  *rgb++ = (unsigned char)G;
2414  *rgb++ = (unsigned char)B;
2415 
2416  //---
2417  R = Y1 + V2;
2418  if ((R >> 8) > 0)
2419  R = 255;
2420  else if (R < 0)
2421  R = 0;
2422 
2423  G = Y1 + UV;
2424  if ((G >> 8) > 0)
2425  G = 255;
2426  else if (G < 0)
2427  G = 0;
2428 
2429  B = Y1 + U5;
2430  if ((B >> 8) > 0)
2431  B = 255;
2432  else if (B < 0)
2433  B = 0;
2434 
2435  *rgb++ = (unsigned char)R;
2436  *rgb++ = (unsigned char)G;
2437  *rgb = (unsigned char)B;
2438  rgb = rgb + 3 * width - 5;
2439 
2440  //---
2441  R = Y2 + V2;
2442  if ((R >> 8) > 0)
2443  R = 255;
2444  else if (R < 0)
2445  R = 0;
2446 
2447  G = Y2 + UV;
2448  if ((G >> 8) > 0)
2449  G = 255;
2450  else if (G < 0)
2451  G = 0;
2452 
2453  B = Y2 + U5;
2454  if ((B >> 8) > 0)
2455  B = 255;
2456  else if (B < 0)
2457  B = 0;
2458 
2459  *rgb++ = (unsigned char)R;
2460  *rgb++ = (unsigned char)G;
2461  *rgb++ = (unsigned char)B;
2462 
2463  //---
2464  R = Y3 + V2;
2465  if ((R >> 8) > 0)
2466  R = 255;
2467  else if (R < 0)
2468  R = 0;
2469 
2470  G = Y3 + UV;
2471  if ((G >> 8) > 0)
2472  G = 255;
2473  else if (G < 0)
2474  G = 0;
2475 
2476  B = Y3 + U5;
2477  if ((B >> 8) > 0)
2478  B = 255;
2479  else if (B < 0)
2480  B = 0;
2481 
2482  *rgb++ = (unsigned char)R;
2483  *rgb++ = (unsigned char)G;
2484  *rgb = (unsigned char)B;
2485  rgb = rgb - 3 * width + 1;
2486  }
2487  yuv += width;
2488  rgb += 3 * width;
2489  }
2490 }
2491 
2499 void vpImageConvert::YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
2500 {
2501  // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2502  int U, V, R, G, B, V2, U5, UV;
2503  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2504  unsigned int size = width * height;
2505  unsigned char *iV = yuv + size;
2506  unsigned char *iU = yuv + 17 * size / 16;
2507  for (unsigned int i = 0; i < height / 4; i++) {
2508  for (unsigned int j = 0; j < width / 4; j++) {
2509  U = (int)((*iU++ - 128) * 0.354);
2510  U5 = 5 * U;
2511  V = (int)((*iV++ - 128) * 0.707);
2512  V2 = 2 * V;
2513  UV = -U - V;
2514  Y0 = *yuv++;
2515  Y1 = *yuv++;
2516  Y2 = *yuv++;
2517  Y3 = *yuv;
2518  yuv = yuv + width - 3;
2519  Y4 = *yuv++;
2520  Y5 = *yuv++;
2521  Y6 = *yuv++;
2522  Y7 = *yuv;
2523  yuv = yuv + width - 3;
2524  Y8 = *yuv++;
2525  Y9 = *yuv++;
2526  Y10 = *yuv++;
2527  Y11 = *yuv;
2528  yuv = yuv + width - 3;
2529  Y12 = *yuv++;
2530  Y13 = *yuv++;
2531  Y14 = *yuv++;
2532  Y15 = *yuv;
2533  yuv = yuv - 3 * width + 1;
2534 
2535  // Original equations
2536  // R = Y + 1.402 V
2537  // G = Y - 0.344 U - 0.714 V
2538  // B = Y + 1.772 U
2539  R = Y0 + V2;
2540  if ((R >> 8) > 0)
2541  R = 255;
2542  else if (R < 0)
2543  R = 0;
2544 
2545  G = Y0 + UV;
2546  if ((G >> 8) > 0)
2547  G = 255;
2548  else if (G < 0)
2549  G = 0;
2550 
2551  B = Y0 + U5;
2552  if ((B >> 8) > 0)
2553  B = 255;
2554  else if (B < 0)
2555  B = 0;
2556 
2557  *rgba++ = (unsigned char)R;
2558  *rgba++ = (unsigned char)G;
2559  *rgba++ = (unsigned char)B;
2560  *rgba++ = vpRGBa::alpha_default;
2561 
2562  //---
2563  R = Y1 + V2;
2564  if ((R >> 8) > 0)
2565  R = 255;
2566  else if (R < 0)
2567  R = 0;
2568 
2569  G = Y1 + UV;
2570  if ((G >> 8) > 0)
2571  G = 255;
2572  else if (G < 0)
2573  G = 0;
2574 
2575  B = Y1 + U5;
2576  if ((B >> 8) > 0)
2577  B = 255;
2578  else if (B < 0)
2579  B = 0;
2580 
2581  *rgba++ = (unsigned char)R;
2582  *rgba++ = (unsigned char)G;
2583  *rgba++ = (unsigned char)B;
2584  *rgba++ = vpRGBa::alpha_default;
2585 
2586  //---
2587  R = Y2 + V2;
2588  if ((R >> 8) > 0)
2589  R = 255;
2590  else if (R < 0)
2591  R = 0;
2592 
2593  G = Y2 + UV;
2594  if ((G >> 8) > 0)
2595  G = 255;
2596  else if (G < 0)
2597  G = 0;
2598 
2599  B = Y2 + U5;
2600  if ((B >> 8) > 0)
2601  B = 255;
2602  else if (B < 0)
2603  B = 0;
2604 
2605  *rgba++ = (unsigned char)R;
2606  *rgba++ = (unsigned char)G;
2607  *rgba++ = (unsigned char)B;
2608  *rgba++ = vpRGBa::alpha_default;
2609 
2610  //---
2611  R = Y3 + V2;
2612  if ((R >> 8) > 0)
2613  R = 255;
2614  else if (R < 0)
2615  R = 0;
2616 
2617  G = Y3 + UV;
2618  if ((G >> 8) > 0)
2619  G = 255;
2620  else if (G < 0)
2621  G = 0;
2622 
2623  B = Y3 + U5;
2624  if ((B >> 8) > 0)
2625  B = 255;
2626  else if (B < 0)
2627  B = 0;
2628 
2629  *rgba++ = (unsigned char)R;
2630  *rgba++ = (unsigned char)G;
2631  *rgba++ = (unsigned char)B;
2632  *rgba = vpRGBa::alpha_default;
2633  rgba = rgba + 4 * width - 15;
2634 
2635  R = Y4 + V2;
2636  if ((R >> 8) > 0)
2637  R = 255;
2638  else if (R < 0)
2639  R = 0;
2640 
2641  G = Y4 + UV;
2642  if ((G >> 8) > 0)
2643  G = 255;
2644  else if (G < 0)
2645  G = 0;
2646 
2647  B = Y4 + U5;
2648  if ((B >> 8) > 0)
2649  B = 255;
2650  else if (B < 0)
2651  B = 0;
2652 
2653  *rgba++ = (unsigned char)R;
2654  *rgba++ = (unsigned char)G;
2655  *rgba++ = (unsigned char)B;
2656  *rgba++ = vpRGBa::alpha_default;
2657 
2658  //---
2659  R = Y5 + V2;
2660  if ((R >> 8) > 0)
2661  R = 255;
2662  else if (R < 0)
2663  R = 0;
2664 
2665  G = Y5 + UV;
2666  if ((G >> 8) > 0)
2667  G = 255;
2668  else if (G < 0)
2669  G = 0;
2670 
2671  B = Y5 + U5;
2672  if ((B >> 8) > 0)
2673  B = 255;
2674  else if (B < 0)
2675  B = 0;
2676 
2677  *rgba++ = (unsigned char)R;
2678  *rgba++ = (unsigned char)G;
2679  *rgba++ = (unsigned char)B;
2680  *rgba++ = vpRGBa::alpha_default;
2681 
2682  //---
2683  R = Y6 + V2;
2684  if ((R >> 8) > 0)
2685  R = 255;
2686  else if (R < 0)
2687  R = 0;
2688 
2689  G = Y6 + UV;
2690  if ((G >> 8) > 0)
2691  G = 255;
2692  else if (G < 0)
2693  G = 0;
2694 
2695  B = Y6 + U5;
2696  if ((B >> 8) > 0)
2697  B = 255;
2698  else if (B < 0)
2699  B = 0;
2700 
2701  *rgba++ = (unsigned char)R;
2702  *rgba++ = (unsigned char)G;
2703  *rgba++ = (unsigned char)B;
2704  *rgba++ = vpRGBa::alpha_default;
2705 
2706  //---
2707  R = Y7 + V2;
2708  if ((R >> 8) > 0)
2709  R = 255;
2710  else if (R < 0)
2711  R = 0;
2712 
2713  G = Y7 + UV;
2714  if ((G >> 8) > 0)
2715  G = 255;
2716  else if (G < 0)
2717  G = 0;
2718 
2719  B = Y7 + U5;
2720  if ((B >> 8) > 0)
2721  B = 255;
2722  else if (B < 0)
2723  B = 0;
2724 
2725  *rgba++ = (unsigned char)R;
2726  *rgba++ = (unsigned char)G;
2727  *rgba++ = (unsigned char)B;
2728  *rgba = vpRGBa::alpha_default;
2729  rgba = rgba + 4 * width - 15;
2730 
2731  R = Y8 + V2;
2732  if ((R >> 8) > 0)
2733  R = 255;
2734  else if (R < 0)
2735  R = 0;
2736 
2737  G = Y8 + UV;
2738  if ((G >> 8) > 0)
2739  G = 255;
2740  else if (G < 0)
2741  G = 0;
2742 
2743  B = Y8 + U5;
2744  if ((B >> 8) > 0)
2745  B = 255;
2746  else if (B < 0)
2747  B = 0;
2748 
2749  *rgba++ = (unsigned char)R;
2750  *rgba++ = (unsigned char)G;
2751  *rgba++ = (unsigned char)B;
2752  *rgba++ = vpRGBa::alpha_default;
2753 
2754  //---
2755  R = Y9 + V2;
2756  if ((R >> 8) > 0)
2757  R = 255;
2758  else if (R < 0)
2759  R = 0;
2760 
2761  G = Y9 + UV;
2762  if ((G >> 8) > 0)
2763  G = 255;
2764  else if (G < 0)
2765  G = 0;
2766 
2767  B = Y9 + U5;
2768  if ((B >> 8) > 0)
2769  B = 255;
2770  else if (B < 0)
2771  B = 0;
2772 
2773  *rgba++ = (unsigned char)R;
2774  *rgba++ = (unsigned char)G;
2775  *rgba++ = (unsigned char)B;
2776  *rgba++ = vpRGBa::alpha_default;
2777 
2778  //---
2779  R = Y10 + V2;
2780  if ((R >> 8) > 0)
2781  R = 255;
2782  else if (R < 0)
2783  R = 0;
2784 
2785  G = Y10 + UV;
2786  if ((G >> 8) > 0)
2787  G = 255;
2788  else if (G < 0)
2789  G = 0;
2790 
2791  B = Y10 + U5;
2792  if ((B >> 8) > 0)
2793  B = 255;
2794  else if (B < 0)
2795  B = 0;
2796 
2797  *rgba++ = (unsigned char)R;
2798  *rgba++ = (unsigned char)G;
2799  *rgba++ = (unsigned char)B;
2800  *rgba++ = vpRGBa::alpha_default;
2801 
2802  //---
2803  R = Y11 + V2;
2804  if ((R >> 8) > 0)
2805  R = 255;
2806  else if (R < 0)
2807  R = 0;
2808 
2809  G = Y11 + UV;
2810  if ((G >> 8) > 0)
2811  G = 255;
2812  else if (G < 0)
2813  G = 0;
2814 
2815  B = Y11 + U5;
2816  if ((B >> 8) > 0)
2817  B = 255;
2818  else if (B < 0)
2819  B = 0;
2820 
2821  *rgba++ = (unsigned char)R;
2822  *rgba++ = (unsigned char)G;
2823  *rgba++ = (unsigned char)B;
2824  *rgba = vpRGBa::alpha_default;
2825  rgba = rgba + 4 * width - 15;
2826 
2827  R = Y12 + V2;
2828  if ((R >> 8) > 0)
2829  R = 255;
2830  else if (R < 0)
2831  R = 0;
2832 
2833  G = Y12 + UV;
2834  if ((G >> 8) > 0)
2835  G = 255;
2836  else if (G < 0)
2837  G = 0;
2838 
2839  B = Y12 + U5;
2840  if ((B >> 8) > 0)
2841  B = 255;
2842  else if (B < 0)
2843  B = 0;
2844 
2845  *rgba++ = (unsigned char)R;
2846  *rgba++ = (unsigned char)G;
2847  *rgba++ = (unsigned char)B;
2848  *rgba++ = vpRGBa::alpha_default;
2849 
2850  //---
2851  R = Y13 + V2;
2852  if ((R >> 8) > 0)
2853  R = 255;
2854  else if (R < 0)
2855  R = 0;
2856 
2857  G = Y13 + UV;
2858  if ((G >> 8) > 0)
2859  G = 255;
2860  else if (G < 0)
2861  G = 0;
2862 
2863  B = Y13 + U5;
2864  if ((B >> 8) > 0)
2865  B = 255;
2866  else if (B < 0)
2867  B = 0;
2868 
2869  *rgba++ = (unsigned char)R;
2870  *rgba++ = (unsigned char)G;
2871  *rgba++ = (unsigned char)B;
2872  *rgba++ = vpRGBa::alpha_default;
2873 
2874  //---
2875  R = Y14 + V2;
2876  if ((R >> 8) > 0)
2877  R = 255;
2878  else if (R < 0)
2879  R = 0;
2880 
2881  G = Y14 + UV;
2882  if ((G >> 8) > 0)
2883  G = 255;
2884  else if (G < 0)
2885  G = 0;
2886 
2887  B = Y14 + U5;
2888  if ((B >> 8) > 0)
2889  B = 255;
2890  else if (B < 0)
2891  B = 0;
2892 
2893  *rgba++ = (unsigned char)R;
2894  *rgba++ = (unsigned char)G;
2895  *rgba++ = (unsigned char)B;
2896  *rgba++ = vpRGBa::alpha_default;
2897 
2898  //---
2899  R = Y15 + V2;
2900  if ((R >> 8) > 0)
2901  R = 255;
2902  else if (R < 0)
2903  R = 0;
2904 
2905  G = Y15 + UV;
2906  if ((G >> 8) > 0)
2907  G = 255;
2908  else if (G < 0)
2909  G = 0;
2910 
2911  B = Y15 + U5;
2912  if ((B >> 8) > 0)
2913  B = 255;
2914  else if (B < 0)
2915  B = 0;
2916 
2917  *rgba++ = (unsigned char)R;
2918  *rgba++ = (unsigned char)G;
2919  *rgba++ = (unsigned char)B;
2920  *rgba = vpRGBa::alpha_default;
2921  rgba = rgba - 12 * width + 1;
2922  }
2923  yuv += 3 * width;
2924  rgba += 12 * width;
2925  }
2926 }
2932 void vpImageConvert::YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width)
2933 {
2934  // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
2935  int U, V, R, G, B, V2, U5, UV;
2936  int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2937  unsigned int size = width * height;
2938  unsigned char *iV = yuv + size;
2939  unsigned char *iU = yuv + 17 * size / 16;
2940  for (unsigned int i = 0; i < height / 4; i++) {
2941  for (unsigned int j = 0; j < width / 4; j++) {
2942  U = (int)((*iU++ - 128) * 0.354);
2943  U5 = 5 * U;
2944  V = (int)((*iV++ - 128) * 0.707);
2945  V2 = 2 * V;
2946  UV = -U - V;
2947  Y0 = *yuv++;
2948  Y1 = *yuv++;
2949  Y2 = *yuv++;
2950  Y3 = *yuv;
2951  yuv = yuv + width - 3;
2952  Y4 = *yuv++;
2953  Y5 = *yuv++;
2954  Y6 = *yuv++;
2955  Y7 = *yuv;
2956  yuv = yuv + width - 3;
2957  Y8 = *yuv++;
2958  Y9 = *yuv++;
2959  Y10 = *yuv++;
2960  Y11 = *yuv;
2961  yuv = yuv + width - 3;
2962  Y12 = *yuv++;
2963  Y13 = *yuv++;
2964  Y14 = *yuv++;
2965  Y15 = *yuv;
2966  yuv = yuv - 3 * width + 1;
2967 
2968  // Original equations
2969  // R = Y + 1.402 V
2970  // G = Y - 0.344 U - 0.714 V
2971  // B = Y + 1.772 U
2972  R = Y0 + V2;
2973  if ((R >> 8) > 0)
2974  R = 255;
2975  else if (R < 0)
2976  R = 0;
2977 
2978  G = Y0 + UV;
2979  if ((G >> 8) > 0)
2980  G = 255;
2981  else if (G < 0)
2982  G = 0;
2983 
2984  B = Y0 + U5;
2985  if ((B >> 8) > 0)
2986  B = 255;
2987  else if (B < 0)
2988  B = 0;
2989 
2990  *rgb++ = (unsigned char)R;
2991  *rgb++ = (unsigned char)G;
2992  *rgb++ = (unsigned char)B;
2993 
2994  //---
2995  R = Y1 + V2;
2996  if ((R >> 8) > 0)
2997  R = 255;
2998  else if (R < 0)
2999  R = 0;
3000 
3001  G = Y1 + UV;
3002  if ((G >> 8) > 0)
3003  G = 255;
3004  else if (G < 0)
3005  G = 0;
3006 
3007  B = Y1 + U5;
3008  if ((B >> 8) > 0)
3009  B = 255;
3010  else if (B < 0)
3011  B = 0;
3012 
3013  *rgb++ = (unsigned char)R;
3014  *rgb++ = (unsigned char)G;
3015  *rgb++ = (unsigned char)B;
3016 
3017  //---
3018  R = Y2 + V2;
3019  if ((R >> 8) > 0)
3020  R = 255;
3021  else if (R < 0)
3022  R = 0;
3023 
3024  G = Y2 + UV;
3025  if ((G >> 8) > 0)
3026  G = 255;
3027  else if (G < 0)
3028  G = 0;
3029 
3030  B = Y2 + U5;
3031  if ((B >> 8) > 0)
3032  B = 255;
3033  else if (B < 0)
3034  B = 0;
3035 
3036  *rgb++ = (unsigned char)R;
3037  *rgb++ = (unsigned char)G;
3038  *rgb++ = (unsigned char)B;
3039 
3040  //---
3041  R = Y3 + V2;
3042  if ((R >> 8) > 0)
3043  R = 255;
3044  else if (R < 0)
3045  R = 0;
3046 
3047  G = Y3 + UV;
3048  if ((G >> 8) > 0)
3049  G = 255;
3050  else if (G < 0)
3051  G = 0;
3052 
3053  B = Y3 + U5;
3054  if ((B >> 8) > 0)
3055  B = 255;
3056  else if (B < 0)
3057  B = 0;
3058 
3059  *rgb++ = (unsigned char)R;
3060  *rgb++ = (unsigned char)G;
3061  *rgb = (unsigned char)B;
3062  rgb = rgb + 3 * width - 11;
3063 
3064  R = Y4 + V2;
3065  if ((R >> 8) > 0)
3066  R = 255;
3067  else if (R < 0)
3068  R = 0;
3069 
3070  G = Y4 + UV;
3071  if ((G >> 8) > 0)
3072  G = 255;
3073  else if (G < 0)
3074  G = 0;
3075 
3076  B = Y4 + U5;
3077  if ((B >> 8) > 0)
3078  B = 255;
3079  else if (B < 0)
3080  B = 0;
3081 
3082  *rgb++ = (unsigned char)R;
3083  *rgb++ = (unsigned char)G;
3084  *rgb++ = (unsigned char)B;
3085 
3086  //---
3087  R = Y5 + V2;
3088  if ((R >> 8) > 0)
3089  R = 255;
3090  else if (R < 0)
3091  R = 0;
3092 
3093  G = Y5 + UV;
3094  if ((G >> 8) > 0)
3095  G = 255;
3096  else if (G < 0)
3097  G = 0;
3098 
3099  B = Y5 + U5;
3100  if ((B >> 8) > 0)
3101  B = 255;
3102  else if (B < 0)
3103  B = 0;
3104 
3105  *rgb++ = (unsigned char)R;
3106  *rgb++ = (unsigned char)G;
3107  *rgb++ = (unsigned char)B;
3108 
3109  //---
3110  R = Y6 + V2;
3111  if ((R >> 8) > 0)
3112  R = 255;
3113  else if (R < 0)
3114  R = 0;
3115 
3116  G = Y6 + UV;
3117  if ((G >> 8) > 0)
3118  G = 255;
3119  else if (G < 0)
3120  G = 0;
3121 
3122  B = Y6 + U5;
3123  if ((B >> 8) > 0)
3124  B = 255;
3125  else if (B < 0)
3126  B = 0;
3127 
3128  *rgb++ = (unsigned char)R;
3129  *rgb++ = (unsigned char)G;
3130  *rgb++ = (unsigned char)B;
3131 
3132  //---
3133  R = Y7 + V2;
3134  if ((R >> 8) > 0)
3135  R = 255;
3136  else if (R < 0)
3137  R = 0;
3138 
3139  G = Y7 + UV;
3140  if ((G >> 8) > 0)
3141  G = 255;
3142  else if (G < 0)
3143  G = 0;
3144 
3145  B = Y7 + 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  rgb = rgb + 3 * width - 11;
3155 
3156  R = Y8 + V2;
3157  if ((R >> 8) > 0)
3158  R = 255;
3159  else if (R < 0)
3160  R = 0;
3161 
3162  G = Y8 + UV;
3163  if ((G >> 8) > 0)
3164  G = 255;
3165  else if (G < 0)
3166  G = 0;
3167 
3168  B = Y8 + 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 = Y9 + V2;
3180  if ((R >> 8) > 0)
3181  R = 255;
3182  else if (R < 0)
3183  R = 0;
3184 
3185  G = Y9 + UV;
3186  if ((G >> 8) > 0)
3187  G = 255;
3188  else if (G < 0)
3189  G = 0;
3190 
3191  B = Y9 + 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 = Y10 + V2;
3203  if ((R >> 8) > 0)
3204  R = 255;
3205  else if (R < 0)
3206  R = 0;
3207 
3208  G = Y10 + UV;
3209  if ((G >> 8) > 0)
3210  G = 255;
3211  else if (G < 0)
3212  G = 0;
3213 
3214  B = Y10 + 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 
3224  //---
3225  R = Y11 + V2;
3226  if ((R >> 8) > 0)
3227  R = 255;
3228  else if (R < 0)
3229  R = 0;
3230 
3231  G = Y11 + UV;
3232  if ((G >> 8) > 0)
3233  G = 255;
3234  else if (G < 0)
3235  G = 0;
3236 
3237  B = Y11 + 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  rgb = rgb + 3 * width - 11;
3247 
3248  R = Y12 + V2;
3249  if ((R >> 8) > 0)
3250  R = 255;
3251  else if (R < 0)
3252  R = 0;
3253 
3254  G = Y12 + UV;
3255  if ((G >> 8) > 0)
3256  G = 255;
3257  else if (G < 0)
3258  G = 0;
3259 
3260  B = Y12 + 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 = Y13 + V2;
3272  if ((R >> 8) > 0)
3273  R = 255;
3274  else if (R < 0)
3275  R = 0;
3276 
3277  G = Y13 + UV;
3278  if ((G >> 8) > 0)
3279  G = 255;
3280  else if (G < 0)
3281  G = 0;
3282 
3283  B = Y13 + 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 = Y14 + V2;
3295  if ((R >> 8) > 0)
3296  R = 255;
3297  else if (R < 0)
3298  R = 0;
3299 
3300  G = Y14 + UV;
3301  if ((G >> 8) > 0)
3302  G = 255;
3303  else if (G < 0)
3304  G = 0;
3305 
3306  B = Y14 + 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 
3316  //---
3317  R = Y15 + V2;
3318  if ((R >> 8) > 0)
3319  R = 255;
3320  else if (R < 0)
3321  R = 0;
3322 
3323  G = Y15 + UV;
3324  if ((G >> 8) > 0)
3325  G = 255;
3326  else if (G < 0)
3327  G = 0;
3328 
3329  B = Y15 + 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  rgb = rgb - 9 * width + 1;
3339  }
3340  yuv += 3 * width;
3341  rgb += 9 * width;
3342  }
3343 }
3344 
3352 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
3353 {
3354  unsigned char *pt_input = rgb;
3355  unsigned char *pt_end = rgb + 3 * size;
3356  unsigned char *pt_output = rgba;
3357 
3358  while (pt_input != pt_end) {
3359  *(pt_output++) = *(pt_input++); // R
3360  *(pt_output++) = *(pt_input++); // G
3361  *(pt_output++) = *(pt_input++); // B
3362  *(pt_output++) = vpRGBa::alpha_default; // A
3363  }
3364 }
3365 
3373 void vpImageConvert::RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
3374 {
3375  unsigned char *pt_input = rgba;
3376  unsigned char *pt_end = rgba + 4 * size;
3377  unsigned char *pt_output = rgb;
3378 
3379  while (pt_input != pt_end) {
3380  *(pt_output++) = *(pt_input++); // R
3381  *(pt_output++) = *(pt_input++); // G
3382  *(pt_output++) = *(pt_input++); // B
3383  pt_input++;
3384  }
3385 }
3392 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
3393 {
3394  bool checkSSSE3 = vpCPUFeatures::checkSSSE3();
3395 #if !VISP_HAVE_SSSE3
3396  checkSSSE3 = false;
3397 #endif
3398 
3399  if (checkSSSE3) {
3400 #if VISP_HAVE_SSSE3
3401  unsigned int i = 0;
3402 
3403  if (size >= 16) {
3404  // Mask to select R component
3405  const __m128i mask_R1 = _mm_set_epi8(-1, -1, -1, -1, 15, -1, 12, -1, 9, -1, 6, -1, 3, -1, 0, -1);
3406  const __m128i mask_R2 = _mm_set_epi8(5, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3407  const __m128i mask_R3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, 11, -1, 8, -1);
3408  const __m128i mask_R4 = _mm_set_epi8(13, -1, 10, -1, 7, -1, 4, -1, 1, -1, -1, -1, -1, -1, -1, -1);
3409 
3410  // Mask to select G component
3411  const __m128i mask_G1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 13, -1, 10, -1, 7, -1, 4, -1, 1, -1);
3412  const __m128i mask_G2 = _mm_set_epi8(6, -1, 3, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3413  const __m128i mask_G3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 12, -1, 9, -1);
3414  const __m128i mask_G4 = _mm_set_epi8(14, -1, 11, -1, 8, -1, 5, -1, 2, -1, -1, -1, -1, -1, -1, -1);
3415 
3416  // Mask to select B component
3417  const __m128i mask_B1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 14, -1, 11, -1, 8, -1, 5, -1, 2, -1);
3418  const __m128i mask_B2 = _mm_set_epi8(7, -1, 4, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3419  const __m128i mask_B3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, -1, 10, -1);
3420  const __m128i mask_B4 = _mm_set_epi8(15, -1, 12, -1, 9, -1, 6, -1, 3, -1, 0, -1, -1, -1, -1, -1);
3421 
3422  // Mask to select the gray component
3423  const __m128i mask_low1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 15, 13, 11, 9, 7, 5, 3, 1);
3424  const __m128i mask_low2 = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1);
3425 
3426  // Coefficients RGB to Gray
3427  const __m128i coeff_R = _mm_set_epi16(13933, 13933, 13933, 13933, 13933, 13933, 13933, 13933);
3428  const __m128i coeff_G = _mm_set_epi16((short int)46871, (short int)46871, (short int)46871, (short int)46871,
3429  (short int)46871, (short int)46871, (short int)46871, (short int)46871);
3430  const __m128i coeff_B = _mm_set_epi16(4732, 4732, 4732, 4732, 4732, 4732, 4732, 4732);
3431 
3432  for (; i <= size - 16; i += 16) {
3433  // Process 16 color pixels
3434  const __m128i data1 = _mm_loadu_si128((const __m128i *)rgb);
3435  const __m128i data2 = _mm_loadu_si128((const __m128i *)(rgb + 16));
3436  const __m128i data3 = _mm_loadu_si128((const __m128i *)(rgb + 32));
3437 
3438  const __m128i red_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_R1), _mm_shuffle_epi8(data2, mask_R2));
3439  const __m128i green_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_G1), _mm_shuffle_epi8(data2, mask_G2));
3440  const __m128i blue_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_B1), _mm_shuffle_epi8(data2, mask_B2));
3441 
3442  const __m128i grays_0_7 =
3443  _mm_adds_epu16(_mm_mulhi_epu16(red_0_7, coeff_R),
3444  _mm_adds_epu16(_mm_mulhi_epu16(green_0_7, coeff_G), _mm_mulhi_epu16(blue_0_7, coeff_B)));
3445 
3446  const __m128i red_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_R3), _mm_shuffle_epi8(data3, mask_R4));
3447  const __m128i green_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_G3), _mm_shuffle_epi8(data3, mask_G4));
3448  const __m128i blue_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_B3), _mm_shuffle_epi8(data3, mask_B4));
3449 
3450  const __m128i grays_8_15 =
3451  _mm_adds_epu16(_mm_mulhi_epu16(red_8_15, coeff_R),
3452  _mm_adds_epu16(_mm_mulhi_epu16(green_8_15, coeff_G), _mm_mulhi_epu16(blue_8_15, coeff_B)));
3453 
3454  _mm_storeu_si128((__m128i *)grey,
3455  _mm_or_si128(_mm_shuffle_epi8(grays_0_7, mask_low1), _mm_shuffle_epi8(grays_8_15, mask_low2)));
3456 
3457  rgb += 48;
3458  grey += 16;
3459  }
3460  }
3461 
3462  for (; i < size; i++) {
3463  *grey = (unsigned char)(0.2126 * (*rgb) + 0.7152 * (*(rgb + 1)) + 0.0722 * (*(rgb + 2)));
3464 
3465  rgb += 3;
3466  ++grey;
3467  }
3468 #endif
3469  } else {
3470  unsigned char *pt_input = rgb;
3471  unsigned char *pt_end = rgb + size * 3;
3472  unsigned char *pt_output = grey;
3473 
3474  while (pt_input != pt_end) {
3475  *pt_output = (unsigned char)(0.2126 * (*pt_input) + 0.7152 * (*(pt_input + 1)) + 0.0722 * (*(pt_input + 2)));
3476  pt_input += 3;
3477  pt_output++;
3478  }
3479  }
3480 }
3488 void vpImageConvert::RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
3489 {
3490  bool checkSSSE3 = vpCPUFeatures::checkSSSE3();
3491 #if !VISP_HAVE_SSSE3
3492  checkSSSE3 = false;
3493 #endif
3494 
3495  if (checkSSSE3) {
3496 #if VISP_HAVE_SSSE3
3497  unsigned int i = 0;
3498 
3499  if (size >= 16) {
3500  // Mask to select R component
3501  const __m128i mask_R1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 12, -1, 8, -1, 4, -1, 0, -1);
3502  const __m128i mask_R2 = _mm_set_epi8(12, -1, 8, -1, 4, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3503 
3504  // Mask to select G component
3505  const __m128i mask_G1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 13, -1, 9, -1, 5, -1, 1, -1);
3506  const __m128i mask_G2 = _mm_set_epi8(13, -1, 9, -1, 5, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3507 
3508  // Mask to select B component
3509  const __m128i mask_B1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 14, -1, 10, -1, 6, -1, 2, -1);
3510  const __m128i mask_B2 = _mm_set_epi8(14, -1, 10, -1, 6, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3511 
3512  // Mask to select the gray component
3513  const __m128i mask_low1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 15, 13, 11, 9, 7, 5, 3, 1);
3514  const __m128i mask_low2 = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1);
3515 
3516  // Coefficients RGB to Gray
3517  const __m128i coeff_R = _mm_set_epi16(13933, 13933, 13933, 13933, 13933, 13933, 13933, 13933);
3518  const __m128i coeff_G = _mm_set_epi16((short int)46871, (short int)46871, (short int)46871, (short int)46871,
3519  (short int)46871, (short int)46871, (short int)46871, (short int)46871);
3520  const __m128i coeff_B = _mm_set_epi16(4732, 4732, 4732, 4732, 4732, 4732, 4732, 4732);
3521 
3522  for (; i <= size - 16; i += 16) {
3523  // Process 2*4 color pixels
3524  const __m128i data1 = _mm_loadu_si128((const __m128i *)rgba);
3525  const __m128i data2 = _mm_loadu_si128((const __m128i *)(rgba + 16));
3526 
3527  const __m128i red_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_R1), _mm_shuffle_epi8(data2, mask_R2));
3528  const __m128i green_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_G1), _mm_shuffle_epi8(data2, mask_G2));
3529  const __m128i blue_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_B1), _mm_shuffle_epi8(data2, mask_B2));
3530 
3531  const __m128i grays_0_7 =
3532  _mm_adds_epu16(_mm_mulhi_epu16(red_0_7, coeff_R),
3533  _mm_adds_epu16(_mm_mulhi_epu16(green_0_7, coeff_G), _mm_mulhi_epu16(blue_0_7, coeff_B)));
3534 
3535  // Process next 2*4 color pixels
3536  const __m128i data3 = _mm_loadu_si128((const __m128i *)(rgba + 32));
3537  const __m128i data4 = _mm_loadu_si128((const __m128i *)(rgba + 48));
3538 
3539  const __m128i red_8_15 = _mm_or_si128(_mm_shuffle_epi8(data3, mask_R1), _mm_shuffle_epi8(data4, mask_R2));
3540  const __m128i green_8_15 = _mm_or_si128(_mm_shuffle_epi8(data3, mask_G1), _mm_shuffle_epi8(data4, mask_G2));
3541  const __m128i blue_8_15 = _mm_or_si128(_mm_shuffle_epi8(data3, mask_B1), _mm_shuffle_epi8(data4, mask_B2));
3542 
3543  const __m128i grays_8_15 =
3544  _mm_adds_epu16(_mm_mulhi_epu16(red_8_15, coeff_R),
3545  _mm_adds_epu16(_mm_mulhi_epu16(green_8_15, coeff_G), _mm_mulhi_epu16(blue_8_15, coeff_B)));
3546 
3547  _mm_storeu_si128((__m128i *)grey,
3548  _mm_or_si128(_mm_shuffle_epi8(grays_0_7, mask_low1), _mm_shuffle_epi8(grays_8_15, mask_low2)));
3549 
3550  rgba += 64;
3551  grey += 16;
3552  }
3553  }
3554 
3555  for (; i < size; i++) {
3556  *grey = (unsigned char)(0.2126 * (*rgba) + 0.7152 * (*(rgba + 1)) + 0.0722 * (*(rgba + 2)));
3557 
3558  rgba += 4;
3559  ++grey;
3560  }
3561 #endif
3562  } else {
3563  unsigned char *pt_input = rgba;
3564  unsigned char *pt_end = rgba + size * 4;
3565  unsigned char *pt_output = grey;
3566 
3567  while (pt_input != pt_end) {
3568  *pt_output = (unsigned char)(0.2126 * (*pt_input) + 0.7152 * (*(pt_input + 1)) + 0.0722 * (*(pt_input + 2)));
3569  pt_input += 4;
3570  pt_output++;
3571  }
3572  }
3573 }
3574 
3580 void vpImageConvert::GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
3581 {
3582  unsigned char *pt_input = grey;
3583  unsigned char *pt_end = grey + size;
3584  unsigned char *pt_output = rgba;
3585 
3586  while (pt_input != pt_end) {
3587  unsigned char p = *pt_input;
3588  *(pt_output) = p; // R
3589  *(pt_output + 1) = p; // G
3590  *(pt_output + 2) = p; // B
3591  *(pt_output + 3) = vpRGBa::alpha_default; // A
3592 
3593  pt_input++;
3594  pt_output += 4;
3595  }
3596 }
3597 
3602 void vpImageConvert::GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
3603 {
3604  unsigned char *pt_input = grey;
3605  unsigned char *pt_end = grey + size;
3606  unsigned char *pt_output = rgb;
3607 
3608  while (pt_input != pt_end) {
3609  unsigned char p = *pt_input;
3610  *(pt_output) = p; // R
3611  *(pt_output + 1) = p; // G
3612  *(pt_output + 2) = p; // B
3613 
3614  pt_input++;
3615  pt_output += 3;
3616  }
3617 }
3618 
3626 void vpImageConvert::BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height,
3627  bool flip)
3628 {
3629  // if we have to flip the image, we start from the end last scanline so the
3630  // step is negative
3631  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3632 
3633  // starting source address = last line if we need to flip the image
3634  unsigned char *src = (flip) ? (bgr + (width * height * 3) + lineStep) : bgr;
3635 
3636  for (unsigned int i = 0; i < height; i++) {
3637  unsigned char *line = src;
3638  for (unsigned int j = 0; j < width; j++) {
3639  *rgba++ = *(line + 2);
3640  *rgba++ = *(line + 1);
3641  *rgba++ = *(line + 0);
3642  *rgba++ = vpRGBa::alpha_default;
3643 
3644  line += 3;
3645  }
3646  // go to the next line
3647  src += lineStep;
3648  }
3649 }
3650 
3656 void vpImageConvert::BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height,
3657  bool flip)
3658 {
3659  bool checkSSSE3 = vpCPUFeatures::checkSSSE3();
3660 #if !VISP_HAVE_SSSE3
3661  checkSSSE3 = false;
3662 #endif
3663 
3664  if (checkSSSE3) {
3665 #if VISP_HAVE_SSSE3
3666  // Mask to select B component
3667  const __m128i mask_B1 = _mm_set_epi8(-1, -1, -1, -1, 15, -1, 12, -1, 9, -1, 6, -1, 3, -1, 0, -1);
3668  const __m128i mask_B2 = _mm_set_epi8(5, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3669  const __m128i mask_B3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, 11, -1, 8, -1);
3670  const __m128i mask_B4 = _mm_set_epi8(13, -1, 10, -1, 7, -1, 4, -1, 1, -1, -1, -1, -1, -1, -1, -1);
3671 
3672  // Mask to select G component
3673  const __m128i mask_G1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 13, -1, 10, -1, 7, -1, 4, -1, 1, -1);
3674  const __m128i mask_G2 = _mm_set_epi8(6, -1, 3, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3675  const __m128i mask_G3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 12, -1, 9, -1);
3676  const __m128i mask_G4 = _mm_set_epi8(14, -1, 11, -1, 8, -1, 5, -1, 2, -1, -1, -1, -1, -1, -1, -1);
3677 
3678  // Mask to select R component
3679  const __m128i mask_R1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 14, -1, 11, -1, 8, -1, 5, -1, 2, -1);
3680  const __m128i mask_R2 = _mm_set_epi8(7, -1, 4, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3681  const __m128i mask_R3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, -1, 10, -1);
3682  const __m128i mask_R4 = _mm_set_epi8(15, -1, 12, -1, 9, -1, 6, -1, 3, -1, 0, -1, -1, -1, -1, -1);
3683 
3684  // Mask to select the gray component
3685  const __m128i mask_low1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 15, 13, 11, 9, 7, 5, 3, 1);
3686  const __m128i mask_low2 = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1);
3687 
3688  // Coefficients RGB to Gray
3689  // const __m128i coeff_R = _mm_set_epi8(
3690  // 54, -1, 54, -1, 54, -1, 54, -1, 54, -1, 54, -1, 54, -1, 54, -1
3691  // );
3692  // const __m128i coeff_G = _mm_set_epi8(
3693  // 183, -1, 183, -1, 183, -1, 183, -1, 183, -1, 183, -1, 183, -1,
3694  // 183, -1
3695  // );
3696  // const __m128i coeff_B = _mm_set_epi8(
3697  // 18, -1, 18, -1, 18, -1, 18, -1, 18, -1, 18, -1, 18, -1, 18, -1
3698  // );
3699  // const __m128i coeff_R = _mm_set_epi16(
3700  // 6969*2, 6969*2, 6969*2, 6969*2, 6969*2, 6969*2, 6969*2, 6969*2
3701  // );
3702  // const __m128i coeff_G = _mm_set_epi16(
3703  // 23434*2, 23434*2, 23434*2, 23434*2, 23434*2, 23434*2, 23434*2,
3704  // 23434*2
3705  // );
3706  // const __m128i coeff_B = _mm_set_epi16(
3707  // 2365*2, 2365*2, 2365*2, 2365*2, 2365*2, 2365*2, 2365*2, 2365*2
3708  // );
3709  const __m128i coeff_R = _mm_set_epi16(13933, 13933, 13933, 13933, 13933, 13933, 13933, 13933);
3710  const __m128i coeff_G = _mm_set_epi16((short int)46871, (short int)46871, (short int)46871, (short int)46871,
3711  (short int)46871, (short int)46871, (short int)46871, (short int)46871);
3712  const __m128i coeff_B = _mm_set_epi16(4732, 4732, 4732, 4732, 4732, 4732, 4732, 4732);
3713 
3714  if (flip) {
3715  int i = ((int)height) - 1;
3716  int lineStep = -(int)(width * 3);
3717  bgr = bgr + (width * (height - 1) * 3);
3718 
3719  unsigned char *linePtr = bgr;
3720  unsigned char r, g, b;
3721 
3722  if (width >= 16) {
3723  for (; i >= 0; i--) {
3724  unsigned int j = 0;
3725 
3726  for (; j <= width - 16; j += 16) {
3727  // Process 16 color pixels
3728  const __m128i data1 = _mm_loadu_si128((const __m128i *)bgr);
3729  const __m128i data2 = _mm_loadu_si128((const __m128i *)(bgr + 16));
3730  const __m128i data3 = _mm_loadu_si128((const __m128i *)(bgr + 32));
3731 
3732  const __m128i red_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_R1), _mm_shuffle_epi8(data2, mask_R2));
3733  const __m128i green_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_G1), _mm_shuffle_epi8(data2, mask_G2));
3734  const __m128i blue_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_B1), _mm_shuffle_epi8(data2, mask_B2));
3735 
3736  const __m128i grays_0_7 =
3737  _mm_adds_epu16(_mm_mulhi_epu16(red_0_7, coeff_R),
3738  _mm_adds_epu16(_mm_mulhi_epu16(green_0_7, coeff_G), _mm_mulhi_epu16(blue_0_7, coeff_B)));
3739 
3740  const __m128i red_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_R3), _mm_shuffle_epi8(data3, mask_R4));
3741  const __m128i green_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_G3), _mm_shuffle_epi8(data3, mask_G4));
3742  const __m128i blue_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_B3), _mm_shuffle_epi8(data3, mask_B4));
3743 
3744  const __m128i grays_8_15 =
3745  _mm_adds_epu16(_mm_mulhi_epu16(red_8_15, coeff_R), _mm_adds_epu16(_mm_mulhi_epu16(green_8_15, coeff_G),
3746  _mm_mulhi_epu16(blue_8_15, coeff_B)));
3747 
3748  _mm_storeu_si128((__m128i *)grey, _mm_or_si128(_mm_shuffle_epi8(grays_0_7, mask_low1),
3749  _mm_shuffle_epi8(grays_8_15, mask_low2)));
3750 
3751  bgr += 48;
3752  grey += 16;
3753  }
3754 
3755  for (; j < width; j++) {
3756  b = *(bgr++);
3757  g = *(bgr++);
3758  r = *(bgr++);
3759  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3760  }
3761 
3762  linePtr += lineStep;
3763  bgr = linePtr;
3764  }
3765  }
3766 
3767  for (; i >= 0; i--) {
3768  for (unsigned int j = 0; j < width; j++) {
3769  b = *(bgr++);
3770  g = *(bgr++);
3771  r = *(bgr++);
3772  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3773  }
3774 
3775  linePtr += lineStep;
3776  bgr = linePtr;
3777  }
3778  } else {
3779  unsigned int i = 0;
3780  unsigned int size = width * height;
3781 
3782  if (size >= 16) {
3783  for (; i <= size - 16; i += 16) {
3784  // Process 16 color pixels
3785  const __m128i data1 = _mm_loadu_si128((const __m128i *)bgr);
3786  const __m128i data2 = _mm_loadu_si128((const __m128i *)(bgr + 16));
3787  const __m128i data3 = _mm_loadu_si128((const __m128i *)(bgr + 32));
3788 
3789  const __m128i red_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_R1), _mm_shuffle_epi8(data2, mask_R2));
3790  const __m128i green_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_G1), _mm_shuffle_epi8(data2, mask_G2));
3791  const __m128i blue_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_B1), _mm_shuffle_epi8(data2, mask_B2));
3792 
3793  const __m128i grays_0_7 =
3794  _mm_adds_epu16(_mm_mulhi_epu16(red_0_7, coeff_R),
3795  _mm_adds_epu16(_mm_mulhi_epu16(green_0_7, coeff_G), _mm_mulhi_epu16(blue_0_7, coeff_B)));
3796 
3797  const __m128i red_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_R3), _mm_shuffle_epi8(data3, mask_R4));
3798  const __m128i green_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_G3), _mm_shuffle_epi8(data3, mask_G4));
3799  const __m128i blue_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_B3), _mm_shuffle_epi8(data3, mask_B4));
3800 
3801  const __m128i grays_8_15 =
3802  _mm_adds_epu16(_mm_mulhi_epu16(red_8_15, coeff_R),
3803  _mm_adds_epu16(_mm_mulhi_epu16(green_8_15, coeff_G), _mm_mulhi_epu16(blue_8_15, coeff_B)));
3804 
3805  _mm_storeu_si128((__m128i *)grey, _mm_or_si128(_mm_shuffle_epi8(grays_0_7, mask_low1),
3806  _mm_shuffle_epi8(grays_8_15, mask_low2)));
3807 
3808  bgr += 48;
3809  grey += 16;
3810  }
3811  }
3812 
3813  for (; i < size; i++) {
3814  *grey = (unsigned char)(0.2126 * (*(bgr + 2)) + 0.7152 * (*(bgr + 1)) + 0.0722 * (*bgr));
3815 
3816  bgr += 3;
3817  ++grey;
3818  }
3819  }
3820 #endif
3821  } else {
3822  // if we have to flip the image, we start from the end last scanline so
3823  // the step is negative
3824  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3825 
3826  // starting source address = last line if we need to flip the image
3827  unsigned char *src = (flip) ? bgr + (width * height * 3) + lineStep : bgr;
3828 
3829  for (unsigned int i = 0; i < height; i++) {
3830  unsigned char *line = src;
3831  for (unsigned int j = 0; j < width; j++) {
3832  *grey++ = (unsigned char)(0.2126 * *(line + 2) + 0.7152 * *(line + 1) + 0.0722 * *(line + 0));
3833  line += 3;
3834  }
3835 
3836  // go to the next line
3837  src += lineStep;
3838  }
3839  }
3840 }
3841 
3849 void vpImageConvert::RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int width, unsigned int height,
3850  bool flip)
3851 {
3852  // if we have to flip the image, we start from the end last scanline so the
3853  // step is negative
3854  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3855 
3856  // starting source address = last line if we need to flip the image
3857  unsigned char *src = (flip) ? (rgb + (width * height * 3) + lineStep) : rgb;
3858 
3859  unsigned int j = 0;
3860  unsigned int i = 0;
3861 
3862  for (i = 0; i < height; i++) {
3863  unsigned char *line = src;
3864  for (j = 0; j < width; j++) {
3865  *rgba++ = *(line++);
3866  *rgba++ = *(line++);
3867  *rgba++ = *(line++);
3868  *rgba++ = vpRGBa::alpha_default;
3869  }
3870  // go to the next line
3871  src += lineStep;
3872  }
3873 }
3874 
3880 void vpImageConvert::RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height,
3881  bool flip)
3882 {
3883  if (flip) {
3884  bool checkSSSE3 = vpCPUFeatures::checkSSSE3();
3885 #if !VISP_HAVE_SSSE3
3886  checkSSSE3 = false;
3887 #endif
3888 
3889  if (checkSSSE3) {
3890 #if VISP_HAVE_SSSE3
3891  int i = ((int)height) - 1;
3892  int lineStep = -(int)(width * 3);
3893  rgb = rgb + (width * (height - 1) * 3);
3894 
3895  unsigned char *linePtr = rgb;
3896  unsigned char r, g, b;
3897 
3898  if (width >= 16) {
3899  // Mask to select R component
3900  const __m128i mask_R1 = _mm_set_epi8(-1, -1, -1, -1, 15, -1, 12, -1, 9, -1, 6, -1, 3, -1, 0, -1);
3901  const __m128i mask_R2 = _mm_set_epi8(5, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3902  const __m128i mask_R3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, 11, -1, 8, -1);
3903  const __m128i mask_R4 = _mm_set_epi8(13, -1, 10, -1, 7, -1, 4, -1, 1, -1, -1, -1, -1, -1, -1, -1);
3904 
3905  // Mask to select G component
3906  const __m128i mask_G1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 13, -1, 10, -1, 7, -1, 4, -1, 1, -1);
3907  const __m128i mask_G2 = _mm_set_epi8(6, -1, 3, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3908  const __m128i mask_G3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 12, -1, 9, -1);
3909  const __m128i mask_G4 = _mm_set_epi8(14, -1, 11, -1, 8, -1, 5, -1, 2, -1, -1, -1, -1, -1, -1, -1);
3910 
3911  // Mask to select B component
3912  const __m128i mask_B1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, 14, -1, 11, -1, 8, -1, 5, -1, 2, -1);
3913  const __m128i mask_B2 = _mm_set_epi8(7, -1, 4, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
3914  const __m128i mask_B3 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13, -1, 10, -1);
3915  const __m128i mask_B4 = _mm_set_epi8(15, -1, 12, -1, 9, -1, 6, -1, 3, -1, 0, -1, -1, -1, -1, -1);
3916 
3917  // Mask to select the gray component
3918  const __m128i mask_low1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 15, 13, 11, 9, 7, 5, 3, 1);
3919  const __m128i mask_low2 = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1);
3920 
3921  // Coefficients RGB to Gray
3922  const __m128i coeff_R = _mm_set_epi16(13933, 13933, 13933, 13933, 13933, 13933, 13933, 13933);
3923  const __m128i coeff_G = _mm_set_epi16((short int)46871, (short int)46871, (short int)46871, (short int)46871,
3924  (short int)46871, (short int)46871, (short int)46871, (short int)46871);
3925  const __m128i coeff_B = _mm_set_epi16(4732, 4732, 4732, 4732, 4732, 4732, 4732, 4732);
3926 
3927  for (; i >= 0; i--) {
3928  unsigned int j = 0;
3929 
3930  for (; j <= width - 16; j += 16) {
3931  // Process 16 color pixels
3932  const __m128i data1 = _mm_loadu_si128((const __m128i *)rgb);
3933  const __m128i data2 = _mm_loadu_si128((const __m128i *)(rgb + 16));
3934  const __m128i data3 = _mm_loadu_si128((const __m128i *)(rgb + 32));
3935 
3936  const __m128i red_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_R1), _mm_shuffle_epi8(data2, mask_R2));
3937  const __m128i green_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_G1), _mm_shuffle_epi8(data2, mask_G2));
3938  const __m128i blue_0_7 = _mm_or_si128(_mm_shuffle_epi8(data1, mask_B1), _mm_shuffle_epi8(data2, mask_B2));
3939 
3940  const __m128i grays_0_7 =
3941  _mm_adds_epu16(_mm_mulhi_epu16(red_0_7, coeff_R),
3942  _mm_adds_epu16(_mm_mulhi_epu16(green_0_7, coeff_G), _mm_mulhi_epu16(blue_0_7, coeff_B)));
3943 
3944  const __m128i red_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_R3), _mm_shuffle_epi8(data3, mask_R4));
3945  const __m128i green_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_G3), _mm_shuffle_epi8(data3, mask_G4));
3946  const __m128i blue_8_15 = _mm_or_si128(_mm_shuffle_epi8(data2, mask_B3), _mm_shuffle_epi8(data3, mask_B4));
3947 
3948  const __m128i grays_8_15 =
3949  _mm_adds_epu16(_mm_mulhi_epu16(red_8_15, coeff_R), _mm_adds_epu16(_mm_mulhi_epu16(green_8_15, coeff_G),
3950  _mm_mulhi_epu16(blue_8_15, coeff_B)));
3951 
3952  _mm_storeu_si128((__m128i *)grey, _mm_or_si128(_mm_shuffle_epi8(grays_0_7, mask_low1),
3953  _mm_shuffle_epi8(grays_8_15, mask_low2)));
3954 
3955  rgb += 48;
3956  grey += 16;
3957  }
3958 
3959  for (; j < width; j++) {
3960  r = *(rgb++);
3961  g = *(rgb++);
3962  b = *(rgb++);
3963  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3964  }
3965 
3966  linePtr += lineStep;
3967  rgb = linePtr;
3968  }
3969  }
3970 
3971  for (; i >= 0; i--) {
3972  for (unsigned int j = 0; j < width; j++) {
3973  r = *(rgb++);
3974  g = *(rgb++);
3975  b = *(rgb++);
3976  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
3977  }
3978 
3979  linePtr += lineStep;
3980  rgb = linePtr;
3981  }
3982 #endif
3983  } else {
3984  // if we have to flip the image, we start from the end last scanline so
3985  // the step is negative
3986  int lineStep = (flip) ? -(int)(width * 3) : (int)(width * 3);
3987 
3988  // starting source address = last line if we need to flip the image
3989  unsigned char *src = (flip) ? rgb + (width * height * 3) + lineStep : rgb;
3990 
3991  unsigned int j = 0;
3992  unsigned int i = 0;
3993 
3994  unsigned r, g, b;
3995 
3996  for (i = 0; i < height; i++) {
3997  unsigned char *line = src;
3998  for (j = 0; j < width; j++) {
3999  r = *(line++);
4000  g = *(line++);
4001  b = *(line++);
4002  *grey++ = (unsigned char)(0.2126 * r + 0.7152 * g + 0.0722 * b);
4003  }
4004 
4005  // go to the next line
4006  src += lineStep;
4007  }
4008  }
4009  } else {
4010  RGBToGrey(rgb, grey, width * height);
4011  }
4012 }
4013 
4017 void vpImageConvert::computeYCbCrLUT()
4018 {
4019  if (YCbCrLUTcomputed == false) {
4020  int index = 256;
4021 
4022  while (index--) {
4023 
4024  int aux = index - 128;
4025  vpImageConvert::vpCrr[index] = (int)(364.6610 * aux) >> 8;
4026  vpImageConvert::vpCgb[index] = (int)(-89.8779 * aux) >> 8;
4027  vpImageConvert::vpCgr[index] = (int)(-185.8154 * aux) >> 8;
4028  vpImageConvert::vpCbb[index] = (int)(460.5724 * aux) >> 8;
4029  }
4030 
4031  YCbCrLUTcomputed = true;
4032  }
4033 }
4034 
4054 void vpImageConvert::YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
4055 {
4056  unsigned char *cbv;
4057  unsigned char *crv;
4058  unsigned char *pt_ycbcr = ycbcr;
4059  unsigned char *pt_rgb = rgb;
4060  cbv = pt_ycbcr + 1;
4061  crv = pt_ycbcr + 3;
4062 
4063  vpImageConvert::computeYCbCrLUT();
4064 
4065  int col = 0;
4066 
4067  while (size--) {
4068  int val_r, val_g, val_b;
4069  if (!(col++ % 2)) {
4070  cbv = pt_ycbcr + 1;
4071  crv = pt_ycbcr + 3;
4072  }
4073 
4074  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4075  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4076  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4077 
4078  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4079 
4080  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4081  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4082  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4083 
4084  pt_ycbcr += 2;
4085  }
4086 }
4087 
4111 void vpImageConvert::YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgba, unsigned int size)
4112 {
4113  unsigned char *cbv;
4114  unsigned char *crv;
4115  unsigned char *pt_ycbcr = ycbcr;
4116  unsigned char *pt_rgba = rgba;
4117  cbv = pt_ycbcr + 1;
4118  crv = pt_ycbcr + 3;
4119 
4120  vpImageConvert::computeYCbCrLUT();
4121 
4122  int col = 0;
4123 
4124  while (size--) {
4125  int val_r, val_g, val_b;
4126  if (!(col++ % 2)) {
4127  cbv = pt_ycbcr + 1;
4128  crv = pt_ycbcr + 3;
4129  }
4130 
4131  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4132  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4133  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4134 
4135  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4136 
4137  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4138  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4139  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4140  *pt_rgba++ = vpRGBa::alpha_default;
4141 
4142  pt_ycbcr += 2;
4143  }
4144 }
4145 
4162 void vpImageConvert::YCbCrToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
4163 {
4164  unsigned int i = 0, j = 0;
4165 
4166  while (j < size * 2) {
4167  grey[i++] = yuv[j];
4168  grey[i++] = yuv[j + 2];
4169  j += 4;
4170  }
4171 }
4172 
4191 void vpImageConvert::YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
4192 {
4193  unsigned char *cbv;
4194  unsigned char *crv;
4195  unsigned char *pt_ycbcr = ycrcb;
4196  unsigned char *pt_rgb = rgb;
4197  crv = pt_ycbcr + 1;
4198  cbv = pt_ycbcr + 3;
4199 
4200  vpImageConvert::computeYCbCrLUT();
4201 
4202  int col = 0;
4203 
4204  while (size--) {
4205  int val_r, val_g, val_b;
4206  if (!(col++ % 2)) {
4207  crv = pt_ycbcr + 1;
4208  cbv = pt_ycbcr + 3;
4209  }
4210 
4211  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4212  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4213  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4214 
4215  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4216 
4217  *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4218  *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4219  *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4220 
4221  pt_ycbcr += 2;
4222  }
4223 }
4246 void vpImageConvert::YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgba, unsigned int size)
4247 {
4248  unsigned char *cbv;
4249  unsigned char *crv;
4250  unsigned char *pt_ycbcr = ycrcb;
4251  unsigned char *pt_rgba = rgba;
4252  crv = pt_ycbcr + 1;
4253  cbv = pt_ycbcr + 3;
4254 
4255  vpImageConvert::computeYCbCrLUT();
4256 
4257  int col = 0;
4258 
4259  while (size--) {
4260  int val_r, val_g, val_b;
4261  if (!(col++ % 2)) {
4262  crv = pt_ycbcr + 1;
4263  cbv = pt_ycbcr + 3;
4264  }
4265 
4266  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4267  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4268  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4269 
4270  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
4271 
4272  *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
4273  *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
4274  *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
4275  *pt_rgba++ = vpRGBa::alpha_default;
4276 
4277  pt_ycbcr += 2;
4278  }
4279 }
4280 
4318 {
4319  size_t n = src.getNumberOfPixel();
4320  unsigned int height = src.getHeight();
4321  unsigned int width = src.getWidth();
4322  unsigned char *input;
4323  unsigned char *dst;
4324 
4325  vpImage<unsigned char> *tabChannel[4];
4326 
4327  /* incrsrc[0] = 0; //init
4328  incrsrc[1] = 0; //step after the first used channel
4329  incrsrc[2] = 0; //step after the second used channel
4330  incrsrc[3] = 0;
4331  incrsrc[4] = 0;
4332  */
4333  tabChannel[0] = pR;
4334  tabChannel[1] = pG;
4335  tabChannel[2] = pB;
4336  tabChannel[3] = pa;
4337 
4338  size_t i; /* ordre */
4339  for (unsigned int j = 0; j < 4; j++) {
4340  if (tabChannel[j] != NULL) {
4341  if (tabChannel[j]->getHeight() != height || tabChannel[j]->getWidth() != width) {
4342  tabChannel[j]->resize(height, width);
4343  }
4344  dst = (unsigned char *)tabChannel[j]->bitmap;
4345 
4346  input = (unsigned char *)src.bitmap + j;
4347  i = 0;
4348 #if 1 // optimization
4349  if (n >= 4) { /* boucle deroulee lsize fois */
4350  n -= 3;
4351  for (; i < n; i += 4) {
4352  *dst = *input;
4353  input += 4;
4354  dst++;
4355  *dst = *input;
4356  input += 4;
4357  dst++;
4358  *dst = *input;
4359  input += 4;
4360  dst++;
4361  *dst = *input;
4362  input += 4;
4363  dst++;
4364  }
4365  n += 3;
4366  }
4367 #endif
4368  for (; i < n; i++) {
4369  *dst = *input;
4370  input += 4;
4371  dst++;
4372  }
4373  }
4374  }
4375 }
4376 
4387 {
4388  // Check if the input channels have all the same dimensions
4389  std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
4390  if (R != NULL) {
4391  mapOfWidths[R->getWidth()]++;
4392  mapOfHeights[R->getHeight()]++;
4393  }
4394 
4395  if (G != NULL) {
4396  mapOfWidths[G->getWidth()]++;
4397  mapOfHeights[G->getHeight()]++;
4398  }
4399 
4400  if (B != NULL) {
4401  mapOfWidths[B->getWidth()]++;
4402  mapOfHeights[B->getHeight()]++;
4403  }
4404 
4405  if (a != NULL) {
4406  mapOfWidths[a->getWidth()]++;
4407  mapOfHeights[a->getHeight()]++;
4408  }
4409 
4410  if (mapOfWidths.size() == 1 && mapOfHeights.size() == 1) {
4411  unsigned int width = mapOfWidths.begin()->first;
4412  unsigned int height = mapOfHeights.begin()->first;
4413 
4414  RGBa.resize(height, width);
4415 
4416  unsigned int size = width * height;
4417  for (unsigned int i = 0; i < size; i++) {
4418  if (R != NULL) {
4419  RGBa.bitmap[i].R = R->bitmap[i];
4420  }
4421 
4422  if (G != NULL) {
4423  RGBa.bitmap[i].G = G->bitmap[i];
4424  }
4425 
4426  if (B != NULL) {
4427  RGBa.bitmap[i].B = B->bitmap[i];
4428  }
4429 
4430  if (a != NULL) {
4431  RGBa.bitmap[i].A = a->bitmap[i];
4432  }
4433  }
4434  } else {
4435  throw vpException(vpException::dimensionError, "Mismatch dimensions !");
4436  }
4437 }
4438 
4449 void vpImageConvert::MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
4450 {
4451  int i = (((int)size) << 1) - 1;
4452  int j = (int)size - 1;
4453 
4454  while (i >= 0) {
4455  int y = grey16[i--];
4456  grey[j--] = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4457  }
4458 }
4459 
4472 void vpImageConvert::MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
4473 {
4474  int i = (((int)size) << 1) - 1;
4475  int j = (int)(size * 4 - 1);
4476 
4477  while (i >= 0) {
4478  int y = grey16[i--];
4479  unsigned char v = static_cast<unsigned char>((y + (grey16[i--] << 8)) >> 8);
4480  rgba[j--] = vpRGBa::alpha_default;
4481  rgba[j--] = v;
4482  rgba[j--] = v;
4483  rgba[j--] = v;
4484  }
4485 }
4486 
4487 void vpImageConvert::HSV2RGB(const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
4488  const unsigned int size, const unsigned int step)
4489 {
4490  for (unsigned int i = 0; i < size; i++) {
4491  double hue = hue_[i], saturation = saturation_[i], value = value_[i];
4492 
4493  if (vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
4494  hue = value;
4495  saturation = value;
4496  } else {
4497  double h = hue * 6.0;
4498  double s = saturation;
4499  double v = value;
4500 
4501  if (vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
4502  h = 0.0;
4503  }
4504 
4505  double f = h - (int)h;
4506  double p = v * (1.0 - s);
4507  double q = v * (1.0 - s * f);
4508  double t = v * (1.0 - s * (1.0 - f));
4509 
4510  switch ((int)h) {
4511  case 0:
4512  hue = v;
4513  saturation = t;
4514  value = p;
4515  break;
4516 
4517  case 1:
4518  hue = q;
4519  saturation = v;
4520  value = p;
4521  break;
4522 
4523  case 2:
4524  hue = p;
4525  saturation = v;
4526  value = t;
4527  break;
4528 
4529  case 3:
4530  hue = p;
4531  saturation = q;
4532  value = v;
4533  break;
4534 
4535  case 4:
4536  hue = t;
4537  saturation = p;
4538  value = v;
4539  break;
4540 
4541  default: // case 5:
4542  hue = v;
4543  saturation = p;
4544  value = q;
4545  break;
4546  }
4547  }
4548 
4549  rgb[i * step] = (unsigned char)vpMath::round(hue * 255.0);
4550  rgb[i * step + 1] = (unsigned char)vpMath::round(saturation * 255.0);
4551  rgb[i * step + 2] = (unsigned char)vpMath::round(value * 255.0);
4552  if (step == 4) // alpha
4553  rgb[i * step + 3] = vpRGBa::alpha_default;
4554  }
4555 }
4556 
4557 void vpImageConvert::RGB2HSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4558  const unsigned int size, const unsigned int step)
4559 {
4560  for (unsigned int i = 0; i < size; i++) {
4561  double red, green, blue;
4562  double h, s, v;
4563  double min, max;
4564 
4565  red = rgb[i * step] / 255.0;
4566  green = rgb[i * step + 1] / 255.0;
4567  blue = rgb[i * step + 2] / 255.0;
4568 
4569  if (red > green) {
4570  max = ((std::max))(red, blue);
4571  min = ((std::min))(green, blue);
4572  } else {
4573  max = ((std::max))(green, blue);
4574  min = ((std::min))(red, blue);
4575  }
4576 
4577  v = max;
4578 
4579  if (!vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
4580  s = (max - min) / max;
4581  } else {
4582  s = 0.0;
4583  }
4584 
4585  if (vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
4586  h = 0.0;
4587  } else {
4588  double delta = max - min;
4589  if (vpMath::equal(delta, 0.0, std::numeric_limits<double>::epsilon())) {
4590  delta = 1.0;
4591  }
4592 
4593  if (vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
4594  h = (green - blue) / delta;
4595  } else if (vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
4596  h = 2 + (blue - red) / delta;
4597  } else {
4598  h = 4 + (red - green) / delta;
4599  }
4600 
4601  h /= 6.0;
4602  if (h < 0.0) {
4603  h += 1.0;
4604  } else if (h > 1.0) {
4605  h -= 1.0;
4606  }
4607  }
4608 
4609  hue[i] = h;
4610  saturation[i] = s;
4611  value[i] = v;
4612  }
4613 }
4614 
4627 void vpImageConvert::HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba,
4628  const unsigned int size)
4629 {
4630  vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
4631 }
4632 
4645 void vpImageConvert::HSVToRGBa(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4646  unsigned char *rgba, const unsigned int size)
4647 {
4648  for (unsigned int i = 0; i < size; i++) {
4649  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4650 
4651  vpImageConvert::HSVToRGBa(&h, &s, &v, (rgba + i * 4), 1);
4652  }
4653 }
4654 
4666 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value,
4667  const unsigned int size)
4668 {
4669  vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
4670 }
4671 
4683 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
4684  unsigned char *value, const unsigned int size)
4685 {
4686  for (unsigned int i = 0; i < size; i++) {
4687  double h, s, v;
4688  vpImageConvert::RGBaToHSV((rgba + i * 4), &h, &s, &v, 1);
4689 
4690  hue[i] = (unsigned char)(255.0 * h);
4691  saturation[i] = (unsigned char)(255.0 * s);
4692  value[i] = (unsigned char)(255.0 * v);
4693  }
4694 }
4695 
4705 void vpImageConvert::HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb,
4706  const unsigned int size)
4707 {
4708  vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
4709 }
4710 
4720 void vpImageConvert::HSVToRGB(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4721  unsigned char *rgb, const unsigned int size)
4722 {
4723  for (unsigned int i = 0; i < size; i++) {
4724  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4725 
4726  vpImageConvert::HSVToRGB(&h, &s, &v, (rgb + i * 3), 1);
4727  }
4728 }
4729 
4740 void vpImageConvert::RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
4741  const unsigned int size)
4742 {
4743  vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
4744 }
4745 
4756 void vpImageConvert::RGBToHSV(const unsigned char *rgb, unsigned char *hue, unsigned char *saturation,
4757  unsigned char *value, const unsigned int size)
4758 {
4759  for (unsigned int i = 0; i < size; i++) {
4760  double h, s, v;
4761 
4762  vpImageConvert::RGBToHSV((rgb + i * 3), &h, &s, &v, 1);
4763 
4764  hue[i] = (unsigned char)(255.0 * h);
4765  saturation[i] = (unsigned char)(255.0 * s);
4766  value[i] = (unsigned char)(255.0 * v);
4767  }
4768 }
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value, const unsigned int size)
unsigned char B
Blue component.
Definition: vpRGBa.h:150
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
unsigned int getRows() const
Definition: vpImage.h:207
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
Type * bitmap
points toward the bitmap
Definition: vpImage.h:133
static void MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:290
static void YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
error that can be emited by ViSP classes.
Definition: vpException.h:71
static void YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
static void YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
unsigned char G
Green component.
Definition: vpRGBa.h:149
static void GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
static int round(const double x)
Definition: vpMath.h:235
Definition: vpRGBa.h:66
static void YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
unsigned int getCols() const
Definition: vpImage.h:169
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
static void YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
static void MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:856
VISP_EXPORT bool checkSSSE3()
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 RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, const unsigned int size)
unsigned int getNumberOfPixel() const
Definition: vpImage.h:197
static void YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
unsigned int getHeight() const
Definition: vpImage.h:178
static void YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
unsigned int getSize() const
Definition: vpImage.h:215
unsigned char R
Red component.
Definition: vpRGBa.h:148
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, const unsigned int size)
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
static void YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
static void YCrCbToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb, const unsigned int size)
static void YCrCbToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
unsigned int getWidth() const
Definition: vpImage.h:229
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:974
static void YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)