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