Visual Servoing Platform version 3.5.0
vpImageConvert.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2021 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See http://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Convert image types.
33 *
34 * Authors:
35 * Eric Marchand
36 * Fabien Spindler
37 * Anthony Saunier
38 *
39 *****************************************************************************/
40
46#include <map>
47#include <sstream>
48
49#if defined _OPENMP
50#include <omp.h>
51#endif
52
53// image
54#include "private/vpBayerConversion.h"
55#include "private/vpImageConvert_impl.h"
56#include <Simd/SimdLib.hpp>
57#include <visp3/core/vpImageConvert.h>
58
59bool vpImageConvert::YCbCrLUTcomputed = false;
60int vpImageConvert::vpCrr[256];
61int vpImageConvert::vpCgb[256];
62int vpImageConvert::vpCgr[256];
63int vpImageConvert::vpCbb[256];
64
73void
75{
76 dest.resize( src.getHeight(), src.getWidth() );
77
78 GreyToRGBa( src.bitmap, reinterpret_cast< unsigned char * >( dest.bitmap ), src.getWidth(), src.getHeight() );
79}
80
90void
91vpImageConvert::convert( const vpImage< vpRGBa > &src, vpImage< unsigned char > &dest, unsigned int nThreads )
92{
93 dest.resize( src.getHeight(), src.getWidth() );
94
95 RGBaToGrey( reinterpret_cast< unsigned char * >( src.bitmap ), dest.bitmap, src.getWidth(), src.getHeight(),
96 nThreads );
97}
98
105void
107{
108 dest.resize( src.getHeight(), src.getWidth() );
109 unsigned int max_xy = src.getWidth() * src.getHeight();
110 float min, max;
111
112 src.getMinMaxValue( min, max );
113
114 for ( unsigned int i = 0; i < max_xy; i++ )
115 {
116 float val = 255.f * ( src.bitmap[i] - min ) / ( max - min );
117 if ( val < 0 )
118 dest.bitmap[i] = 0;
119 else if ( val > 255 )
120 dest.bitmap[i] = 255;
121 else
122 dest.bitmap[i] = (unsigned char)val;
123 }
124}
125
131void
133{
134 dest.resize( src.getHeight(), src.getWidth() );
135 for ( unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++ )
136 dest.bitmap[i] = (float)src.bitmap[i];
137}
138
145void
147{
148 dest.resize( src.getHeight(), src.getWidth() );
149 unsigned int max_xy = src.getWidth() * src.getHeight();
150 double min, max;
151
152 src.getMinMaxValue( min, max );
153
154 for ( unsigned int i = 0; i < max_xy; i++ )
155 {
156 double val = 255. * ( src.bitmap[i] - min ) / ( max - min );
157 if ( val < 0 )
158 dest.bitmap[i] = 0;
159 else if ( val > 255 )
160 dest.bitmap[i] = 255;
161 else
162 dest.bitmap[i] = (unsigned char)val;
163 }
164}
165
172void
173vpImageConvert::convert( const vpImage< uint16_t > &src, vpImage< unsigned char > &dest, unsigned char bitshift )
174{
175 dest.resize( src.getHeight(), src.getWidth() );
176
177 for ( unsigned int i = 0; i < src.getSize(); i++ )
178 dest.bitmap[i] = static_cast< unsigned char >( src.bitmap[i] >> bitshift );
179}
180
187void
188vpImageConvert::convert( const vpImage< unsigned char > &src, vpImage< uint16_t > &dest, unsigned char bitshift )
189{
190 dest.resize( src.getHeight(), src.getWidth() );
191
192 for ( unsigned int i = 0; i < src.getSize(); i++ )
193 dest.bitmap[i] = static_cast< unsigned char >( src.bitmap[i] << bitshift );
194}
195
201void
203{
204 dest.resize( src.getHeight(), src.getWidth() );
205 for ( unsigned int i = 0; i < src.getHeight() * src.getWidth(); i++ )
206 dest.bitmap[i] = (double)src.bitmap[i];
207}
208
216void
218{
219 vp_createDepthHistogram(src_depth, dest_rgba);
220}
221
228void
230{
231 vp_createDepthHistogram(src_depth, dest_depth);
232}
233
241void
243{
244 vp_createDepthHistogram(src_depth, dest_rgba);
245}
246
253void
255{
256 vp_createDepthHistogram(src_depth, dest_depth);
257}
258
259
260#ifdef VISP_HAVE_OPENCV
261// Deprecated: will be removed with OpenCV transcient from C to C++ api
307void
308vpImageConvert::convert( const IplImage *src, vpImage< vpRGBa > &dest, bool flip )
309{
310 int nChannel = src->nChannels;
311 int depth = src->depth;
312 int height = src->height;
313 int width = src->width;
314 int widthStep = src->widthStep;
315 int lineStep = ( flip ) ? 1 : 0;
316
317 if ( nChannel == 3 && depth == 8 )
318 {
319 dest.resize( (unsigned int)height, (unsigned int)width );
320
321 // starting source address
322 unsigned char *input = (unsigned char *)src->imageData;
323 unsigned char *beginOutput = (unsigned char *)dest.bitmap;
324
325 for ( int i = 0; i < height; i++ )
326 {
327 unsigned char *line = input;
328 unsigned char *output =
329 beginOutput + lineStep * ( 4 * width * ( height - 1 - i ) ) + ( 1 - lineStep ) * 4 * width * i;
330 for ( int j = 0; j < width; j++ )
331 {
332 *( output++ ) = *( line + 2 );
333 *( output++ ) = *( line + 1 );
334 *( output++ ) = *( line );
335 *( output++ ) = vpRGBa::alpha_default;
336
337 line += 3;
338 }
339 // go to the next line
340 input += widthStep;
341 }
342 }
343 else if ( nChannel == 1 && depth == 8 )
344 {
345 dest.resize( (unsigned int)height, (unsigned int)width );
346 // starting source address
347 unsigned char *input = (unsigned char *)src->imageData;
348 unsigned char *beginOutput = (unsigned char *)dest.bitmap;
349
350 for ( int i = 0; i < height; i++ )
351 {
352 unsigned char *line = input;
353 unsigned char *output =
354 beginOutput + lineStep * ( 4 * width * ( height - 1 - i ) ) + ( 1 - lineStep ) * 4 * width * i;
355 for ( int j = 0; j < width; j++ )
356 {
357 *output++ = *( line );
358 *output++ = *( line );
359 *output++ = *( line );
360 *output++ = vpRGBa::alpha_default; // alpha
361
362 line++;
363 }
364 // go to the next line
365 input += widthStep;
366 }
367 }
368}
369
412void
413vpImageConvert::convert( const IplImage *src, vpImage< unsigned char > &dest, bool flip )
414{
415 int nChannel = src->nChannels;
416 int depth = src->depth;
417 int height = src->height;
418 int width = src->width;
419 int widthStep = src->widthStep;
420 int lineStep = ( flip ) ? 1 : 0;
421
422 if ( flip == false )
423 {
424 if ( widthStep == width )
425 {
426 if ( nChannel == 1 && depth == 8 )
427 {
428 dest.resize( (unsigned int)height, (unsigned int)width );
429 memcpy( dest.bitmap, src->imageData, ( size_t )( height * width ) );
430 }
431 if ( nChannel == 3 && depth == 8 )
432 {
433 dest.resize( (unsigned int)height, (unsigned int)width );
434 BGRToGrey( (unsigned char *)src->imageData, dest.bitmap, (unsigned int)width, (unsigned int)height, false );
435 }
436 }
437 else
438 {
439 if ( nChannel == 1 && depth == 8 )
440 {
441 dest.resize( (unsigned int)height, (unsigned int)width );
442 for ( int i = 0; i < height; i++ )
443 {
444 memcpy( dest.bitmap + i * width, src->imageData + i * widthStep, (size_t)width );
445 }
446 }
447 if ( nChannel == 3 && depth == 8 )
448 {
449 dest.resize( (unsigned int)height, (unsigned int)width );
450 for ( int i = 0; i < height; i++ )
451 {
452 BGRToGrey( (unsigned char *)src->imageData + i * widthStep, dest.bitmap + i * width, (unsigned int)width, 1,
453 false );
454 }
455 }
456 }
457 }
458 else
459 {
460 if ( nChannel == 1 && depth == 8 )
461 {
462 dest.resize( (unsigned int)height, (unsigned int)width );
463 unsigned char *beginOutput = (unsigned char *)dest.bitmap;
464 for ( int i = 0; i < height; i++ )
465 {
466 memcpy( beginOutput + lineStep * ( 4 * width * ( height - 1 - i ) ), src->imageData + i * widthStep,
467 (size_t)width );
468 }
469 }
470 if ( nChannel == 3 && depth == 8 )
471 {
472 dest.resize( (unsigned int)height, (unsigned int)width );
473 // for (int i = 0 ; i < height ; i++){
474 BGRToGrey( (unsigned char *)src->imageData /*+ i*widthStep*/, dest.bitmap /*+ i*width*/, (unsigned int)width,
475 (unsigned int)height /*1*/, true );
476 //}
477 }
478 }
479}
480
524void
525vpImageConvert::convert( const vpImage< vpRGBa > &src, IplImage *&dest )
526{
527 int height = (int)src.getHeight();
528 int width = (int)src.getWidth();
529 CvSize size = cvSize( width, height );
530 int depth = 8;
531 int channels = 3;
532 if ( dest != NULL )
533 {
534 if ( dest->nChannels != channels || dest->depth != depth || dest->height != height || dest->width != width )
535 {
536 if ( dest->nChannels != 0 )
537 cvReleaseImage( &dest );
538 dest = cvCreateImage( size, depth, channels );
539 }
540 }
541 else
542 dest = cvCreateImage( size, depth, channels );
543
544 // starting source address
545 unsigned char *input = (unsigned char *)src.bitmap; // rgba image
546 unsigned char *output = (unsigned char *)dest->imageData; // bgr image
547
548 int j = 0;
549 int i = 0;
550 int widthStep = dest->widthStep;
551
552 for ( i = 0; i < height; i++ )
553 {
554 output = (unsigned char *)dest->imageData + i * widthStep;
555 unsigned char *line = input;
556 for ( j = 0; j < width; j++ )
557 {
558 *output++ = *( line + 2 ); // B
559 *output++ = *( line + 1 ); // G
560 *output++ = *( line ); // R
561
562 line += 4;
563 }
564 // go to the next line
565 input += 4 * width;
566 }
567}
568
612void
614{
615 unsigned int height = src.getHeight();
616 unsigned int width = src.getWidth();
617 CvSize size = cvSize( (int)width, (int)height );
618 int depth = 8;
619 int channels = 1;
620 if ( dest != NULL )
621 {
622 if ( dest->nChannels != channels || dest->depth != depth || dest->height != (int)height ||
623 dest->width != (int)width )
624 {
625 if ( dest->nChannels != 0 )
626 cvReleaseImage( &dest );
627 dest = cvCreateImage( size, depth, channels );
628 }
629 }
630 else
631 dest = cvCreateImage( size, depth, channels );
632
633 unsigned int widthStep = (unsigned int)dest->widthStep;
634
635 if ( width == widthStep )
636 {
637 memcpy( dest->imageData, src.bitmap, width * height );
638 }
639 else
640 {
641 // copying each line taking account of the widthStep
642 for ( unsigned int i = 0; i < height; i++ )
643 {
644 memcpy( dest->imageData + i * widthStep, src.bitmap + i * width, width );
645 }
646 }
647}
648
649#if VISP_HAVE_OPENCV_VERSION >= 0x020100
697void
698vpImageConvert::convert( const cv::Mat &src, vpImage< vpRGBa > &dest, bool flip )
699{
700 dest.resize( (unsigned int)src.rows, (unsigned int)src.cols );
701
702 if ( src.type() == CV_8UC4 )
703 {
704 vpRGBa rgbaVal;
705 for ( unsigned int i = 0; i < dest.getRows(); ++i )
706 for ( unsigned int j = 0; j < dest.getCols(); ++j )
707 {
708 cv::Vec4b tmp = src.at< cv::Vec4b >( (int)i, (int)j );
709 rgbaVal.R = tmp[2];
710 rgbaVal.G = tmp[1];
711 rgbaVal.B = tmp[0];
712 rgbaVal.A = tmp[3];
713 if ( flip )
714 dest[dest.getRows() - i - 1][j] = rgbaVal;
715 else
716 dest[i][j] = rgbaVal;
717 }
718 }
719 else if ( src.type() == CV_8UC3 )
720 {
721 if ( src.isContinuous() && !flip )
722 {
723 SimdRgbToBgra( src.data, src.cols, src.rows, src.step[0], reinterpret_cast< uint8_t * >( dest.bitmap ),
724 dest.getWidth() * sizeof( vpRGBa ), vpRGBa::alpha_default );
725 }
726 else
727 {
728 vpRGBa rgbaVal;
729 rgbaVal.A = vpRGBa::alpha_default;
730 for ( unsigned int i = 0; i < dest.getRows(); ++i )
731 {
732 for ( unsigned int j = 0; j < dest.getCols(); ++j )
733 {
734 cv::Vec3b tmp = src.at< cv::Vec3b >( (int)i, (int)j );
735 rgbaVal.R = tmp[2];
736 rgbaVal.G = tmp[1];
737 rgbaVal.B = tmp[0];
738 if ( flip )
739 {
740 dest[dest.getRows() - i - 1][j] = rgbaVal;
741 }
742 else
743 {
744 dest[i][j] = rgbaVal;
745 }
746 }
747 }
748 }
749 }
750 else if ( src.type() == CV_8UC1 )
751 {
752 if ( src.isContinuous() && !flip )
753 {
754 SimdGrayToBgra( src.data, src.cols, src.rows, src.step[0], reinterpret_cast< uint8_t * >( dest.bitmap ),
755 dest.getWidth() * sizeof( vpRGBa ), vpRGBa::alpha_default );
756 }
757 else
758 {
759 vpRGBa rgbaVal;
760 for ( unsigned int i = 0; i < dest.getRows(); ++i )
761 {
762 for ( unsigned int j = 0; j < dest.getCols(); ++j )
763 {
764 rgbaVal = src.at< unsigned char >( (int)i, (int)j );
765 if ( flip )
766 {
767 dest[dest.getRows() - i - 1][j] = rgbaVal;
768 }
769 else
770 {
771 dest[i][j] = rgbaVal;
772 }
773 }
774 }
775 }
776 }
777}
778
821void
822vpImageConvert::convert( const cv::Mat &src, vpImage< unsigned char > &dest, bool flip, unsigned int nThreads )
823{
824 if ( src.type() == CV_8UC1 )
825 {
826 dest.resize( (unsigned int)src.rows, (unsigned int)src.cols );
827 if ( src.isContinuous() && !flip )
828 {
829 memcpy( dest.bitmap, src.data, ( size_t )( src.rows * src.cols ) );
830 }
831 else
832 {
833 if ( flip )
834 {
835 for ( unsigned int i = 0; i < dest.getRows(); ++i )
836 {
837 memcpy( dest.bitmap + i * dest.getCols(), src.data + ( dest.getRows() - i - 1 ) * src.step1(),
838 (size_t)src.step );
839 }
840 }
841 else
842 {
843 for ( unsigned int i = 0; i < dest.getRows(); ++i )
844 {
845 memcpy( dest.bitmap + i * dest.getCols(), src.data + i * src.step1(), (size_t)src.step );
846 }
847 }
848 }
849 }
850 else if ( src.type() == CV_8UC3 )
851 {
852 dest.resize( (unsigned int)src.rows, (unsigned int)src.cols );
853 if ( src.isContinuous() )
854 {
855 BGRToGrey( (unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols,
856 (unsigned int)src.rows, flip, nThreads );
857 }
858 else
859 {
860 if ( flip )
861 {
862 for ( unsigned int i = 0; i < dest.getRows(); ++i )
863 {
864 BGRToGrey( (unsigned char *)src.data + i * src.step1(),
865 (unsigned char *)dest.bitmap + ( dest.getRows() - i - 1 ) * dest.getCols(),
866 (unsigned int)dest.getCols(), 1, false );
867 }
868 }
869 else
870 {
871 for ( unsigned int i = 0; i < dest.getRows(); ++i )
872 {
873 BGRToGrey( (unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
874 (unsigned int)dest.getCols(), 1, false );
875 }
876 }
877 }
878 }
879 else if ( src.type() == CV_8UC4 )
880 {
881 dest.resize( (unsigned int)src.rows, (unsigned int)src.cols );
882 if ( src.isContinuous() )
883 {
884 BGRaToGrey( (unsigned char *)src.data, (unsigned char *)dest.bitmap, (unsigned int)src.cols,
885 (unsigned int)src.rows, flip, nThreads );
886 }
887 else
888 {
889 if ( flip )
890 {
891 for ( unsigned int i = 0; i < dest.getRows(); ++i )
892 {
893 BGRaToGrey( (unsigned char *)src.data + i * src.step1(),
894 (unsigned char *)dest.bitmap + ( dest.getRows() - i - 1 ) * dest.getCols(),
895 (unsigned int)dest.getCols(), 1, false );
896 }
897 }
898 else
899 {
900 for ( unsigned int i = 0; i < dest.getRows(); ++i )
901 {
902 BGRaToGrey( (unsigned char *)src.data + i * src.step1(), (unsigned char *)dest.bitmap + i * dest.getCols(),
903 (unsigned int)dest.getCols(), 1, false );
904 }
905 }
906 }
907 }
908}
909
946void
947vpImageConvert::convert( const vpImage< vpRGBa > &src, cv::Mat &dest )
948{
949 cv::Mat vpToMat( (int)src.getRows(), (int)src.getCols(), CV_8UC4, (void *)src.bitmap );
950 cv::cvtColor( vpToMat, dest, cv::COLOR_RGBA2BGR );
951}
952
991void
992vpImageConvert::convert( const vpImage< unsigned char > &src, cv::Mat &dest, bool copyData )
993{
994 if ( copyData )
995 {
996 cv::Mat tmpMap( (int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap );
997 dest = tmpMap.clone();
998 }
999 else
1000 {
1001 dest = cv::Mat( (int)src.getRows(), (int)src.getCols(), CV_8UC1, (void *)src.bitmap );
1002 }
1003}
1004
1005#endif
1006#endif
1007
1008#ifdef VISP_HAVE_YARP
1042void
1043vpImageConvert::convert( const vpImage< unsigned char > &src, yarp::sig::ImageOf< yarp::sig::PixelMono > *dest,
1044 bool copyData )
1045{
1046 if ( copyData )
1047 {
1048 dest->resize( src.getWidth(), src.getHeight() );
1049 memcpy( dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() );
1050 }
1051 else
1052 dest->setExternal( src.bitmap, (int)src.getCols(), (int)src.getRows() );
1053}
1054
1093void
1094vpImageConvert::convert( const yarp::sig::ImageOf< yarp::sig::PixelMono > *src, vpImage< unsigned char > &dest,
1095 bool copyData )
1096{
1097 dest.resize( src->height(), src->width() );
1098 if ( copyData )
1099 memcpy( dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof( yarp::sig::PixelMono ) );
1100 else
1101 dest.bitmap = src->getRawImage();
1102}
1103
1138void
1139vpImageConvert::convert( const vpImage< vpRGBa > &src, yarp::sig::ImageOf< yarp::sig::PixelRgba > *dest, bool copyData )
1140{
1141 if ( copyData )
1142 {
1143 dest->resize( src.getWidth(), src.getHeight() );
1144 memcpy( dest->getRawImage(), src.bitmap, src.getHeight() * src.getWidth() * sizeof( vpRGBa ) );
1145 }
1146 else
1147 dest->setExternal( src.bitmap, (int)src.getCols(), (int)src.getRows() );
1148}
1149
1188void
1189vpImageConvert::convert( const yarp::sig::ImageOf< yarp::sig::PixelRgba > *src, vpImage< vpRGBa > &dest, bool copyData )
1190{
1191 dest.resize( src->height(), src->width() );
1192 if ( copyData )
1193 memcpy( dest.bitmap, src->getRawImage(), src->height() * src->width() * sizeof( yarp::sig::PixelRgba ) );
1194 else
1195 dest.bitmap = static_cast< vpRGBa * >( src->getRawImage() );
1196}
1197
1230void
1231vpImageConvert::convert( const vpImage< vpRGBa > &src, yarp::sig::ImageOf< yarp::sig::PixelRgb > *dest )
1232{
1233 dest->resize( src.getWidth(), src.getHeight() );
1234 for ( unsigned int i = 0; i < src.getRows(); i++ )
1235 {
1236 for ( unsigned int j = 0; j < src.getWidth(); j++ )
1237 {
1238 dest->pixel( j, i ).r = src[i][j].R;
1239 dest->pixel( j, i ).g = src[i][j].G;
1240 dest->pixel( j, i ).b = src[i][j].B;
1241 }
1242 }
1243}
1244
1283void
1284vpImageConvert::convert( const yarp::sig::ImageOf< yarp::sig::PixelRgb > *src, vpImage< vpRGBa > &dest )
1285{
1286 dest.resize( src->height(), src->width() );
1287 for ( int i = 0; i < src->height(); i++ )
1288 {
1289 for ( int j = 0; j < src->width(); j++ )
1290 {
1291 dest[i][j].R = src->pixel( j, i ).r;
1292 dest[i][j].G = src->pixel( j, i ).g;
1293 dest[i][j].B = src->pixel( j, i ).b;
1294 dest[i][j].A = vpRGBa::alpha_default;
1295 }
1296 }
1297}
1298
1299#endif
1300
1301#define vpSAT( c ) \
1302 if ( c & ( ~255 ) ) \
1303 { \
1304 if ( c < 0 ) \
1305 c = 0; \
1306 else \
1307 c = 255; \
1308 }
1321void
1322vpImageConvert::YUYVToRGBa( unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height )
1323{
1324 unsigned char *s;
1325 unsigned char *d;
1326 int w, h;
1327 int r, g, b, cr, cg, cb, y1, y2;
1328
1329 h = (int)height;
1330 w = (int)width;
1331 s = yuyv;
1332 d = rgba;
1333 while ( h-- )
1334 {
1335 int c = w >> 1;
1336 while ( c-- )
1337 {
1338 y1 = *s++;
1339 cb = ( ( *s - 128 ) * 454 ) >> 8;
1340 cg = ( *s++ - 128 ) * 88;
1341 y2 = *s++;
1342 cr = ( ( *s - 128 ) * 359 ) >> 8;
1343 cg = ( cg + ( *s++ - 128 ) * 183 ) >> 8;
1344
1345 r = y1 + cr;
1346 b = y1 + cb;
1347 g = y1 - cg;
1348 vpSAT( r ) vpSAT( g ) vpSAT( b )
1349
1350 *d++ = static_cast< unsigned char >( r );
1351 *d++ = static_cast< unsigned char >( g );
1352 *d++ = static_cast< unsigned char >( b );
1353 *d++ = vpRGBa::alpha_default;
1354
1355 r = y2 + cr;
1356 b = y2 + cb;
1357 g = y2 - cg;
1358 vpSAT( r ) vpSAT( g ) vpSAT( b )
1359
1360 *d++ = static_cast< unsigned char >( r );
1361 *d++ = static_cast< unsigned char >( g );
1362 *d++ = static_cast< unsigned char >( b );
1363 *d++ = vpRGBa::alpha_default;
1364 }
1365 }
1366}
1367
1378void
1379vpImageConvert::YUYVToRGB( unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height )
1380{
1381 unsigned char *s;
1382 unsigned char *d;
1383 int h, w;
1384 int r, g, b, cr, cg, cb, y1, y2;
1385
1386 h = (int)height;
1387 w = (int)width;
1388 s = yuyv;
1389 d = rgb;
1390 while ( h-- )
1391 {
1392 int c = w >> 1;
1393 while ( c-- )
1394 {
1395 y1 = *s++;
1396 cb = ( ( *s - 128 ) * 454 ) >> 8;
1397 cg = ( *s++ - 128 ) * 88;
1398 y2 = *s++;
1399 cr = ( ( *s - 128 ) * 359 ) >> 8;
1400 cg = ( cg + ( *s++ - 128 ) * 183 ) >> 8;
1401
1402 r = y1 + cr;
1403 b = y1 + cb;
1404 g = y1 - cg;
1405 vpSAT( r ) vpSAT( g ) vpSAT( b )
1406
1407 *d++ = static_cast< unsigned char >( r );
1408 *d++ = static_cast< unsigned char >( g );
1409 *d++ = static_cast< unsigned char >( b );
1410
1411 r = y2 + cr;
1412 b = y2 + cb;
1413 g = y2 - cg;
1414 vpSAT( r ) vpSAT( g ) vpSAT( b )
1415
1416 *d++ = static_cast< unsigned char >( r );
1417 *d++ = static_cast< unsigned char >( g );
1418 *d++ = static_cast< unsigned char >( b );
1419 }
1420 }
1421}
1422
1433void
1434vpImageConvert::YUYVToGrey( unsigned char *yuyv, unsigned char *grey, unsigned int size )
1435{
1436 unsigned int i = 0, j = 0;
1437
1438 while ( j < size * 2 )
1439 {
1440 grey[i++] = yuyv[j];
1441 grey[i++] = yuyv[j + 2];
1442 j += 4;
1443 }
1444}
1445
1455void
1456vpImageConvert::YUV411ToRGBa( unsigned char *yuv, unsigned char *rgba, unsigned int size )
1457{
1458#if 1
1459 // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1460 for ( unsigned int i = size / 4; i; i-- )
1461 {
1462 int U = (int)( ( *yuv++ - 128 ) * 0.354 );
1463 int U5 = 5 * U;
1464 int Y0 = *yuv++;
1465 int Y1 = *yuv++;
1466 int V = (int)( ( *yuv++ - 128 ) * 0.707 );
1467 int V2 = 2 * V;
1468 int Y2 = *yuv++;
1469 int Y3 = *yuv++;
1470 int UV = -U - V;
1471
1472 // Original equations
1473 // R = Y + 1.402 V
1474 // G = Y - 0.344 U - 0.714 V
1475 // B = Y + 1.772 U
1476 int R = Y0 + V2;
1477 if ( ( R >> 8 ) > 0 )
1478 R = 255;
1479 else if ( R < 0 )
1480 R = 0;
1481
1482 int G = Y0 + UV;
1483 if ( ( G >> 8 ) > 0 )
1484 G = 255;
1485 else if ( G < 0 )
1486 G = 0;
1487
1488 int B = Y0 + U5;
1489 if ( ( B >> 8 ) > 0 )
1490 B = 255;
1491 else if ( B < 0 )
1492 B = 0;
1493
1494 *rgba++ = (unsigned char)R;
1495 *rgba++ = (unsigned char)G;
1496 *rgba++ = (unsigned char)B;
1497 *rgba++ = vpRGBa::alpha_default;
1498
1499 //---
1500 R = Y1 + V2;
1501 if ( ( R >> 8 ) > 0 )
1502 R = 255;
1503 else if ( R < 0 )
1504 R = 0;
1505
1506 G = Y1 + UV;
1507 if ( ( G >> 8 ) > 0 )
1508 G = 255;
1509 else if ( G < 0 )
1510 G = 0;
1511
1512 B = Y1 + U5;
1513 if ( ( B >> 8 ) > 0 )
1514 B = 255;
1515 else if ( B < 0 )
1516 B = 0;
1517
1518 *rgba++ = (unsigned char)R;
1519 *rgba++ = (unsigned char)G;
1520 *rgba++ = (unsigned char)B;
1521 *rgba++ = vpRGBa::alpha_default;
1522
1523 //---
1524 R = Y2 + V2;
1525 if ( ( R >> 8 ) > 0 )
1526 R = 255;
1527 else if ( R < 0 )
1528 R = 0;
1529
1530 G = Y2 + UV;
1531 if ( ( G >> 8 ) > 0 )
1532 G = 255;
1533 else if ( G < 0 )
1534 G = 0;
1535
1536 B = Y2 + U5;
1537 if ( ( B >> 8 ) > 0 )
1538 B = 255;
1539 else if ( B < 0 )
1540 B = 0;
1541
1542 *rgba++ = (unsigned char)R;
1543 *rgba++ = (unsigned char)G;
1544 *rgba++ = (unsigned char)B;
1545 *rgba++ = vpRGBa::alpha_default;
1546
1547 //---
1548 R = Y3 + V2;
1549 if ( ( R >> 8 ) > 0 )
1550 R = 255;
1551 else if ( R < 0 )
1552 R = 0;
1553
1554 G = Y3 + UV;
1555 if ( ( G >> 8 ) > 0 )
1556 G = 255;
1557 else if ( G < 0 )
1558 G = 0;
1559
1560 B = Y3 + U5;
1561 if ( ( B >> 8 ) > 0 )
1562 B = 255;
1563 else if ( B < 0 )
1564 B = 0;
1565
1566 *rgba++ = (unsigned char)R;
1567 *rgba++ = (unsigned char)G;
1568 *rgba++ = (unsigned char)B;
1569 *rgba++ = vpRGBa::alpha_default;
1570 }
1571#else
1572 // tres tres lent ....
1573 unsigned int i = 0, j = 0;
1574 unsigned char r, g, b;
1575 while ( j < numpixels * 3 / 2 )
1576 {
1577
1578 YUVToRGB( yuv[j + 1], yuv[j], yuv[j + 3], r, g, b );
1579 rgba[i] = r;
1580 rgba[i + 1] = g;
1581 rgba[i + 2] = b;
1582 rgba[i + 3] = vpRGBa::alpha_default;
1583 i += 4;
1584
1585 YUVToRGB( yuv[j + 2], yuv[j], yuv[j + 3], r, g, b );
1586 rgba[i] = r;
1587 rgba[i + 1] = g;
1588 rgba[i + 2] = b;
1589 rgba[i + 3] = vpRGBa::alpha_default;
1590 i += 4;
1591
1592 YUVToRGB( yuv[j + 4], yuv[j], yuv[j + 3], r, g, b );
1593 rgba[i] = r;
1594 rgba[i + 1] = g;
1595 rgba[i + 2] = b;
1596 rgba[i + 3] = vpRGBa::alpha_default;
1597 i += 4;
1598
1599 YUVToRGB( yuv[j + 5], yuv[j], yuv[j + 3], r, g, b );
1600 rgba[i] = r;
1601 rgba[i + 1] = g;
1602 rgba[i + 2] = b;
1603 rgba[i + 3] = vpRGBa::alpha_default;
1604 i += 4;
1605
1606 j += 6;
1607 }
1608#endif
1609}
1610
1623void
1624vpImageConvert::YUV422ToRGBa( unsigned char *yuv, unsigned char *rgba, unsigned int size )
1625{
1626
1627#if 1
1628 // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1629 for ( unsigned int i = size / 2; i; i-- )
1630 {
1631 int U = (int)( ( *yuv++ - 128 ) * 0.354 );
1632 int U5 = 5 * U;
1633 int Y0 = *yuv++;
1634 int V = (int)( ( *yuv++ - 128 ) * 0.707 );
1635 int V2 = 2 * V;
1636 int Y1 = *yuv++;
1637 int UV = -U - V;
1638
1639 //---
1640 int R = Y0 + V2;
1641 if ( ( R >> 8 ) > 0 )
1642 R = 255;
1643 else if ( R < 0 )
1644 R = 0;
1645
1646 int G = Y0 + UV;
1647 if ( ( G >> 8 ) > 0 )
1648 G = 255;
1649 else if ( G < 0 )
1650 G = 0;
1651
1652 int B = Y0 + U5;
1653 if ( ( B >> 8 ) > 0 )
1654 B = 255;
1655 else if ( B < 0 )
1656 B = 0;
1657
1658 *rgba++ = (unsigned char)R;
1659 *rgba++ = (unsigned char)G;
1660 *rgba++ = (unsigned char)B;
1661 *rgba++ = vpRGBa::alpha_default;
1662
1663 //---
1664 R = Y1 + V2;
1665 if ( ( R >> 8 ) > 0 )
1666 R = 255;
1667 else if ( R < 0 )
1668 R = 0;
1669
1670 G = Y1 + UV;
1671 if ( ( G >> 8 ) > 0 )
1672 G = 255;
1673 else if ( G < 0 )
1674 G = 0;
1675
1676 B = Y1 + U5;
1677 if ( ( B >> 8 ) > 0 )
1678 B = 255;
1679 else if ( B < 0 )
1680 B = 0;
1681
1682 *rgba++ = (unsigned char)R;
1683 *rgba++ = (unsigned char)G;
1684 *rgba++ = (unsigned char)B;
1685 *rgba++ = vpRGBa::alpha_default;
1686 }
1687
1688#else
1689 // tres tres lent ....
1690 unsigned int i = 0, j = 0;
1691 unsigned char r, g, b;
1692
1693 while ( j < size * 2 )
1694 {
1695
1696 YUVToRGB( yuv[j + 1], yuv[j], yuv[j + 2], r, g, b );
1697 rgba[i] = r;
1698 rgba[i + 1] = g;
1699 rgba[i + 2] = b;
1700 rgba[i + 3] = vpRGBa::alpha_default;
1701 i += 4;
1702
1703 YUVToRGB( yuv[j + 3], yuv[j], yuv[j + 2], r, g, b );
1704 rgba[i] = r;
1705 rgba[i + 1] = g;
1706 rgba[i + 2] = b;
1707 rgba[i + 3] = vpRGBa::alpha_default;
1708 i += 4;
1709 j += 4;
1710 }
1711#endif
1712}
1713
1722void
1723vpImageConvert::YUV411ToGrey( unsigned char *yuv, unsigned char *grey, unsigned int size )
1724{
1725 unsigned int i = 0, j = 0;
1726 while ( j < size * 3 / 2 )
1727 {
1728 grey[i] = yuv[j + 1];
1729 grey[i + 1] = yuv[j + 2];
1730 grey[i + 2] = yuv[j + 4];
1731 grey[i + 3] = yuv[j + 5];
1732
1733 i += 4;
1734
1735 j += 6;
1736 }
1737}
1738
1749void
1750vpImageConvert::YUV422ToRGB( unsigned char *yuv, unsigned char *rgb, unsigned int size )
1751{
1752#if 1
1753 // std::cout << "call optimized convertYUV422ToRGB()" << std::endl;
1754 for ( unsigned int i = size / 2; i; i-- )
1755 {
1756 int U = (int)( ( *yuv++ - 128 ) * 0.354 );
1757 int U5 = 5 * U;
1758 int Y0 = *yuv++;
1759 int V = (int)( ( *yuv++ - 128 ) * 0.707 );
1760 int V2 = 2 * V;
1761 int Y1 = *yuv++;
1762 int UV = -U - V;
1763
1764 //---
1765 int R = Y0 + V2;
1766 if ( ( R >> 8 ) > 0 )
1767 R = 255;
1768 else if ( R < 0 )
1769 R = 0;
1770
1771 int G = Y0 + UV;
1772 if ( ( G >> 8 ) > 0 )
1773 G = 255;
1774 else if ( G < 0 )
1775 G = 0;
1776
1777 int B = Y0 + U5;
1778 if ( ( B >> 8 ) > 0 )
1779 B = 255;
1780 else if ( B < 0 )
1781 B = 0;
1782
1783 *rgb++ = (unsigned char)R;
1784 *rgb++ = (unsigned char)G;
1785 *rgb++ = (unsigned char)B;
1786
1787 //---
1788 R = Y1 + V2;
1789 if ( ( R >> 8 ) > 0 )
1790 R = 255;
1791 else if ( R < 0 )
1792 R = 0;
1793
1794 G = Y1 + UV;
1795 if ( ( G >> 8 ) > 0 )
1796 G = 255;
1797 else if ( G < 0 )
1798 G = 0;
1799
1800 B = Y1 + U5;
1801 if ( ( B >> 8 ) > 0 )
1802 B = 255;
1803 else if ( B < 0 )
1804 B = 0;
1805
1806 *rgb++ = (unsigned char)R;
1807 *rgb++ = (unsigned char)G;
1808 *rgb++ = (unsigned char)B;
1809 }
1810
1811#else
1812 // tres tres lent ....
1813 unsigned int i = 0, j = 0;
1814 unsigned char r, g, b;
1815
1816 while ( j < size * 2 )
1817 {
1818
1819 YUVToRGB( yuv[j + 1], yuv[j], yuv[j + 2], r, g, b );
1820 rgb[i] = r;
1821 rgb[i + 1] = g;
1822 rgb[i + 2] = b;
1823 i += 3;
1824
1825 YUVToRGB( yuv[j + 3], yuv[j], yuv[j + 2], r, g, b );
1826 rgb[i] = r;
1827 rgb[i + 1] = g;
1828 rgb[i + 2] = b;
1829 i += 3;
1830 j += 4;
1831 }
1832#endif
1833}
1834
1845void
1846vpImageConvert::YUV422ToGrey( unsigned char *yuv, unsigned char *grey, unsigned int size )
1847{
1848 unsigned int i = 0, j = 0;
1849
1850 while ( j < size * 2 )
1851 {
1852 grey[i++] = yuv[j + 1];
1853 grey[i++] = yuv[j + 3];
1854 j += 4;
1855 }
1856}
1857
1866void
1867vpImageConvert::YUV411ToRGB( unsigned char *yuv, unsigned char *rgb, unsigned int size )
1868{
1869#if 1
1870 // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1871 for ( unsigned int i = size / 4; i; i-- )
1872 {
1873 int U = (int)( ( *yuv++ - 128 ) * 0.354 );
1874 int U5 = 5 * U;
1875 int Y0 = *yuv++;
1876 int Y1 = *yuv++;
1877 int V = (int)( ( *yuv++ - 128 ) * 0.707 );
1878 int V2 = 2 * V;
1879 int Y2 = *yuv++;
1880 int Y3 = *yuv++;
1881 int UV = -U - V;
1882
1883 // Original equations
1884 // R = Y + 1.402 V
1885 // G = Y - 0.344 U - 0.714 V
1886 // B = Y + 1.772 U
1887 int R = Y0 + V2;
1888 if ( ( R >> 8 ) > 0 )
1889 R = 255;
1890 else if ( R < 0 )
1891 R = 0;
1892
1893 int G = Y0 + UV;
1894 if ( ( G >> 8 ) > 0 )
1895 G = 255;
1896 else if ( G < 0 )
1897 G = 0;
1898
1899 int B = Y0 + U5;
1900 if ( ( B >> 8 ) > 0 )
1901 B = 255;
1902 else if ( B < 0 )
1903 B = 0;
1904
1905 *rgb++ = (unsigned char)R;
1906 *rgb++ = (unsigned char)G;
1907 *rgb++ = (unsigned char)B;
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 *rgb++ = (unsigned char)R;
1929 *rgb++ = (unsigned char)G;
1930 *rgb++ = (unsigned char)B;
1931
1932 //---
1933 R = Y2 + V2;
1934 if ( ( R >> 8 ) > 0 )
1935 R = 255;
1936 else if ( R < 0 )
1937 R = 0;
1938
1939 G = Y2 + UV;
1940 if ( ( G >> 8 ) > 0 )
1941 G = 255;
1942 else if ( G < 0 )
1943 G = 0;
1944
1945 B = Y2 + U5;
1946 if ( ( B >> 8 ) > 0 )
1947 B = 255;
1948 else if ( B < 0 )
1949 B = 0;
1950
1951 *rgb++ = (unsigned char)R;
1952 *rgb++ = (unsigned char)G;
1953 *rgb++ = (unsigned char)B;
1954
1955 //---
1956 R = Y3 + V2;
1957 if ( ( R >> 8 ) > 0 )
1958 R = 255;
1959 else if ( R < 0 )
1960 R = 0;
1961
1962 G = Y3 + UV;
1963 if ( ( G >> 8 ) > 0 )
1964 G = 255;
1965 else if ( G < 0 )
1966 G = 0;
1967
1968 B = Y3 + U5;
1969 if ( ( B >> 8 ) > 0 )
1970 B = 255;
1971 else if ( B < 0 )
1972 B = 0;
1973
1974 *rgb++ = (unsigned char)R;
1975 *rgb++ = (unsigned char)G;
1976 *rgb++ = (unsigned char)B;
1977 }
1978#else
1979 // tres tres lent ....
1980
1981 unsigned int i = 0, j = 0;
1982 unsigned char r, g, b;
1983
1984 while ( j < size * 3 / 2 )
1985 {
1986 YUVToRGB( yuv[j + 1], yuv[j], yuv[j + 3], r, g, b );
1987 rgb[i] = r;
1988 rgb[i + 1] = g;
1989 rgb[i + 2] = b;
1990 i += 3;
1991
1992 YUVToRGB( yuv[j + 2], yuv[j], yuv[j + 3], r, g, b );
1993 rgb[i] = r;
1994 rgb[i + 1] = g;
1995 rgb[i + 2] = b;
1996 i += 3;
1997
1998 YUVToRGB( yuv[j + 4], yuv[j], yuv[j + 3], r, g, b );
1999 rgb[i] = r;
2000 rgb[i + 1] = g;
2001 rgb[i + 2] = b;
2002 i += 3;
2003
2004 YUVToRGB( yuv[j + 5], yuv[j], yuv[j + 3], r, g, b );
2005 rgb[i] = r;
2006 rgb[i + 1] = g;
2007 rgb[i + 2] = b;
2008 i += 3;
2009 // TRACE("r= %d g=%d b=%d", r, g, b);
2010
2011 j += 6;
2012 }
2013#endif
2014}
2015
2026void
2027vpImageConvert::YUV420ToRGBa( unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height )
2028{
2029 // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
2030 int U, V, R, G, B, V2, U5, UV;
2031 int Y0, Y1, Y2, Y3;
2032 unsigned int size = width * height;
2033 unsigned char *iU = yuv + size;
2034 unsigned char *iV = yuv + 5 * size / 4;
2035 for ( unsigned int i = 0; i < height / 2; i++ )
2036 {
2037 for ( unsigned int j = 0; j < width / 2; j++ )
2038 {
2039 U = (int)( ( *iU++ - 128 ) * 0.354 );
2040 U5 = 5 * U;
2041 V = (int)( ( *iV++ - 128 ) * 0.707 );
2042 V2 = 2 * V;
2043 UV = -U - V;
2044 Y0 = *yuv++;
2045 Y1 = *yuv;
2046 yuv = yuv + width - 1;
2047 Y2 = *yuv++;
2048 Y3 = *yuv;
2049 yuv = yuv - width + 1;
2050
2051 // Original equations
2052 // R = Y + 1.402 V
2053 // G = Y - 0.344 U - 0.714 V
2054 // B = Y + 1.772 U
2055 R = Y0 + V2;
2056 if ( ( R >> 8 ) > 0 )
2057 R = 255;
2058 else if ( R < 0 )
2059 R = 0;
2060
2061 G = Y0 + UV;
2062 if ( ( G >> 8 ) > 0 )
2063 G = 255;
2064 else if ( G < 0 )
2065 G = 0;
2066
2067 B = Y0 + U5;
2068 if ( ( B >> 8 ) > 0 )
2069 B = 255;
2070 else if ( B < 0 )
2071 B = 0;
2072
2073 *rgba++ = (unsigned char)R;
2074 *rgba++ = (unsigned char)G;
2075 *rgba++ = (unsigned char)B;
2076 *rgba++ = vpRGBa::alpha_default;
2077
2078 //---
2079 R = Y1 + V2;
2080 if ( ( R >> 8 ) > 0 )
2081 R = 255;
2082 else if ( R < 0 )
2083 R = 0;
2084
2085 G = Y1 + UV;
2086 if ( ( G >> 8 ) > 0 )
2087 G = 255;
2088 else if ( G < 0 )
2089 G = 0;
2090
2091 B = Y1 + U5;
2092 if ( ( B >> 8 ) > 0 )
2093 B = 255;
2094 else if ( B < 0 )
2095 B = 0;
2096
2097 *rgba++ = (unsigned char)R;
2098 *rgba++ = (unsigned char)G;
2099 *rgba++ = (unsigned char)B;
2100 *rgba = vpRGBa::alpha_default;
2101 rgba = rgba + 4 * width - 7;
2102
2103 //---
2104 R = Y2 + V2;
2105 if ( ( R >> 8 ) > 0 )
2106 R = 255;
2107 else if ( R < 0 )
2108 R = 0;
2109
2110 G = Y2 + UV;
2111 if ( ( G >> 8 ) > 0 )
2112 G = 255;
2113 else if ( G < 0 )
2114 G = 0;
2115
2116 B = Y2 + U5;
2117 if ( ( B >> 8 ) > 0 )
2118 B = 255;
2119 else if ( B < 0 )
2120 B = 0;
2121
2122 *rgba++ = (unsigned char)R;
2123 *rgba++ = (unsigned char)G;
2124 *rgba++ = (unsigned char)B;
2125 *rgba++ = vpRGBa::alpha_default;
2126
2127 //---
2128 R = Y3 + V2;
2129 if ( ( R >> 8 ) > 0 )
2130 R = 255;
2131 else if ( R < 0 )
2132 R = 0;
2133
2134 G = Y3 + UV;
2135 if ( ( G >> 8 ) > 0 )
2136 G = 255;
2137 else if ( G < 0 )
2138 G = 0;
2139
2140 B = Y3 + U5;
2141 if ( ( B >> 8 ) > 0 )
2142 B = 255;
2143 else if ( B < 0 )
2144 B = 0;
2145
2146 *rgba++ = (unsigned char)R;
2147 *rgba++ = (unsigned char)G;
2148 *rgba++ = (unsigned char)B;
2149 *rgba = vpRGBa::alpha_default;
2150 rgba = rgba - 4 * width + 1;
2151 }
2152 yuv += width;
2153 rgba += 4 * width;
2154 }
2155}
2156
2165void
2166vpImageConvert::YUV420ToRGB( unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height )
2167{
2168 // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
2169 int U, V, R, G, B, V2, U5, UV;
2170 int Y0, Y1, Y2, Y3;
2171 unsigned int size = width * height;
2172 unsigned char *iU = yuv + size;
2173 unsigned char *iV = yuv + 5 * size / 4;
2174 for ( unsigned int i = 0; i < height / 2; i++ )
2175 {
2176 for ( unsigned int j = 0; j < width / 2; j++ )
2177 {
2178 U = (int)( ( *iU++ - 128 ) * 0.354 );
2179 U5 = 5 * U;
2180 V = (int)( ( *iV++ - 128 ) * 0.707 );
2181 V2 = 2 * V;
2182 UV = -U - V;
2183 Y0 = *yuv++;
2184 Y1 = *yuv;
2185 yuv = yuv + width - 1;
2186 Y2 = *yuv++;
2187 Y3 = *yuv;
2188 yuv = yuv - width + 1;
2189
2190 // Original equations
2191 // R = Y + 1.402 V
2192 // G = Y - 0.344 U - 0.714 V
2193 // B = Y + 1.772 U
2194 R = Y0 + V2;
2195 if ( ( R >> 8 ) > 0 )
2196 R = 255;
2197 else if ( R < 0 )
2198 R = 0;
2199
2200 G = Y0 + UV;
2201 if ( ( G >> 8 ) > 0 )
2202 G = 255;
2203 else if ( G < 0 )
2204 G = 0;
2205
2206 B = Y0 + U5;
2207 if ( ( B >> 8 ) > 0 )
2208 B = 255;
2209 else if ( B < 0 )
2210 B = 0;
2211
2212 *rgb++ = (unsigned char)R;
2213 *rgb++ = (unsigned char)G;
2214 *rgb++ = (unsigned char)B;
2215
2216 //---
2217 R = Y1 + V2;
2218 if ( ( R >> 8 ) > 0 )
2219 R = 255;
2220 else if ( R < 0 )
2221 R = 0;
2222
2223 G = Y1 + UV;
2224 if ( ( G >> 8 ) > 0 )
2225 G = 255;
2226 else if ( G < 0 )
2227 G = 0;
2228
2229 B = Y1 + U5;
2230 if ( ( B >> 8 ) > 0 )
2231 B = 255;
2232 else if ( B < 0 )
2233 B = 0;
2234
2235 *rgb++ = (unsigned char)R;
2236 *rgb++ = (unsigned char)G;
2237 *rgb = (unsigned char)B;
2238 rgb = rgb + 3 * width - 5;
2239
2240 //---
2241 R = Y2 + V2;
2242 if ( ( R >> 8 ) > 0 )
2243 R = 255;
2244 else if ( R < 0 )
2245 R = 0;
2246
2247 G = Y2 + UV;
2248 if ( ( G >> 8 ) > 0 )
2249 G = 255;
2250 else if ( G < 0 )
2251 G = 0;
2252
2253 B = Y2 + U5;
2254 if ( ( B >> 8 ) > 0 )
2255 B = 255;
2256 else if ( B < 0 )
2257 B = 0;
2258
2259 *rgb++ = (unsigned char)R;
2260 *rgb++ = (unsigned char)G;
2261 *rgb++ = (unsigned char)B;
2262
2263 //---
2264 R = Y3 + V2;
2265 if ( ( R >> 8 ) > 0 )
2266 R = 255;
2267 else if ( R < 0 )
2268 R = 0;
2269
2270 G = Y3 + UV;
2271 if ( ( G >> 8 ) > 0 )
2272 G = 255;
2273 else if ( G < 0 )
2274 G = 0;
2275
2276 B = Y3 + U5;
2277 if ( ( B >> 8 ) > 0 )
2278 B = 255;
2279 else if ( B < 0 )
2280 B = 0;
2281
2282 *rgb++ = (unsigned char)R;
2283 *rgb++ = (unsigned char)G;
2284 *rgb = (unsigned char)B;
2285 rgb = rgb - 3 * width + 1;
2286 }
2287 yuv += width;
2288 rgb += 3 * width;
2289 }
2290}
2291
2299void
2300vpImageConvert::YUV420ToGrey( unsigned char *yuv, unsigned char *grey, unsigned int size )
2301{
2302 for ( unsigned int i = 0; i < size; i++ )
2303 {
2304 *grey++ = *yuv++;
2305 }
2306}
2307
2317void
2318vpImageConvert::YUV444ToRGBa( unsigned char *yuv, unsigned char *rgba, unsigned int size )
2319{
2320 for ( unsigned int i = 0; i < size; i++ )
2321 {
2322 int U = (int)( ( *yuv++ - 128 ) * 0.354 );
2323 int U5 = 5 * U;
2324 int Y = *yuv++;
2325 int V = (int)( ( *yuv++ - 128 ) * 0.707 );
2326 int V2 = 2 * V;
2327 int UV = -U - V;
2328
2329 // Original equations
2330 // R = Y + 1.402 V
2331 // G = Y - 0.344 U - 0.714 V
2332 // B = Y + 1.772 U
2333 int R = Y + V2;
2334 if ( ( R >> 8 ) > 0 )
2335 R = 255;
2336 else if ( R < 0 )
2337 R = 0;
2338
2339 int G = Y + UV;
2340 if ( ( G >> 8 ) > 0 )
2341 G = 255;
2342 else if ( G < 0 )
2343 G = 0;
2344
2345 int B = Y + U5;
2346 if ( ( B >> 8 ) > 0 )
2347 B = 255;
2348 else if ( B < 0 )
2349 B = 0;
2350
2351 *rgba++ = (unsigned char)R;
2352 *rgba++ = (unsigned char)G;
2353 *rgba++ = (unsigned char)B;
2354 *rgba++ = vpRGBa::alpha_default;
2355 }
2356}
2357
2365void
2366vpImageConvert::YUV444ToRGB( unsigned char *yuv, unsigned char *rgb, unsigned int size )
2367{
2368 for ( unsigned int i = 0; i < size; i++ )
2369 {
2370 int U = (int)( ( *yuv++ - 128 ) * 0.354 );
2371 int U5 = 5 * U;
2372 int Y = *yuv++;
2373 int V = (int)( ( *yuv++ - 128 ) * 0.707 );
2374 int V2 = 2 * V;
2375 int UV = -U - V;
2376
2377 // Original equations
2378 // R = Y + 1.402 V
2379 // G = Y - 0.344 U - 0.714 V
2380 // B = Y + 1.772 U
2381 int R = Y + V2;
2382 if ( ( R >> 8 ) > 0 )
2383 R = 255;
2384 else if ( R < 0 )
2385 R = 0;
2386
2387 int G = Y + UV;
2388 if ( ( G >> 8 ) > 0 )
2389 G = 255;
2390 else if ( G < 0 )
2391 G = 0;
2392
2393 int B = Y + U5;
2394 if ( ( B >> 8 ) > 0 )
2395 B = 255;
2396 else if ( B < 0 )
2397 B = 0;
2398
2399 *rgb++ = (unsigned char)R;
2400 *rgb++ = (unsigned char)G;
2401 *rgb++ = (unsigned char)B;
2402 }
2403}
2404
2412void
2413vpImageConvert::YUV444ToGrey( unsigned char *yuv, unsigned char *grey, unsigned int size )
2414{
2415 yuv++;
2416 for ( unsigned int i = 0; i < size; i++ )
2417 {
2418 *grey++ = *yuv;
2419 yuv = yuv + 3;
2420 }
2421}
2422
2433void
2434vpImageConvert::YV12ToRGBa( unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height )
2435{
2436 // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
2437 int U, V, R, G, B, V2, U5, UV;
2438 int Y0, Y1, Y2, Y3;
2439 unsigned int size = width * height;
2440 unsigned char *iV = yuv + size;
2441 unsigned char *iU = yuv + 5 * size / 4;
2442 for ( unsigned int i = 0; i < height / 2; i++ )
2443 {
2444 for ( unsigned int j = 0; j < width / 2; j++ )
2445 {
2446 U = (int)( ( *iU++ - 128 ) * 0.354 );
2447 U5 = 5 * U;
2448 V = (int)( ( *iV++ - 128 ) * 0.707 );
2449 V2 = 2 * V;
2450 UV = -U - V;
2451 Y0 = *yuv++;
2452 Y1 = *yuv;
2453 yuv = yuv + width - 1;
2454 Y2 = *yuv++;
2455 Y3 = *yuv;
2456 yuv = yuv - width + 1;
2457
2458 // Original equations
2459 // R = Y + 1.402 V
2460 // G = Y - 0.344 U - 0.714 V
2461 // B = Y + 1.772 U
2462 R = Y0 + V2;
2463 if ( ( R >> 8 ) > 0 )
2464 R = 255;
2465 else if ( R < 0 )
2466 R = 0;
2467
2468 G = Y0 + UV;
2469 if ( ( G >> 8 ) > 0 )
2470 G = 255;
2471 else if ( G < 0 )
2472 G = 0;
2473
2474 B = Y0 + U5;
2475 if ( ( B >> 8 ) > 0 )
2476 B = 255;
2477 else if ( B < 0 )
2478 B = 0;
2479
2480 *rgba++ = (unsigned char)R;
2481 *rgba++ = (unsigned char)G;
2482 *rgba++ = (unsigned char)B;
2483 *rgba++ = vpRGBa::alpha_default;
2484
2485 //---
2486 R = Y1 + V2;
2487 if ( ( R >> 8 ) > 0 )
2488 R = 255;
2489 else if ( R < 0 )
2490 R = 0;
2491
2492 G = Y1 + UV;
2493 if ( ( G >> 8 ) > 0 )
2494 G = 255;
2495 else if ( G < 0 )
2496 G = 0;
2497
2498 B = Y1 + U5;
2499 if ( ( B >> 8 ) > 0 )
2500 B = 255;
2501 else if ( B < 0 )
2502 B = 0;
2503
2504 *rgba++ = (unsigned char)R;
2505 *rgba++ = (unsigned char)G;
2506 *rgba++ = (unsigned char)B;
2507 *rgba = 0;
2508 rgba = rgba + 4 * width - 7;
2509
2510 //---
2511 R = Y2 + V2;
2512 if ( ( R >> 8 ) > 0 )
2513 R = 255;
2514 else if ( R < 0 )
2515 R = 0;
2516
2517 G = Y2 + UV;
2518 if ( ( G >> 8 ) > 0 )
2519 G = 255;
2520 else if ( G < 0 )
2521 G = 0;
2522
2523 B = Y2 + U5;
2524 if ( ( B >> 8 ) > 0 )
2525 B = 255;
2526 else if ( B < 0 )
2527 B = 0;
2528
2529 *rgba++ = (unsigned char)R;
2530 *rgba++ = (unsigned char)G;
2531 *rgba++ = (unsigned char)B;
2532 *rgba++ = vpRGBa::alpha_default;
2533
2534 //---
2535 R = Y3 + V2;
2536 if ( ( R >> 8 ) > 0 )
2537 R = 255;
2538 else if ( R < 0 )
2539 R = 0;
2540
2541 G = Y3 + UV;
2542 if ( ( G >> 8 ) > 0 )
2543 G = 255;
2544 else if ( G < 0 )
2545 G = 0;
2546
2547 B = Y3 + U5;
2548 if ( ( B >> 8 ) > 0 )
2549 B = 255;
2550 else if ( B < 0 )
2551 B = 0;
2552
2553 *rgba++ = (unsigned char)R;
2554 *rgba++ = (unsigned char)G;
2555 *rgba++ = (unsigned char)B;
2556 *rgba = vpRGBa::alpha_default;
2557 rgba = rgba - 4 * width + 1;
2558 }
2559 yuv += width;
2560 rgba += 4 * width;
2561 }
2562}
2563
2572void
2573vpImageConvert::YV12ToRGB( unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width )
2574{
2575 // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2576 int U, V, R, G, B, V2, U5, UV;
2577 int Y0, Y1, Y2, Y3;
2578 unsigned int size = width * height;
2579 unsigned char *iV = yuv + size;
2580 unsigned char *iU = yuv + 5 * size / 4;
2581 for ( unsigned int i = 0; i < height / 2; i++ )
2582 {
2583 for ( unsigned int j = 0; j < width / 2; j++ )
2584 {
2585 U = (int)( ( *iU++ - 128 ) * 0.354 );
2586 U5 = 5 * U;
2587 V = (int)( ( *iV++ - 128 ) * 0.707 );
2588 V2 = 2 * V;
2589 UV = -U - V;
2590 Y0 = *yuv++;
2591 Y1 = *yuv;
2592 yuv = yuv + width - 1;
2593 Y2 = *yuv++;
2594 Y3 = *yuv;
2595 yuv = yuv - width + 1;
2596
2597 // Original equations
2598 // R = Y + 1.402 V
2599 // G = Y - 0.344 U - 0.714 V
2600 // B = Y + 1.772 U
2601 R = Y0 + V2;
2602 if ( ( R >> 8 ) > 0 )
2603 R = 255;
2604 else if ( R < 0 )
2605 R = 0;
2606
2607 G = Y0 + UV;
2608 if ( ( G >> 8 ) > 0 )
2609 G = 255;
2610 else if ( G < 0 )
2611 G = 0;
2612
2613 B = Y0 + U5;
2614 if ( ( B >> 8 ) > 0 )
2615 B = 255;
2616 else if ( B < 0 )
2617 B = 0;
2618
2619 *rgb++ = (unsigned char)R;
2620 *rgb++ = (unsigned char)G;
2621 *rgb++ = (unsigned char)B;
2622
2623 //---
2624 R = Y1 + V2;
2625 if ( ( R >> 8 ) > 0 )
2626 R = 255;
2627 else if ( R < 0 )
2628 R = 0;
2629
2630 G = Y1 + UV;
2631 if ( ( G >> 8 ) > 0 )
2632 G = 255;
2633 else if ( G < 0 )
2634 G = 0;
2635
2636 B = Y1 + U5;
2637 if ( ( B >> 8 ) > 0 )
2638 B = 255;
2639 else if ( B < 0 )
2640 B = 0;
2641
2642 *rgb++ = (unsigned char)R;
2643 *rgb++ = (unsigned char)G;
2644 *rgb = (unsigned char)B;
2645 rgb = rgb + 3 * width - 5;
2646
2647 //---
2648 R = Y2 + V2;
2649 if ( ( R >> 8 ) > 0 )
2650 R = 255;
2651 else if ( R < 0 )
2652 R = 0;
2653
2654 G = Y2 + UV;
2655 if ( ( G >> 8 ) > 0 )
2656 G = 255;
2657 else if ( G < 0 )
2658 G = 0;
2659
2660 B = Y2 + U5;
2661 if ( ( B >> 8 ) > 0 )
2662 B = 255;
2663 else if ( B < 0 )
2664 B = 0;
2665
2666 *rgb++ = (unsigned char)R;
2667 *rgb++ = (unsigned char)G;
2668 *rgb++ = (unsigned char)B;
2669
2670 //---
2671 R = Y3 + V2;
2672 if ( ( R >> 8 ) > 0 )
2673 R = 255;
2674 else if ( R < 0 )
2675 R = 0;
2676
2677 G = Y3 + UV;
2678 if ( ( G >> 8 ) > 0 )
2679 G = 255;
2680 else if ( G < 0 )
2681 G = 0;
2682
2683 B = Y3 + U5;
2684 if ( ( B >> 8 ) > 0 )
2685 B = 255;
2686 else if ( B < 0 )
2687 B = 0;
2688
2689 *rgb++ = (unsigned char)R;
2690 *rgb++ = (unsigned char)G;
2691 *rgb = (unsigned char)B;
2692 rgb = rgb - 3 * width + 1;
2693 }
2694 yuv += width;
2695 rgb += 3 * width;
2696 }
2697}
2698
2709void
2710vpImageConvert::YVU9ToRGBa( unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height )
2711{
2712 // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2713 int U, V, R, G, B, V2, U5, UV;
2714 int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2715 unsigned int size = width * height;
2716 unsigned char *iV = yuv + size;
2717 unsigned char *iU = yuv + 17 * size / 16;
2718 for ( unsigned int i = 0; i < height / 4; i++ )
2719 {
2720 for ( unsigned int j = 0; j < width / 4; j++ )
2721 {
2722 U = (int)( ( *iU++ - 128 ) * 0.354 );
2723 U5 = 5 * U;
2724 V = (int)( ( *iV++ - 128 ) * 0.707 );
2725 V2 = 2 * V;
2726 UV = -U - V;
2727 Y0 = *yuv++;
2728 Y1 = *yuv++;
2729 Y2 = *yuv++;
2730 Y3 = *yuv;
2731 yuv = yuv + width - 3;
2732 Y4 = *yuv++;
2733 Y5 = *yuv++;
2734 Y6 = *yuv++;
2735 Y7 = *yuv;
2736 yuv = yuv + width - 3;
2737 Y8 = *yuv++;
2738 Y9 = *yuv++;
2739 Y10 = *yuv++;
2740 Y11 = *yuv;
2741 yuv = yuv + width - 3;
2742 Y12 = *yuv++;
2743 Y13 = *yuv++;
2744 Y14 = *yuv++;
2745 Y15 = *yuv;
2746 yuv = yuv - 3 * width + 1;
2747
2748 // Original equations
2749 // R = Y + 1.402 V
2750 // G = Y - 0.344 U - 0.714 V
2751 // B = Y + 1.772 U
2752 R = Y0 + V2;
2753 if ( ( R >> 8 ) > 0 )
2754 R = 255;
2755 else if ( R < 0 )
2756 R = 0;
2757
2758 G = Y0 + UV;
2759 if ( ( G >> 8 ) > 0 )
2760 G = 255;
2761 else if ( G < 0 )
2762 G = 0;
2763
2764 B = Y0 + U5;
2765 if ( ( B >> 8 ) > 0 )
2766 B = 255;
2767 else if ( B < 0 )
2768 B = 0;
2769
2770 *rgba++ = (unsigned char)R;
2771 *rgba++ = (unsigned char)G;
2772 *rgba++ = (unsigned char)B;
2773 *rgba++ = vpRGBa::alpha_default;
2774
2775 //---
2776 R = Y1 + V2;
2777 if ( ( R >> 8 ) > 0 )
2778 R = 255;
2779 else if ( R < 0 )
2780 R = 0;
2781
2782 G = Y1 + UV;
2783 if ( ( G >> 8 ) > 0 )
2784 G = 255;
2785 else if ( G < 0 )
2786 G = 0;
2787
2788 B = Y1 + U5;
2789 if ( ( B >> 8 ) > 0 )
2790 B = 255;
2791 else if ( B < 0 )
2792 B = 0;
2793
2794 *rgba++ = (unsigned char)R;
2795 *rgba++ = (unsigned char)G;
2796 *rgba++ = (unsigned char)B;
2797 *rgba++ = vpRGBa::alpha_default;
2798
2799 //---
2800 R = Y2 + V2;
2801 if ( ( R >> 8 ) > 0 )
2802 R = 255;
2803 else if ( R < 0 )
2804 R = 0;
2805
2806 G = Y2 + UV;
2807 if ( ( G >> 8 ) > 0 )
2808 G = 255;
2809 else if ( G < 0 )
2810 G = 0;
2811
2812 B = Y2 + U5;
2813 if ( ( B >> 8 ) > 0 )
2814 B = 255;
2815 else if ( B < 0 )
2816 B = 0;
2817
2818 *rgba++ = (unsigned char)R;
2819 *rgba++ = (unsigned char)G;
2820 *rgba++ = (unsigned char)B;
2821 *rgba++ = vpRGBa::alpha_default;
2822
2823 //---
2824 R = Y3 + V2;
2825 if ( ( R >> 8 ) > 0 )
2826 R = 255;
2827 else if ( R < 0 )
2828 R = 0;
2829
2830 G = Y3 + UV;
2831 if ( ( G >> 8 ) > 0 )
2832 G = 255;
2833 else if ( G < 0 )
2834 G = 0;
2835
2836 B = Y3 + U5;
2837 if ( ( B >> 8 ) > 0 )
2838 B = 255;
2839 else if ( B < 0 )
2840 B = 0;
2841
2842 *rgba++ = (unsigned char)R;
2843 *rgba++ = (unsigned char)G;
2844 *rgba++ = (unsigned char)B;
2845 *rgba = vpRGBa::alpha_default;
2846 rgba = rgba + 4 * width - 15;
2847
2848 R = Y4 + V2;
2849 if ( ( R >> 8 ) > 0 )
2850 R = 255;
2851 else if ( R < 0 )
2852 R = 0;
2853
2854 G = Y4 + UV;
2855 if ( ( G >> 8 ) > 0 )
2856 G = 255;
2857 else if ( G < 0 )
2858 G = 0;
2859
2860 B = Y4 + U5;
2861 if ( ( B >> 8 ) > 0 )
2862 B = 255;
2863 else if ( B < 0 )
2864 B = 0;
2865
2866 *rgba++ = (unsigned char)R;
2867 *rgba++ = (unsigned char)G;
2868 *rgba++ = (unsigned char)B;
2869 *rgba++ = vpRGBa::alpha_default;
2870
2871 //---
2872 R = Y5 + V2;
2873 if ( ( R >> 8 ) > 0 )
2874 R = 255;
2875 else if ( R < 0 )
2876 R = 0;
2877
2878 G = Y5 + UV;
2879 if ( ( G >> 8 ) > 0 )
2880 G = 255;
2881 else if ( G < 0 )
2882 G = 0;
2883
2884 B = Y5 + U5;
2885 if ( ( B >> 8 ) > 0 )
2886 B = 255;
2887 else if ( B < 0 )
2888 B = 0;
2889
2890 *rgba++ = (unsigned char)R;
2891 *rgba++ = (unsigned char)G;
2892 *rgba++ = (unsigned char)B;
2893 *rgba++ = vpRGBa::alpha_default;
2894
2895 //---
2896 R = Y6 + V2;
2897 if ( ( R >> 8 ) > 0 )
2898 R = 255;
2899 else if ( R < 0 )
2900 R = 0;
2901
2902 G = Y6 + UV;
2903 if ( ( G >> 8 ) > 0 )
2904 G = 255;
2905 else if ( G < 0 )
2906 G = 0;
2907
2908 B = Y6 + U5;
2909 if ( ( B >> 8 ) > 0 )
2910 B = 255;
2911 else if ( B < 0 )
2912 B = 0;
2913
2914 *rgba++ = (unsigned char)R;
2915 *rgba++ = (unsigned char)G;
2916 *rgba++ = (unsigned char)B;
2917 *rgba++ = vpRGBa::alpha_default;
2918
2919 //---
2920 R = Y7 + V2;
2921 if ( ( R >> 8 ) > 0 )
2922 R = 255;
2923 else if ( R < 0 )
2924 R = 0;
2925
2926 G = Y7 + UV;
2927 if ( ( G >> 8 ) > 0 )
2928 G = 255;
2929 else if ( G < 0 )
2930 G = 0;
2931
2932 B = Y7 + U5;
2933 if ( ( B >> 8 ) > 0 )
2934 B = 255;
2935 else if ( B < 0 )
2936 B = 0;
2937
2938 *rgba++ = (unsigned char)R;
2939 *rgba++ = (unsigned char)G;
2940 *rgba++ = (unsigned char)B;
2941 *rgba = vpRGBa::alpha_default;
2942 rgba = rgba + 4 * width - 15;
2943
2944 R = Y8 + V2;
2945 if ( ( R >> 8 ) > 0 )
2946 R = 255;
2947 else if ( R < 0 )
2948 R = 0;
2949
2950 G = Y8 + UV;
2951 if ( ( G >> 8 ) > 0 )
2952 G = 255;
2953 else if ( G < 0 )
2954 G = 0;
2955
2956 B = Y8 + U5;
2957 if ( ( B >> 8 ) > 0 )
2958 B = 255;
2959 else if ( B < 0 )
2960 B = 0;
2961
2962 *rgba++ = (unsigned char)R;
2963 *rgba++ = (unsigned char)G;
2964 *rgba++ = (unsigned char)B;
2965 *rgba++ = vpRGBa::alpha_default;
2966
2967 //---
2968 R = Y9 + V2;
2969 if ( ( R >> 8 ) > 0 )
2970 R = 255;
2971 else if ( R < 0 )
2972 R = 0;
2973
2974 G = Y9 + UV;
2975 if ( ( G >> 8 ) > 0 )
2976 G = 255;
2977 else if ( G < 0 )
2978 G = 0;
2979
2980 B = Y9 + U5;
2981 if ( ( B >> 8 ) > 0 )
2982 B = 255;
2983 else if ( B < 0 )
2984 B = 0;
2985
2986 *rgba++ = (unsigned char)R;
2987 *rgba++ = (unsigned char)G;
2988 *rgba++ = (unsigned char)B;
2989 *rgba++ = vpRGBa::alpha_default;
2990
2991 //---
2992 R = Y10 + V2;
2993 if ( ( R >> 8 ) > 0 )
2994 R = 255;
2995 else if ( R < 0 )
2996 R = 0;
2997
2998 G = Y10 + UV;
2999 if ( ( G >> 8 ) > 0 )
3000 G = 255;
3001 else if ( G < 0 )
3002 G = 0;
3003
3004 B = Y10 + U5;
3005 if ( ( B >> 8 ) > 0 )
3006 B = 255;
3007 else if ( B < 0 )
3008 B = 0;
3009
3010 *rgba++ = (unsigned char)R;
3011 *rgba++ = (unsigned char)G;
3012 *rgba++ = (unsigned char)B;
3013 *rgba++ = vpRGBa::alpha_default;
3014
3015 //---
3016 R = Y11 + V2;
3017 if ( ( R >> 8 ) > 0 )
3018 R = 255;
3019 else if ( R < 0 )
3020 R = 0;
3021
3022 G = Y11 + UV;
3023 if ( ( G >> 8 ) > 0 )
3024 G = 255;
3025 else if ( G < 0 )
3026 G = 0;
3027
3028 B = Y11 + U5;
3029 if ( ( B >> 8 ) > 0 )
3030 B = 255;
3031 else if ( B < 0 )
3032 B = 0;
3033
3034 *rgba++ = (unsigned char)R;
3035 *rgba++ = (unsigned char)G;
3036 *rgba++ = (unsigned char)B;
3037 *rgba = vpRGBa::alpha_default;
3038 rgba = rgba + 4 * width - 15;
3039
3040 R = Y12 + V2;
3041 if ( ( R >> 8 ) > 0 )
3042 R = 255;
3043 else if ( R < 0 )
3044 R = 0;
3045
3046 G = Y12 + UV;
3047 if ( ( G >> 8 ) > 0 )
3048 G = 255;
3049 else if ( G < 0 )
3050 G = 0;
3051
3052 B = Y12 + U5;
3053 if ( ( B >> 8 ) > 0 )
3054 B = 255;
3055 else if ( B < 0 )
3056 B = 0;
3057
3058 *rgba++ = (unsigned char)R;
3059 *rgba++ = (unsigned char)G;
3060 *rgba++ = (unsigned char)B;
3061 *rgba++ = vpRGBa::alpha_default;
3062
3063 //---
3064 R = Y13 + V2;
3065 if ( ( R >> 8 ) > 0 )
3066 R = 255;
3067 else if ( R < 0 )
3068 R = 0;
3069
3070 G = Y13 + UV;
3071 if ( ( G >> 8 ) > 0 )
3072 G = 255;
3073 else if ( G < 0 )
3074 G = 0;
3075
3076 B = Y13 + U5;
3077 if ( ( B >> 8 ) > 0 )
3078 B = 255;
3079 else if ( B < 0 )
3080 B = 0;
3081
3082 *rgba++ = (unsigned char)R;
3083 *rgba++ = (unsigned char)G;
3084 *rgba++ = (unsigned char)B;
3085 *rgba++ = vpRGBa::alpha_default;
3086
3087 //---
3088 R = Y14 + V2;
3089 if ( ( R >> 8 ) > 0 )
3090 R = 255;
3091 else if ( R < 0 )
3092 R = 0;
3093
3094 G = Y14 + UV;
3095 if ( ( G >> 8 ) > 0 )
3096 G = 255;
3097 else if ( G < 0 )
3098 G = 0;
3099
3100 B = Y14 + U5;
3101 if ( ( B >> 8 ) > 0 )
3102 B = 255;
3103 else if ( B < 0 )
3104 B = 0;
3105
3106 *rgba++ = (unsigned char)R;
3107 *rgba++ = (unsigned char)G;
3108 *rgba++ = (unsigned char)B;
3109 *rgba++ = vpRGBa::alpha_default;
3110
3111 //---
3112 R = Y15 + V2;
3113 if ( ( R >> 8 ) > 0 )
3114 R = 255;
3115 else if ( R < 0 )
3116 R = 0;
3117
3118 G = Y15 + UV;
3119 if ( ( G >> 8 ) > 0 )
3120 G = 255;
3121 else if ( G < 0 )
3122 G = 0;
3123
3124 B = Y15 + U5;
3125 if ( ( B >> 8 ) > 0 )
3126 B = 255;
3127 else if ( B < 0 )
3128 B = 0;
3129
3130 *rgba++ = (unsigned char)R;
3131 *rgba++ = (unsigned char)G;
3132 *rgba++ = (unsigned char)B;
3133 *rgba = vpRGBa::alpha_default;
3134 rgba = rgba - 12 * width + 1;
3135 }
3136 yuv += 3 * width;
3137 rgba += 12 * width;
3138 }
3139}
3140
3148void
3149vpImageConvert::YVU9ToRGB( unsigned char *yuv, unsigned char *rgb, unsigned int height, unsigned int width )
3150{
3151 // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
3152 int U, V, R, G, B, V2, U5, UV;
3153 int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
3154 unsigned int size = width * height;
3155 unsigned char *iV = yuv + size;
3156 unsigned char *iU = yuv + 17 * size / 16;
3157 for ( unsigned int i = 0; i < height / 4; i++ )
3158 {
3159 for ( unsigned int j = 0; j < width / 4; j++ )
3160 {
3161 U = (int)( ( *iU++ - 128 ) * 0.354 );
3162 U5 = 5 * U;
3163 V = (int)( ( *iV++ - 128 ) * 0.707 );
3164 V2 = 2 * V;
3165 UV = -U - V;
3166 Y0 = *yuv++;
3167 Y1 = *yuv++;
3168 Y2 = *yuv++;
3169 Y3 = *yuv;
3170 yuv = yuv + width - 3;
3171 Y4 = *yuv++;
3172 Y5 = *yuv++;
3173 Y6 = *yuv++;
3174 Y7 = *yuv;
3175 yuv = yuv + width - 3;
3176 Y8 = *yuv++;
3177 Y9 = *yuv++;
3178 Y10 = *yuv++;
3179 Y11 = *yuv;
3180 yuv = yuv + width - 3;
3181 Y12 = *yuv++;
3182 Y13 = *yuv++;
3183 Y14 = *yuv++;
3184 Y15 = *yuv;
3185 yuv = yuv - 3 * width + 1;
3186
3187 // Original equations
3188 // R = Y + 1.402 V
3189 // G = Y - 0.344 U - 0.714 V
3190 // B = Y + 1.772 U
3191 R = Y0 + V2;
3192 if ( ( R >> 8 ) > 0 )
3193 R = 255;
3194 else if ( R < 0 )
3195 R = 0;
3196
3197 G = Y0 + UV;
3198 if ( ( G >> 8 ) > 0 )
3199 G = 255;
3200 else if ( G < 0 )
3201 G = 0;
3202
3203 B = Y0 + U5;
3204 if ( ( B >> 8 ) > 0 )
3205 B = 255;
3206 else if ( B < 0 )
3207 B = 0;
3208
3209 *rgb++ = (unsigned char)R;
3210 *rgb++ = (unsigned char)G;
3211 *rgb++ = (unsigned char)B;
3212
3213 //---
3214 R = Y1 + V2;
3215 if ( ( R >> 8 ) > 0 )
3216 R = 255;
3217 else if ( R < 0 )
3218 R = 0;
3219
3220 G = Y1 + UV;
3221 if ( ( G >> 8 ) > 0 )
3222 G = 255;
3223 else if ( G < 0 )
3224 G = 0;
3225
3226 B = Y1 + U5;
3227 if ( ( B >> 8 ) > 0 )
3228 B = 255;
3229 else if ( B < 0 )
3230 B = 0;
3231
3232 *rgb++ = (unsigned char)R;
3233 *rgb++ = (unsigned char)G;
3234 *rgb++ = (unsigned char)B;
3235
3236 //---
3237 R = Y2 + V2;
3238 if ( ( R >> 8 ) > 0 )
3239 R = 255;
3240 else if ( R < 0 )
3241 R = 0;
3242
3243 G = Y2 + UV;
3244 if ( ( G >> 8 ) > 0 )
3245 G = 255;
3246 else if ( G < 0 )
3247 G = 0;
3248
3249 B = Y2 + U5;
3250 if ( ( B >> 8 ) > 0 )
3251 B = 255;
3252 else if ( B < 0 )
3253 B = 0;
3254
3255 *rgb++ = (unsigned char)R;
3256 *rgb++ = (unsigned char)G;
3257 *rgb++ = (unsigned char)B;
3258
3259 //---
3260 R = Y3 + V2;
3261 if ( ( R >> 8 ) > 0 )
3262 R = 255;
3263 else if ( R < 0 )
3264 R = 0;
3265
3266 G = Y3 + UV;
3267 if ( ( G >> 8 ) > 0 )
3268 G = 255;
3269 else if ( G < 0 )
3270 G = 0;
3271
3272 B = Y3 + U5;
3273 if ( ( B >> 8 ) > 0 )
3274 B = 255;
3275 else if ( B < 0 )
3276 B = 0;
3277
3278 *rgb++ = (unsigned char)R;
3279 *rgb++ = (unsigned char)G;
3280 *rgb = (unsigned char)B;
3281 rgb = rgb + 3 * width - 11;
3282
3283 R = Y4 + V2;
3284 if ( ( R >> 8 ) > 0 )
3285 R = 255;
3286 else if ( R < 0 )
3287 R = 0;
3288
3289 G = Y4 + UV;
3290 if ( ( G >> 8 ) > 0 )
3291 G = 255;
3292 else if ( G < 0 )
3293 G = 0;
3294
3295 B = Y4 + U5;
3296 if ( ( B >> 8 ) > 0 )
3297 B = 255;
3298 else if ( B < 0 )
3299 B = 0;
3300
3301 *rgb++ = (unsigned char)R;
3302 *rgb++ = (unsigned char)G;
3303 *rgb++ = (unsigned char)B;
3304
3305 //---
3306 R = Y5 + V2;
3307 if ( ( R >> 8 ) > 0 )
3308 R = 255;
3309 else if ( R < 0 )
3310 R = 0;
3311
3312 G = Y5 + UV;
3313 if ( ( G >> 8 ) > 0 )
3314 G = 255;
3315 else if ( G < 0 )
3316 G = 0;
3317
3318 B = Y5 + U5;
3319 if ( ( B >> 8 ) > 0 )
3320 B = 255;
3321 else if ( B < 0 )
3322 B = 0;
3323
3324 *rgb++ = (unsigned char)R;
3325 *rgb++ = (unsigned char)G;
3326 *rgb++ = (unsigned char)B;
3327
3328 //---
3329 R = Y6 + V2;
3330 if ( ( R >> 8 ) > 0 )
3331 R = 255;
3332 else if ( R < 0 )
3333 R = 0;
3334
3335 G = Y6 + UV;
3336 if ( ( G >> 8 ) > 0 )
3337 G = 255;
3338 else if ( G < 0 )
3339 G = 0;
3340
3341 B = Y6 + U5;
3342 if ( ( B >> 8 ) > 0 )
3343 B = 255;
3344 else if ( B < 0 )
3345 B = 0;
3346
3347 *rgb++ = (unsigned char)R;
3348 *rgb++ = (unsigned char)G;
3349 *rgb++ = (unsigned char)B;
3350
3351 //---
3352 R = Y7 + V2;
3353 if ( ( R >> 8 ) > 0 )
3354 R = 255;
3355 else if ( R < 0 )
3356 R = 0;
3357
3358 G = Y7 + UV;
3359 if ( ( G >> 8 ) > 0 )
3360 G = 255;
3361 else if ( G < 0 )
3362 G = 0;
3363
3364 B = Y7 + U5;
3365 if ( ( B >> 8 ) > 0 )
3366 B = 255;
3367 else if ( B < 0 )
3368 B = 0;
3369
3370 *rgb++ = (unsigned char)R;
3371 *rgb++ = (unsigned char)G;
3372 *rgb = (unsigned char)B;
3373 rgb = rgb + 3 * width - 11;
3374
3375 R = Y8 + V2;
3376 if ( ( R >> 8 ) > 0 )
3377 R = 255;
3378 else if ( R < 0 )
3379 R = 0;
3380
3381 G = Y8 + UV;
3382 if ( ( G >> 8 ) > 0 )
3383 G = 255;
3384 else if ( G < 0 )
3385 G = 0;
3386
3387 B = Y8 + U5;
3388 if ( ( B >> 8 ) > 0 )
3389 B = 255;
3390 else if ( B < 0 )
3391 B = 0;
3392
3393 *rgb++ = (unsigned char)R;
3394 *rgb++ = (unsigned char)G;
3395 *rgb++ = (unsigned char)B;
3396
3397 //---
3398 R = Y9 + V2;
3399 if ( ( R >> 8 ) > 0 )
3400 R = 255;
3401 else if ( R < 0 )
3402 R = 0;
3403
3404 G = Y9 + UV;
3405 if ( ( G >> 8 ) > 0 )
3406 G = 255;
3407 else if ( G < 0 )
3408 G = 0;
3409
3410 B = Y9 + U5;
3411 if ( ( B >> 8 ) > 0 )
3412 B = 255;
3413 else if ( B < 0 )
3414 B = 0;
3415
3416 *rgb++ = (unsigned char)R;
3417 *rgb++ = (unsigned char)G;
3418 *rgb++ = (unsigned char)B;
3419
3420 //---
3421 R = Y10 + V2;
3422 if ( ( R >> 8 ) > 0 )
3423 R = 255;
3424 else if ( R < 0 )
3425 R = 0;
3426
3427 G = Y10 + UV;
3428 if ( ( G >> 8 ) > 0 )
3429 G = 255;
3430 else if ( G < 0 )
3431 G = 0;
3432
3433 B = Y10 + U5;
3434 if ( ( B >> 8 ) > 0 )
3435 B = 255;
3436 else if ( B < 0 )
3437 B = 0;
3438
3439 *rgb++ = (unsigned char)R;
3440 *rgb++ = (unsigned char)G;
3441 *rgb++ = (unsigned char)B;
3442
3443 //---
3444 R = Y11 + V2;
3445 if ( ( R >> 8 ) > 0 )
3446 R = 255;
3447 else if ( R < 0 )
3448 R = 0;
3449
3450 G = Y11 + UV;
3451 if ( ( G >> 8 ) > 0 )
3452 G = 255;
3453 else if ( G < 0 )
3454 G = 0;
3455
3456 B = Y11 + U5;
3457 if ( ( B >> 8 ) > 0 )
3458 B = 255;
3459 else if ( B < 0 )
3460 B = 0;
3461
3462 *rgb++ = (unsigned char)R;
3463 *rgb++ = (unsigned char)G;
3464 *rgb = (unsigned char)B;
3465 rgb = rgb + 3 * width - 11;
3466
3467 R = Y12 + V2;
3468 if ( ( R >> 8 ) > 0 )
3469 R = 255;
3470 else if ( R < 0 )
3471 R = 0;
3472
3473 G = Y12 + UV;
3474 if ( ( G >> 8 ) > 0 )
3475 G = 255;
3476 else if ( G < 0 )
3477 G = 0;
3478
3479 B = Y12 + U5;
3480 if ( ( B >> 8 ) > 0 )
3481 B = 255;
3482 else if ( B < 0 )
3483 B = 0;
3484
3485 *rgb++ = (unsigned char)R;
3486 *rgb++ = (unsigned char)G;
3487 *rgb++ = (unsigned char)B;
3488
3489 //---
3490 R = Y13 + V2;
3491 if ( ( R >> 8 ) > 0 )
3492 R = 255;
3493 else if ( R < 0 )
3494 R = 0;
3495
3496 G = Y13 + UV;
3497 if ( ( G >> 8 ) > 0 )
3498 G = 255;
3499 else if ( G < 0 )
3500 G = 0;
3501
3502 B = Y13 + U5;
3503 if ( ( B >> 8 ) > 0 )
3504 B = 255;
3505 else if ( B < 0 )
3506 B = 0;
3507
3508 *rgb++ = (unsigned char)R;
3509 *rgb++ = (unsigned char)G;
3510 *rgb++ = (unsigned char)B;
3511
3512 //---
3513 R = Y14 + V2;
3514 if ( ( R >> 8 ) > 0 )
3515 R = 255;
3516 else if ( R < 0 )
3517 R = 0;
3518
3519 G = Y14 + UV;
3520 if ( ( G >> 8 ) > 0 )
3521 G = 255;
3522 else if ( G < 0 )
3523 G = 0;
3524
3525 B = Y14 + U5;
3526 if ( ( B >> 8 ) > 0 )
3527 B = 255;
3528 else if ( B < 0 )
3529 B = 0;
3530
3531 *rgb++ = (unsigned char)R;
3532 *rgb++ = (unsigned char)G;
3533 *rgb++ = (unsigned char)B;
3534
3535 //---
3536 R = Y15 + V2;
3537 if ( ( R >> 8 ) > 0 )
3538 R = 255;
3539 else if ( R < 0 )
3540 R = 0;
3541
3542 G = Y15 + UV;
3543 if ( ( G >> 8 ) > 0 )
3544 G = 255;
3545 else if ( G < 0 )
3546 G = 0;
3547
3548 B = Y15 + U5;
3549 if ( ( B >> 8 ) > 0 )
3550 B = 255;
3551 else if ( B < 0 )
3552 B = 0;
3553
3554 *rgb++ = (unsigned char)R;
3555 *rgb++ = (unsigned char)G;
3556 *rgb++ = (unsigned char)B;
3557 rgb = rgb - 9 * width + 1;
3558 }
3559 yuv += 3 * width;
3560 rgb += 9 * width;
3561 }
3562}
3563
3573void
3574vpImageConvert::RGBToRGBa( unsigned char *rgb, unsigned char *rgba, unsigned int size )
3575{
3576 RGBToRGBa( rgb, rgba, size, 1, false );
3577}
3578
3594void
3595vpImageConvert::RGBToRGBa( unsigned char *rgb, unsigned char *rgba, unsigned int width, unsigned int height, bool flip )
3596{
3597 if ( !flip )
3598 {
3599 SimdBgrToBgra( rgb, width, height, width * 3, rgba, width * 4, vpRGBa::alpha_default );
3600 }
3601 else
3602 {
3603 // if we have to flip the image, we start from the end last scanline so the
3604 // step is negative
3605 int lineStep = ( flip ) ? -(int)( width * 3 ) : (int)( width * 3 );
3606
3607 // starting source address = last line if we need to flip the image
3608 unsigned char *src = ( flip ) ? ( rgb + ( width * height * 3 ) + lineStep ) : rgb;
3609
3610 unsigned int j = 0;
3611 unsigned int i = 0;
3612
3613 for ( i = 0; i < height; i++ )
3614 {
3615 unsigned char *line = src;
3616 for ( j = 0; j < width; j++ )
3617 {
3618 *rgba++ = *( line++ );
3619 *rgba++ = *( line++ );
3620 *rgba++ = *( line++ );
3621 *rgba++ = vpRGBa::alpha_default;
3622 }
3623 // go to the next line
3624 src += lineStep;
3625 }
3626 }
3627}
3628
3641void
3642vpImageConvert::RGBaToRGB( unsigned char *rgba, unsigned char *rgb, unsigned int size )
3643{
3644 SimdBgraToBgr( rgba, size, 1, size * 4, rgb, size * 3 );
3645}
3646
3659void
3660vpImageConvert::RGBToGrey( unsigned char *rgb, unsigned char *grey, unsigned int size )
3661{
3662 RGBToGrey( rgb, grey, size, 1, false );
3663}
3664
3678void
3679vpImageConvert::RGBToGrey( unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip )
3680{
3681 if ( !flip )
3682 {
3683 SimdRgbToGray( rgb, width, height, width * 3, grey, width );
3684 }
3685 else
3686 {
3687 // if we have to flip the image, we start from the end last scanline so
3688 // the step is negative
3689 int lineStep = ( flip ) ? -(int)( width * 3 ) : (int)( width * 3 );
3690
3691 // starting source address = last line if we need to flip the image
3692 unsigned char *src = ( flip ) ? rgb + ( width * height * 3 ) + lineStep : rgb;
3693
3694 unsigned int j = 0;
3695 unsigned int i = 0;
3696
3697 unsigned r, g, b;
3698
3699 for ( i = 0; i < height; i++ )
3700 {
3701 unsigned char *line = src;
3702 for ( j = 0; j < width; j++ )
3703 {
3704 r = *( line++ );
3705 g = *( line++ );
3706 b = *( line++ );
3707 *grey++ = (unsigned char)( 0.2126 * r + 0.7152 * g + 0.0722 * b );
3708 }
3709
3710 // go to the next line
3711 src += lineStep;
3712 }
3713 }
3714}
3715
3731void
3732vpImageConvert::RGBaToGrey( unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height,
3733 unsigned int
3734#if defined _OPENMP
3735 nThreads
3736#endif
3737)
3738{
3739#if defined _OPENMP
3740 if ( nThreads > 0 )
3741 {
3742 omp_set_num_threads( static_cast< int >( nThreads ) );
3743 }
3744#pragma omp parallel for
3745#endif
3746 for ( int i = 0; i < static_cast< int >( height ); i++ )
3747 {
3748 SimdRgbaToGray( rgba + i * width * 4, width, 1, width * 4, grey + i * width, width );
3749 }
3750}
3751
3766void
3767vpImageConvert::RGBaToGrey( unsigned char *rgba, unsigned char *grey, unsigned int size )
3768{
3769 SimdRgbaToGray( rgba, size, 1, size * 4, grey, size );
3770}
3771
3783void
3784vpImageConvert::GreyToRGBa( unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height )
3785{
3786 SimdGrayToBgra( grey, width, height, width, rgba, width * sizeof( vpRGBa ), vpRGBa::alpha_default );
3787}
3788
3801void
3802vpImageConvert::GreyToRGBa( unsigned char *grey, unsigned char *rgba, unsigned int size )
3803{
3804 GreyToRGBa( grey, rgba, size, 1 );
3805}
3806
3817void
3818vpImageConvert::GreyToRGB( unsigned char *grey, unsigned char *rgb, unsigned int size )
3819{
3820 SimdGrayToBgr( grey, size, 1, size, rgb, size * 3 );
3821}
3822
3838void
3839vpImageConvert::BGRToRGBa( unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip )
3840{
3841 if ( !flip )
3842 {
3843 SimdRgbToBgra( bgr, width, height, width * 3, rgba, width * sizeof( vpRGBa ), vpRGBa::alpha_default );
3844 }
3845 else
3846 {
3847 // if we have to flip the image, we start from the end last scanline so the
3848 // step is negative
3849 int lineStep = ( flip ) ? -(int)( width * 3 ) : (int)( width * 3 );
3850
3851 // starting source address = last line if we need to flip the image
3852 unsigned char *src = ( flip ) ? ( bgr + ( width * height * 3 ) + lineStep ) : bgr;
3853
3854 for ( unsigned int i = 0; i < height; i++ )
3855 {
3856 unsigned char *line = src;
3857 for ( unsigned int j = 0; j < width; j++ )
3858 {
3859 *rgba++ = *( line + 2 );
3860 *rgba++ = *( line + 1 );
3861 *rgba++ = *( line + 0 );
3862 *rgba++ = vpRGBa::alpha_default;
3863
3864 line += 3;
3865 }
3866 // go to the next line
3867 src += lineStep;
3868 }
3869 }
3870}
3871
3886void
3887vpImageConvert::BGRaToRGBa( unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height,
3888 bool flip )
3889{
3890 if ( !flip )
3891 {
3892 SimdBgraToRgba( bgra, width, height, width * 4, rgba, width * 4 );
3893 }
3894 else
3895 {
3896 // if we have to flip the image, we start from the end last scanline so the
3897 // step is negative
3898 int lineStep = ( flip ) ? -(int)( width * 4 ) : (int)( width * 4 );
3899
3900 // starting source address = last line if we need to flip the image
3901 unsigned char *src = ( flip ) ? ( bgra + ( width * height * 4 ) + lineStep ) : bgra;
3902
3903 for ( unsigned int i = 0; i < height; i++ )
3904 {
3905 unsigned char *line = src;
3906 for ( unsigned int j = 0; j < width; j++ )
3907 {
3908 *rgba++ = *( line + 2 );
3909 *rgba++ = *( line + 1 );
3910 *rgba++ = *( line + 0 );
3911 *rgba++ = *( line + 3 );
3912
3913 line += 4;
3914 }
3915 // go to the next line
3916 src += lineStep;
3917 }
3918 }
3919}
3920
3935void
3936vpImageConvert::BGRToGrey( unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip,
3937 unsigned int
3938#if defined _OPENMP
3939 nThreads
3940#endif
3941)
3942{
3943 if ( !flip )
3944 {
3945#if defined _OPENMP
3946 if ( nThreads > 0 )
3947 {
3948 omp_set_num_threads( static_cast< int >( nThreads ) );
3949 }
3950#pragma omp parallel for
3951#endif
3952 for ( int i = 0; i < static_cast< int >( height ); i++ )
3953 {
3954 SimdBgrToGray( bgr + i * width * 3, width, 1, width * 3, grey + i * width, width );
3955 }
3956 }
3957 else
3958 {
3959 // if we have to flip the image, we start from the end last scanline so
3960 // the step is negative
3961 int lineStep = ( flip ) ? -(int)( width * 3 ) : (int)( width * 3 );
3962
3963 // starting source address = last line if we need to flip the image
3964 unsigned char *src = ( flip ) ? bgr + ( width * height * 3 ) + lineStep : bgr;
3965
3966 for ( unsigned int i = 0; i < height; i++ )
3967 {
3968 unsigned char *line = src;
3969 for ( unsigned int j = 0; j < width; j++ )
3970 {
3971 *grey++ = (unsigned char)( 0.2126 * *( line + 2 ) + 0.7152 * *( line + 1 ) + 0.0722 * *( line + 0 ) );
3972 line += 3;
3973 }
3974
3975 // go to the next line
3976 src += lineStep;
3977 }
3978 }
3979}
3980
3995void
3996vpImageConvert::BGRaToGrey( unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height,
3997 bool flip,
3998 unsigned int
3999#if defined _OPENMP
4000 nThreads
4001#endif
4002)
4003{
4004 if ( !flip )
4005 {
4006#if defined _OPENMP
4007 if ( nThreads > 0 )
4008 {
4009 omp_set_num_threads( static_cast< int >( nThreads ) );
4010 }
4011#pragma omp parallel for
4012#endif
4013 for ( int i = 0; i < static_cast< int >( height ); i++ )
4014 {
4015 SimdBgraToGray( bgra + i * width * 4, width, 1, width * 4, grey + i * width, width );
4016 }
4017 }
4018 else
4019 {
4020 // if we have to flip the image, we start from the end last scanline so
4021 // the step is negative
4022 int lineStep = ( flip ) ? -(int)( width * 4 ) : (int)( width * 4 );
4023
4024 // starting source address = last line if we need to flip the image
4025 unsigned char *src = ( flip ) ? bgra + ( width * height * 4 ) + lineStep : bgra;
4026
4027 for ( unsigned int i = 0; i < height; i++ )
4028 {
4029 unsigned char *line = src;
4030 for ( unsigned int j = 0; j < width; j++ )
4031 {
4032 *grey++ = (unsigned char)( 0.2126 * *( line + 2 ) + 0.7152 * *( line + 1 ) + 0.0722 * *( line + 0 ) );
4033 line += 4;
4034 }
4035
4036 // go to the next line
4037 src += lineStep;
4038 }
4039 }
4040}
4041
4045void
4046vpImageConvert::computeYCbCrLUT()
4047{
4048 if ( YCbCrLUTcomputed == false )
4049 {
4050 int index = 256;
4051
4052 while ( index-- )
4053 {
4054
4055 int aux = index - 128;
4056 vpImageConvert::vpCrr[index] = (int)( 364.6610 * aux ) >> 8;
4057 vpImageConvert::vpCgb[index] = (int)( -89.8779 * aux ) >> 8;
4058 vpImageConvert::vpCgr[index] = (int)( -185.8154 * aux ) >> 8;
4059 vpImageConvert::vpCbb[index] = (int)( 460.5724 * aux ) >> 8;
4060 }
4061
4062 YCbCrLUTcomputed = true;
4063 }
4064}
4065
4087void
4088vpImageConvert::YCbCrToRGB( unsigned char *ycbcr, unsigned char *rgb, unsigned int size )
4089{
4090 unsigned char *cbv;
4091 unsigned char *crv;
4092 unsigned char *pt_ycbcr = ycbcr;
4093 unsigned char *pt_rgb = rgb;
4094 cbv = pt_ycbcr + 1;
4095 crv = pt_ycbcr + 3;
4096
4097 vpImageConvert::computeYCbCrLUT();
4098
4099 int col = 0;
4100
4101 while ( size-- )
4102 {
4103 int val_r, val_g, val_b;
4104 if ( !( col++ % 2 ) )
4105 {
4106 cbv = pt_ycbcr + 1;
4107 crv = pt_ycbcr + 3;
4108 }
4109
4110 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4111 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4112 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4113
4114 vpDEBUG_TRACE( 5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b );
4115
4116 *pt_rgb++ = ( val_r < 0 ) ? 0u : ( ( val_r > 255 ) ? 255u : (unsigned char)val_r ); // Red component.
4117 *pt_rgb++ = ( val_g < 0 ) ? 0u : ( ( val_g > 255 ) ? 255u : (unsigned char)val_g ); // Green component.
4118 *pt_rgb++ = ( val_b < 0 ) ? 0u : ( ( val_b > 255 ) ? 255u : (unsigned char)val_b ); // Blue component.
4119
4120 pt_ycbcr += 2;
4121 }
4122}
4123
4149void
4150vpImageConvert::YCbCrToRGBa( unsigned char *ycbcr, unsigned char *rgba, unsigned int size )
4151{
4152 unsigned char *cbv;
4153 unsigned char *crv;
4154 unsigned char *pt_ycbcr = ycbcr;
4155 unsigned char *pt_rgba = rgba;
4156 cbv = pt_ycbcr + 1;
4157 crv = pt_ycbcr + 3;
4158
4159 vpImageConvert::computeYCbCrLUT();
4160
4161 int col = 0;
4162
4163 while ( size-- )
4164 {
4165 int val_r, val_g, val_b;
4166 if ( !( col++ % 2 ) )
4167 {
4168 cbv = pt_ycbcr + 1;
4169 crv = pt_ycbcr + 3;
4170 }
4171
4172 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4173 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4174 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4175
4176 vpDEBUG_TRACE( 5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b );
4177
4178 *pt_rgba++ = ( val_r < 0 ) ? 0u : ( ( val_r > 255 ) ? 255u : (unsigned char)val_r ); // Red component.
4179 *pt_rgba++ = ( val_g < 0 ) ? 0u : ( ( val_g > 255 ) ? 255u : (unsigned char)val_g ); // Green component.
4180 *pt_rgba++ = ( val_b < 0 ) ? 0u : ( ( val_b > 255 ) ? 255u : (unsigned char)val_b ); // Blue component.
4181 *pt_rgba++ = vpRGBa::alpha_default;
4182
4183 pt_ycbcr += 2;
4184 }
4185}
4186
4206void
4207vpImageConvert::YCbCrToGrey( unsigned char *ycbcr, unsigned char *grey, unsigned int size )
4208{
4209 unsigned int i = 0, j = 0;
4210
4211 while ( j < size * 2 )
4212 {
4213 grey[i++] = ycbcr[j];
4214 grey[i++] = ycbcr[j + 2];
4215 j += 4;
4216 }
4217}
4218
4240void
4241vpImageConvert::YCrCbToRGB( unsigned char *ycrcb, unsigned char *rgb, unsigned int size )
4242{
4243 unsigned char *cbv;
4244 unsigned char *crv;
4245 unsigned char *pt_ycbcr = ycrcb;
4246 unsigned char *pt_rgb = rgb;
4247 crv = pt_ycbcr + 1;
4248 cbv = pt_ycbcr + 3;
4249
4250 vpImageConvert::computeYCbCrLUT();
4251
4252 int col = 0;
4253
4254 while ( size-- )
4255 {
4256 int val_r, val_g, val_b;
4257 if ( !( col++ % 2 ) )
4258 {
4259 crv = pt_ycbcr + 1;
4260 cbv = pt_ycbcr + 3;
4261 }
4262
4263 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4264 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4265 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4266
4267 vpDEBUG_TRACE( 5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b );
4268
4269 *pt_rgb++ = ( val_r < 0 ) ? 0u : ( ( val_r > 255 ) ? 255u : (unsigned char)val_r ); // Red component.
4270 *pt_rgb++ = ( val_g < 0 ) ? 0u : ( ( val_g > 255 ) ? 255u : (unsigned char)val_g ); // Green component.
4271 *pt_rgb++ = ( val_b < 0 ) ? 0u : ( ( val_b > 255 ) ? 255u : (unsigned char)val_b ); // Blue component.
4272
4273 pt_ycbcr += 2;
4274 }
4275}
4276
4301void
4302vpImageConvert::YCrCbToRGBa( unsigned char *ycrcb, unsigned char *rgba, unsigned int size )
4303{
4304 unsigned char *cbv;
4305 unsigned char *crv;
4306 unsigned char *pt_ycbcr = ycrcb;
4307 unsigned char *pt_rgba = rgba;
4308 crv = pt_ycbcr + 1;
4309 cbv = pt_ycbcr + 3;
4310
4311 vpImageConvert::computeYCbCrLUT();
4312
4313 int col = 0;
4314
4315 while ( size-- )
4316 {
4317 int val_r, val_g, val_b;
4318 if ( !( col++ % 2 ) )
4319 {
4320 crv = pt_ycbcr + 1;
4321 cbv = pt_ycbcr + 3;
4322 }
4323
4324 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
4325 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
4326 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
4327
4328 vpDEBUG_TRACE( 5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b );
4329
4330 *pt_rgba++ = ( val_r < 0 ) ? 0u : ( ( val_r > 255 ) ? 255u : (unsigned char)val_r ); // Red component.
4331 *pt_rgba++ = ( val_g < 0 ) ? 0u : ( ( val_g > 255 ) ? 255u : (unsigned char)val_g ); // Green component.
4332 *pt_rgba++ = ( val_b < 0 ) ? 0u : ( ( val_b > 255 ) ? 255u : (unsigned char)val_b ); // Blue component.
4333 *pt_rgba++ = vpRGBa::alpha_default;
4334
4335 pt_ycbcr += 2;
4336 }
4337}
4338
4377void
4380{
4381 if ( src.getSize() > 0 )
4382 {
4383 if ( pR )
4384 {
4385 pR->resize( src.getHeight(), src.getWidth() );
4386 }
4387 if ( pG )
4388 {
4389 pG->resize( src.getHeight(), src.getWidth() );
4390 }
4391 if ( pB )
4392 {
4393 pB->resize( src.getHeight(), src.getWidth() );
4394 }
4395 if ( pa )
4396 {
4397 pa->resize( src.getHeight(), src.getWidth() );
4398 }
4399
4400 unsigned char *ptrR = pR ? pR->bitmap : new unsigned char[src.getSize()];
4401 unsigned char *ptrG = pG ? pG->bitmap : new unsigned char[src.getSize()];
4402 unsigned char *ptrB = pB ? pB->bitmap : new unsigned char[src.getSize()];
4403 unsigned char *ptrA = pa ? pa->bitmap : new unsigned char[src.getSize()];
4404
4405 SimdDeinterleaveBgra( reinterpret_cast< unsigned char * >( src.bitmap ), src.getWidth() * sizeof( vpRGBa ),
4406 src.getWidth(), src.getHeight(), ptrR, src.getWidth(), ptrG, src.getWidth(), ptrB,
4407 src.getWidth(), ptrA, src.getWidth() );
4408
4409 if ( !pR )
4410 {
4411 delete[] ptrR;
4412 }
4413 if ( !pG )
4414 {
4415 delete[] ptrG;
4416 }
4417 if ( !pB )
4418 {
4419 delete[] ptrB;
4420 }
4421 if ( !pa )
4422 {
4423 delete[] ptrA;
4424 }
4425 }
4426}
4427
4438void
4441{
4442 // Check if the input channels have all the same dimensions
4443 std::map< unsigned int, unsigned int > mapOfWidths, mapOfHeights;
4444 if ( R != NULL )
4445 {
4446 mapOfWidths[R->getWidth()]++;
4447 mapOfHeights[R->getHeight()]++;
4448 }
4449
4450 if ( G != NULL )
4451 {
4452 mapOfWidths[G->getWidth()]++;
4453 mapOfHeights[G->getHeight()]++;
4454 }
4455
4456 if ( B != NULL )
4457 {
4458 mapOfWidths[B->getWidth()]++;
4459 mapOfHeights[B->getHeight()]++;
4460 }
4461
4462 if ( a != NULL )
4463 {
4464 mapOfWidths[a->getWidth()]++;
4465 mapOfHeights[a->getHeight()]++;
4466 }
4467
4468 if ( mapOfWidths.size() == 1 && mapOfHeights.size() == 1 )
4469 {
4470 unsigned int width = mapOfWidths.begin()->first;
4471 unsigned int height = mapOfHeights.begin()->first;
4472
4473 RGBa.resize( height, width );
4474
4475 if ( R != NULL && G != NULL && B != NULL && a != NULL )
4476 {
4477 SimdInterleaveBgra( R->bitmap, width, G->bitmap, width, B->bitmap, width, a->bitmap, width, width, height,
4478 reinterpret_cast< uint8_t * >( RGBa.bitmap ), width * sizeof( vpRGBa ) );
4479 }
4480 else
4481 {
4482 unsigned int size = width * height;
4483 for ( unsigned int i = 0; i < size; i++ )
4484 {
4485 if ( R != NULL )
4486 {
4487 RGBa.bitmap[i].R = R->bitmap[i];
4488 }
4489
4490 if ( G != NULL )
4491 {
4492 RGBa.bitmap[i].G = G->bitmap[i];
4493 }
4494
4495 if ( B != NULL )
4496 {
4497 RGBa.bitmap[i].B = B->bitmap[i];
4498 }
4499
4500 if ( a != NULL )
4501 {
4502 RGBa.bitmap[i].A = a->bitmap[i];
4503 }
4504 }
4505 }
4506 }
4507 else
4508 {
4509 throw vpException( vpException::dimensionError, "Mismatched dimensions!" );
4510 }
4511}
4512
4523void
4524vpImageConvert::MONO16ToGrey( unsigned char *grey16, unsigned char *grey, unsigned int size )
4525{
4526 int i = ( ( (int)size ) << 1 ) - 1;
4527 int j = (int)size - 1;
4528
4529 while ( i >= 0 )
4530 {
4531 int y = grey16[i--];
4532 grey[j--] = static_cast< unsigned char >( ( y + ( grey16[i--] << 8 ) ) >> 8 );
4533 }
4534}
4535
4547void
4548vpImageConvert::MONO16ToRGBa( unsigned char *grey16, unsigned char *rgba, unsigned int size )
4549{
4550 int i = ( ( (int)size ) << 1 ) - 1;
4551 int j = (int)( size * 4 - 1 );
4552
4553 while ( i >= 0 )
4554 {
4555 int y = grey16[i--];
4556 unsigned char v = static_cast< unsigned char >( ( y + ( grey16[i--] << 8 ) ) >> 8 );
4557 rgba[j--] = vpRGBa::alpha_default;
4558 rgba[j--] = v;
4559 rgba[j--] = v;
4560 rgba[j--] = v;
4561 }
4562}
4563
4574void
4575vpImageConvert::HSV2RGB( const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
4576 unsigned int size, unsigned int step )
4577{
4578 for ( unsigned int i = 0; i < size; i++ )
4579 {
4580 double hue = hue_[i], saturation = saturation_[i], value = value_[i];
4581
4582 if ( vpMath::equal( saturation, 0.0, std::numeric_limits< double >::epsilon() ) )
4583 {
4584 hue = value;
4585 saturation = value;
4586 }
4587 else
4588 {
4589 double h = hue * 6.0;
4590 double s = saturation;
4591 double v = value;
4592
4593 if ( vpMath::equal( h, 6.0, std::numeric_limits< double >::epsilon() ) )
4594 {
4595 h = 0.0;
4596 }
4597
4598 double f = h - (int)h;
4599 double p = v * ( 1.0 - s );
4600 double q = v * ( 1.0 - s * f );
4601 double t = v * ( 1.0 - s * ( 1.0 - f ) );
4602
4603 switch ( (int)h )
4604 {
4605 case 0:
4606 hue = v;
4607 saturation = t;
4608 value = p;
4609 break;
4610
4611 case 1:
4612 hue = q;
4613 saturation = v;
4614 value = p;
4615 break;
4616
4617 case 2:
4618 hue = p;
4619 saturation = v;
4620 value = t;
4621 break;
4622
4623 case 3:
4624 hue = p;
4625 saturation = q;
4626 value = v;
4627 break;
4628
4629 case 4:
4630 hue = t;
4631 saturation = p;
4632 value = v;
4633 break;
4634
4635 default: // case 5:
4636 hue = v;
4637 saturation = p;
4638 value = q;
4639 break;
4640 }
4641 }
4642
4643 rgb[i * step] = (unsigned char)vpMath::round( hue * 255.0 );
4644 rgb[i * step + 1] = (unsigned char)vpMath::round( saturation * 255.0 );
4645 rgb[i * step + 2] = (unsigned char)vpMath::round( value * 255.0 );
4646 if ( step == 4 ) // alpha
4647 rgb[i * step + 3] = vpRGBa::alpha_default;
4648 }
4649}
4650
4661void
4662vpImageConvert::RGB2HSV( const unsigned char *rgb, double *hue, double *saturation, double *value, unsigned int size,
4663 unsigned int step )
4664{
4665 for ( unsigned int i = 0; i < size; i++ )
4666 {
4667 double red, green, blue;
4668 double h, s, v;
4669 double min, max;
4670
4671 red = rgb[i * step] / 255.0;
4672 green = rgb[i * step + 1] / 255.0;
4673 blue = rgb[i * step + 2] / 255.0;
4674
4675 if ( red > green )
4676 {
4677 max = ( ( std::max ) )( red, blue );
4678 min = ( ( std::min ) )( green, blue );
4679 }
4680 else
4681 {
4682 max = ( ( std::max ) )( green, blue );
4683 min = ( ( std::min ) )( red, blue );
4684 }
4685
4686 v = max;
4687
4688 if ( !vpMath::equal( max, 0.0, std::numeric_limits< double >::epsilon() ) )
4689 {
4690 s = ( max - min ) / max;
4691 }
4692 else
4693 {
4694 s = 0.0;
4695 }
4696
4697 if ( vpMath::equal( s, 0.0, std::numeric_limits< double >::epsilon() ) )
4698 {
4699 h = 0.0;
4700 }
4701 else
4702 {
4703 double delta = max - min;
4704 if ( vpMath::equal( delta, 0.0, std::numeric_limits< double >::epsilon() ) )
4705 {
4706 delta = 1.0;
4707 }
4708
4709 if ( vpMath::equal( red, max, std::numeric_limits< double >::epsilon() ) )
4710 {
4711 h = ( green - blue ) / delta;
4712 }
4713 else if ( vpMath::equal( green, max, std::numeric_limits< double >::epsilon() ) )
4714 {
4715 h = 2 + ( blue - red ) / delta;
4716 }
4717 else
4718 {
4719 h = 4 + ( red - green ) / delta;
4720 }
4721
4722 h /= 6.0;
4723 if ( h < 0.0 )
4724 {
4725 h += 1.0;
4726 }
4727 else if ( h > 1.0 )
4728 {
4729 h -= 1.0;
4730 }
4731 }
4732
4733 hue[i] = h;
4734 saturation[i] = s;
4735 value[i] = v;
4736 }
4737}
4738
4751void
4752vpImageConvert::HSVToRGBa( const double *hue, const double *saturation, const double *value, unsigned char *rgba,
4753 unsigned int size )
4754{
4755 vpImageConvert::HSV2RGB( hue, saturation, value, rgba, size, 4 );
4756}
4757
4770void
4771vpImageConvert::HSVToRGBa( const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4772 unsigned char *rgba, unsigned int size )
4773{
4774 for ( unsigned int i = 0; i < size; i++ )
4775 {
4776 double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4777
4778 vpImageConvert::HSVToRGBa( &h, &s, &v, ( rgba + i * 4 ), 1 );
4779 }
4780}
4781
4794void
4795vpImageConvert::RGBaToHSV( const unsigned char *rgba, double *hue, double *saturation, double *value,
4796 unsigned int size )
4797{
4798 vpImageConvert::RGB2HSV( rgba, hue, saturation, value, size, 4 );
4799}
4800
4812void
4813vpImageConvert::RGBaToHSV( const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
4814 unsigned char *value, unsigned int size )
4815{
4816 for ( unsigned int i = 0; i < size; i++ )
4817 {
4818 double h, s, v;
4819 vpImageConvert::RGBaToHSV( ( rgba + i * 4 ), &h, &s, &v, 1 );
4820
4821 hue[i] = (unsigned char)( 255.0 * h );
4822 saturation[i] = (unsigned char)( 255.0 * s );
4823 value[i] = (unsigned char)( 255.0 * v );
4824 }
4825}
4826
4837void
4838vpImageConvert::HSVToRGB( const double *hue, const double *saturation, const double *value, unsigned char *rgb,
4839 unsigned int size )
4840{
4841 vpImageConvert::HSV2RGB( hue, saturation, value, rgb, size, 3 );
4842}
4843
4854void
4855vpImageConvert::HSVToRGB( const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
4856 unsigned char *rgb, unsigned int size )
4857{
4858 for ( unsigned int i = 0; i < size; i++ )
4859 {
4860 double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
4861
4862 vpImageConvert::HSVToRGB( &h, &s, &v, ( rgb + i * 3 ), 1 );
4863 }
4864}
4865
4877void
4878vpImageConvert::RGBToHSV( const unsigned char *rgb, double *hue, double *saturation, double *value, unsigned int size )
4879{
4880 vpImageConvert::RGB2HSV( rgb, hue, saturation, value, size, 3 );
4881}
4882
4893void
4894vpImageConvert::RGBToHSV( const unsigned char *rgb, unsigned char *hue, unsigned char *saturation, unsigned char *value,
4895 unsigned int size )
4896{
4897 for ( unsigned int i = 0; i < size; i++ )
4898 {
4899 double h, s, v;
4900
4901 vpImageConvert::RGBToHSV( ( rgb + i * 3 ), &h, &s, &v, 1 );
4902
4903 hue[i] = (unsigned char)( 255.0 * h );
4904 saturation[i] = (unsigned char)( 255.0 * s );
4905 value[i] = (unsigned char)( 255.0 * v );
4906 }
4907}
4908
4909// Bilinear
4910
4923void
4924vpImageConvert::demosaicBGGRToRGBaBilinear( const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height,
4925 unsigned int nThreads )
4926{
4927 demosaicBGGRToRGBaBilinearTpl( bggr, rgba, width, height, nThreads );
4928}
4929
4942void
4943vpImageConvert::demosaicBGGRToRGBaBilinear( const uint16_t *bggr, uint16_t *rgba, unsigned int width,
4944 unsigned int height, unsigned int nThreads )
4945{
4946 demosaicBGGRToRGBaBilinearTpl( bggr, rgba, width, height, nThreads );
4947}
4948
4961void
4962vpImageConvert::demosaicGBRGToRGBaBilinear( const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height,
4963 unsigned int nThreads )
4964{
4965 demosaicGBRGToRGBaBilinearTpl( gbrg, rgba, width, height, nThreads );
4966}
4967
4980void
4981vpImageConvert::demosaicGBRGToRGBaBilinear( const uint16_t *gbrg, uint16_t *rgba, unsigned int width,
4982 unsigned int height, unsigned int nThreads )
4983{
4984 demosaicGBRGToRGBaBilinearTpl( gbrg, rgba, width, height, nThreads );
4985}
4986
4999void
5000vpImageConvert::demosaicGRBGToRGBaBilinear( const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height,
5001 unsigned int nThreads )
5002{
5003 demosaicGRBGToRGBaBilinearTpl( grbg, rgba, width, height, nThreads );
5004}
5005
5018void
5019vpImageConvert::demosaicGRBGToRGBaBilinear( const uint16_t *grbg, uint16_t *rgba, unsigned int width,
5020 unsigned int height, unsigned int nThreads )
5021{
5022 demosaicGRBGToRGBaBilinearTpl( grbg, rgba, width, height, nThreads );
5023}
5024
5037void
5038vpImageConvert::demosaicRGGBToRGBaBilinear( const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height,
5039 unsigned int nThreads )
5040{
5041 demosaicRGGBToRGBaBilinearTpl( rggb, rgba, width, height, nThreads );
5042}
5043
5056void
5057vpImageConvert::demosaicRGGBToRGBaBilinear( const uint16_t *rggb, uint16_t *rgba, unsigned int width,
5058 unsigned int height, unsigned int nThreads )
5059{
5060 demosaicRGGBToRGBaBilinearTpl( rggb, rgba, width, height, nThreads );
5061}
5062
5063// Malvar
5064
5077void
5078vpImageConvert::demosaicBGGRToRGBaMalvar( const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height,
5079 unsigned int nThreads )
5080{
5081 demosaicBGGRToRGBaMalvarTpl( bggr, rgba, width, height, nThreads );
5082}
5083
5096void
5097vpImageConvert::demosaicBGGRToRGBaMalvar( const uint16_t *bggr, uint16_t *rgba, unsigned int width, unsigned int height,
5098 unsigned int nThreads )
5099{
5100 demosaicBGGRToRGBaMalvarTpl( bggr, rgba, width, height, nThreads );
5101}
5102
5115void
5116vpImageConvert::demosaicGBRGToRGBaMalvar( const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height,
5117 unsigned int nThreads )
5118{
5119 demosaicGBRGToRGBaMalvarTpl( gbrg, rgba, width, height, nThreads );
5120}
5121
5134void
5135vpImageConvert::demosaicGBRGToRGBaMalvar( const uint16_t *gbrg, uint16_t *rgba, unsigned int width, unsigned int height,
5136 unsigned int nThreads )
5137{
5138 demosaicGBRGToRGBaMalvarTpl( gbrg, rgba, width, height, nThreads );
5139}
5140
5153void
5154vpImageConvert::demosaicGRBGToRGBaMalvar( const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height,
5155 unsigned int nThreads )
5156{
5157 demosaicGRBGToRGBaMalvarTpl( grbg, rgba, width, height, nThreads );
5158}
5159
5172void
5173vpImageConvert::demosaicGRBGToRGBaMalvar( const uint16_t *grbg, uint16_t *rgba, unsigned int width, unsigned int height,
5174 unsigned int nThreads )
5175{
5176 demosaicGRBGToRGBaMalvarTpl( grbg, rgba, width, height, nThreads );
5177}
5178
5191void
5192vpImageConvert::demosaicRGGBToRGBaMalvar( const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height,
5193 unsigned int nThreads )
5194{
5195 demosaicRGGBToRGBaMalvarTpl( rggb, rgba, width, height, nThreads );
5196}
5197
5210void
5211vpImageConvert::demosaicRGGBToRGBaMalvar( const uint16_t *rggb, uint16_t *rgba, unsigned int width, unsigned int height,
5212 unsigned int nThreads )
5213{
5214 demosaicRGGBToRGBaMalvarTpl( rggb, rgba, width, height, nThreads );
5215}
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ dimensionError
Bad dimension.
Definition: vpException.h:95
static void YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, unsigned int size)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
static void demosaicBGGRToRGBaBilinear(const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void demosaicGRBGToRGBaBilinear(const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
static void RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value, unsigned int size)
static void demosaicGRBGToRGBaMalvar(const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
static void YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void demosaicGBRGToRGBaMalvar(const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
static void YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void demosaicBGGRToRGBaMalvar(const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
static void demosaicGBRGToRGBaBilinear(const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
static void YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
static void YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, unsigned int size)
static void demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
static void YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
static void YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void demosaicRGGBToRGBaBilinear(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
static void YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb, unsigned int size)
static void YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
unsigned int getWidth() const
Definition: vpImage.h:246
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:938
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:800
unsigned int getSize() const
Definition: vpImage.h:227
unsigned int getCols() const
Definition: vpImage.h:179
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
unsigned int getHeight() const
Definition: vpImage.h:188
unsigned int getRows() const
Definition: vpImage.h:218
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:295
static int round(double x)
Definition: vpMath.h:247
Definition: vpRGBa.h:67
unsigned char B
Blue component.
Definition: vpRGBa.h:150
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned char G
Green component.
Definition: vpRGBa.h:149
@ alpha_default
Definition: vpRGBa.h:69
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
#define vpDEBUG_TRACE
Definition: vpDebug.h:487