Visual Servoing Platform  version 3.0.0
vpImageConvert.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Convert image types.
32  *
33  * Authors:
34  * Eric Marchand
35  * Fabien Spindler
36  * Anthony Saunier
37  *
38  *****************************************************************************/
39 
46 #include <sstream>
47 #include <map>
48 
49 // image
50 #include <visp3/core/vpImageConvert.h>
51 
52 bool vpImageConvert::YCbCrLUTcomputed = false;
53 int vpImageConvert::vpCrr[256];
54 int vpImageConvert::vpCgb[256];
55 int vpImageConvert::vpCgr[256];
56 int vpImageConvert::vpCbb[256];
57 
58 
64 void
66 {
67  dest.resize(src.getHeight(), src.getWidth()) ;
68 
69  GreyToRGBa(src.bitmap, (unsigned char *)dest.bitmap,
70  src.getHeight() * src.getWidth() );
71 }
72 
78 void
80 {
81  dest.resize(src.getHeight(), src.getWidth()) ;
82 
83  RGBaToGrey((unsigned char *)src.bitmap, dest.bitmap,
84  src.getHeight() * src.getWidth() );
85 }
86 
87 
93 void
95 {
96  dest.resize(src.getHeight(), src.getWidth()) ;
97  unsigned int max_xy = src.getWidth()*src.getHeight();
98  float min, max;
99 
100  src.getMinMaxValue(min,max);
101 
102  for (unsigned int i = 0; i < max_xy; i++) {
103  float val = 255.f * (src.bitmap[i] - min) / (max - min);
104  if(val < 0)
105  dest.bitmap[i] = 0;
106  else if(val > 255)
107  dest.bitmap[i] = 255;
108  else
109  dest.bitmap[i] = (unsigned char)val;
110  }
111 }
112 
118 void
120 {
121  dest.resize(src.getHeight(), src.getWidth()) ;
122  for (unsigned int i = 0; i < src.getHeight()*src.getWidth(); i++)
123  dest.bitmap[i] = (float)src.bitmap[i];
124 }
125 
131 void
133 {
134  dest.resize(src.getHeight(), src.getWidth()) ;
135  unsigned int max_xy = src.getWidth()*src.getHeight();
136  double min, max;
137 
138  src.getMinMaxValue(min,max);
139 
140  for (unsigned int i = 0; i < max_xy; i++) {
141  double val = 255. * (src.bitmap[i] - min) / (max - min);
142  if(val < 0)
143  dest.bitmap[i] = 0;
144  else if(val > 255)
145  dest.bitmap[i] = 255;
146  else
147  dest.bitmap[i] = (unsigned char)val;
148  }
149 }
150 
156 void
158 {
159  dest.resize(src.getHeight(), src.getWidth()) ;
160  for (unsigned int i = 0; i < src.getHeight()*src.getWidth(); i++)
161  dest.bitmap[i] = (double)src.bitmap[i];
162 }
163 
164 #ifdef VISP_HAVE_OPENCV
165 // Deprecated: will be removed with OpenCV transcient from C to C++ api
209 void
210 vpImageConvert::convert(const IplImage* src, vpImage<vpRGBa> & dest, bool flip)
211 {
212  int nChannel = src->nChannels;
213  int depth = src->depth;
214  int height = src->height;
215  int width = src->width;
216  int widthStep = src->widthStep;
217  int lineStep = (flip) ? 1 : 0;
218 
219  if(nChannel == 3 && depth == 8){
220  dest.resize((unsigned int)height, (unsigned int)width);
221 
222  //starting source address
223  unsigned char* input = (unsigned char*)src->imageData;
224  unsigned char* line;
225  unsigned char* beginOutput = (unsigned char*)dest.bitmap;
226  unsigned char* output = NULL;
227 
228  for(int i=0 ; i < height ; i++)
229  {
230  line = input;
231  output = beginOutput + lineStep * ( 4 * width * ( height - 1 - i ) ) + (1-lineStep) * 4 * width * i;
232  for(int j=0 ; j < width ; j++)
233  {
234  *(output++) = *(line+2);
235  *(output++) = *(line+1);
236  *(output++) = *(line);
237  *(output++) = 0;
238 
239  line+=3;
240  }
241  //go to the next line
242  input+=widthStep;
243  }
244  }
245  else if(nChannel == 1 && depth == 8 ){
246  dest.resize((unsigned int)height, (unsigned int)width);
247  //starting source address
248  unsigned char * input = (unsigned char*)src->imageData;
249  unsigned char * line;
250  unsigned char* beginOutput = (unsigned char*)dest.bitmap;
251  unsigned char* output = NULL;
252 
253  for(int i=0 ; i < height ; i++)
254  {
255  line = input;
256  output = beginOutput + lineStep * ( 4 * width * ( height - 1 - i ) ) + (1-lineStep) * 4 * width * i;
257  for(int j=0 ; j < width ; j++)
258  {
259  *output++ = *(line);
260  *output++ = *(line);
261  *output++ = *(line);
262  *output++ = *(line);;
263 
264  line++;
265  }
266  //go to the next line
267  input+=widthStep;
268  }
269  }
270 }
271 
315 void
316 vpImageConvert::convert(const IplImage* src, vpImage<unsigned char> &dest, bool flip)
317 {
318  int nChannel = src->nChannels;
319  int depth = src->depth;
320  int height = src->height;
321  int width = src->width;
322  int widthStep = src->widthStep;
323  int lineStep = (flip) ? 1 : 0;
324 
325  if (flip == false)
326  {
327  if(widthStep == width){
328  if(nChannel == 1 && depth == 8){
329  dest.resize((unsigned int)height, (unsigned int)width) ;
330  memcpy(dest.bitmap, src->imageData,
331  (size_t)(height*width));
332  }
333  if(nChannel == 3 && depth == 8){
334  dest.resize((unsigned int)height, (unsigned int)width) ;
335  BGRToGrey((unsigned char*)src->imageData,dest.bitmap, (unsigned int)width, (unsigned int)height,false);
336  }
337  }
338  else{
339  if(nChannel == 1 && depth == 8){
340  dest.resize((unsigned int)height, (unsigned int)width) ;
341  for (int i =0 ; i < height ; i++){
342  memcpy(dest.bitmap+i*width, src->imageData + i*widthStep,
343  (size_t)width);
344  }
345  }
346  if(nChannel == 3 && depth == 8){
347  dest.resize((unsigned int)height, (unsigned int)width) ;
348  for (int i = 0 ; i < height ; i++){
349  BGRToGrey((unsigned char*)src->imageData + i*widthStep,
350  dest.bitmap + i*width, (unsigned int)width, 1, false);
351  }
352  }
353  }
354  }
355  else
356  {
357  if(nChannel == 1 && depth == 8){
358  dest.resize((unsigned int)height, (unsigned int)width) ;
359  unsigned char* beginOutput = (unsigned char*)dest.bitmap;
360  for (int i =0 ; i < height ; i++){
361  memcpy(beginOutput + lineStep * ( 4 * width * ( height - 1 - i ) ) , src->imageData + i*widthStep,
362  (size_t)width);
363  }
364  }
365  if(nChannel == 3 && depth == 8){
366  dest.resize((unsigned int)height, (unsigned int)width) ;
367  //for (int i = 0 ; i < height ; i++){
368  BGRToGrey((unsigned char*)src->imageData /*+ i*widthStep*/,
369  dest.bitmap /*+ i*width*/, (unsigned int)width, (unsigned int)height/*1*/, true);
370  //}
371  }
372  }
373 }
374 
419 void
420 vpImageConvert::convert(const vpImage<vpRGBa> & src, IplImage *&dest)
421 {
422  int height = (int)src.getHeight();
423  int width = (int)src.getWidth();
424  CvSize size = cvSize(width, height);
425  int depth = 8;
426  int channels = 3;
427  if (dest != NULL){
428  if(dest->nChannels != channels || dest->depth != depth
429  || dest->height != height || dest->width != width){
430  if(dest->nChannels != 0) cvReleaseImage(&dest);
431  dest = cvCreateImage( size, depth, channels );
432  }
433  }
434  else dest = cvCreateImage( size, depth, channels );
435 
436 
437  //starting source address
438  unsigned char * input = (unsigned char*)src.bitmap;//rgba image
439  unsigned char * line;
440  unsigned char * output = (unsigned char*)dest->imageData;//bgr image
441 
442  int j=0;
443  int i=0;
444  int widthStep = dest->widthStep;
445 
446  for(i=0 ; i < height ; i++)
447  {
448  output = (unsigned char*)dest->imageData + i*widthStep;
449  line = input;
450  for( j=0 ; j < width ; j++)
451  {
452  *output++ = *(line+2); //B
453  *output++ = *(line+1); //G
454  *output++ = *(line); //R
455 
456  line+=4;
457  }
458  //go to the next line
459  input+=4*width;
460  }
461 }
462 
507 void
508 vpImageConvert::convert(const vpImage<unsigned char> & src, IplImage* &dest)
509 {
510  unsigned int height = src.getHeight();
511  unsigned int width = src.getWidth();
512  CvSize size = cvSize((int)width, (int)height);
513  int depth = 8;
514  int channels = 1;
515  if (dest != NULL){
516  if(dest->nChannels != channels || dest->depth != depth
517  || dest->height != (int) height || dest->width != (int) width){
518  if(dest->nChannels != 0) cvReleaseImage(&dest);
519  dest = cvCreateImage( size, depth, channels );
520  }
521  }
522  else dest = cvCreateImage( size, depth, channels );
523 
524  unsigned int widthStep = (unsigned int)dest->widthStep;
525 
526  if ( width == widthStep){
527  memcpy(dest->imageData,src.bitmap, width*height);
528  }
529  else{
530  //copying each line taking account of the widthStep
531  for (unsigned int i =0 ; i < height ; i++){
532  memcpy(dest->imageData + i*widthStep, src.bitmap + i*width,
533  width);
534  }
535  }
536 }
537 
538 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
539 
581 void
582 vpImageConvert::convert(const cv::Mat& src, vpImage<vpRGBa>& dest, const bool flip)
583 {
584  if(src.type() == CV_8UC4){
585  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
586  vpRGBa rgbaVal;
587  for(unsigned int i=0; i<dest.getRows(); ++i)
588  for(unsigned int j=0; j<dest.getCols(); ++j){
589  cv::Vec4b tmp = src.at<cv::Vec4b>((int)i, (int)j);
590  rgbaVal.R = tmp[2];
591  rgbaVal.G = tmp[1];
592  rgbaVal.B = tmp[0];
593  rgbaVal.A = tmp[3];
594  if(flip)
595  dest[dest.getRows()-i-1][j] = rgbaVal;
596  else
597  dest[i][j] = rgbaVal;
598  }
599  }else if(src.type() == CV_8UC3){
600  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
601  vpRGBa rgbaVal;
602  rgbaVal.A = 0;
603  for(unsigned int i=0; i<dest.getRows(); ++i){
604  for(unsigned int j=0; j<dest.getCols(); ++j){
605  cv::Vec3b tmp = src.at<cv::Vec3b>((int)i, (int)j);
606  rgbaVal.R = tmp[2];
607  rgbaVal.G = tmp[1];
608  rgbaVal.B = tmp[0];
609  if(flip){
610  dest[dest.getRows()-i-1][j] = rgbaVal;
611  }else{
612  dest[i][j] = rgbaVal;
613  }
614  }
615  }
616  }else if(src.type() == CV_8UC1){
617  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
618  vpRGBa rgbaVal;
619  for(unsigned int i=0; i<dest.getRows(); ++i){
620  for(unsigned int j=0; j<dest.getCols(); ++j){
621  rgbaVal = src.at<unsigned char>((int)i, (int)j);
622  if(flip){
623  dest[dest.getRows()-i-1][j] = rgbaVal;
624  }else{
625  dest[i][j] = rgbaVal;
626  }
627  }
628  }
629  }
630 }
631 
674 void
675 vpImageConvert::convert(const cv::Mat& src, vpImage<unsigned char>& dest, const bool flip)
676 {
677  if(src.type() == CV_8UC1){
678  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
679  if(src.isContinuous() && !flip){
680  memcpy(dest.bitmap, src.data, (size_t)(src.rows*src.cols));
681  }
682  else{
683  if(flip){
684  for(unsigned int i=0; i<dest.getRows(); ++i){
685  memcpy(dest.bitmap+i*dest.getCols(), src.data+(dest.getRows()-i-1)*src.step1(), (size_t)src.step);
686  }
687  }else{
688  for(unsigned int i=0; i<dest.getRows(); ++i){
689  memcpy(dest.bitmap+i*dest.getCols(), src.data+i*src.step1(), (size_t)src.step);
690  }
691  }
692  }
693  }else if(src.type() == CV_8UC3){
694  dest.resize((unsigned int)src.rows, (unsigned int)src.cols);
695  if(src.isContinuous() && !flip){
696  BGRToGrey((unsigned char*)src.data, (unsigned char*)dest.bitmap, (unsigned int)src.cols, (unsigned int)src.rows, flip);
697  }
698  else{
699  if(flip){
700  for(unsigned int i=0; i<dest.getRows(); ++i){
701  BGRToGrey((unsigned char*)src.data+i*src.step1(),
702  (unsigned char*)dest.bitmap+(dest.getRows()-i-1)*dest.getCols(),
703  (unsigned int)dest.getCols(), 1, false);
704  }
705  }else{
706  for(unsigned int i=0; i<dest.getRows(); ++i){
707  BGRToGrey((unsigned char*)src.data+i*src.step1(),
708  (unsigned char*)dest.bitmap+i*dest.getCols(),
709  (unsigned int)dest.getCols(), 1, false);
710  }
711  }
712  }
713  }
714 }
715 
716 
756 void
757 vpImageConvert::convert(const vpImage<vpRGBa> & src, cv::Mat& dest)
758 {
759  cv::Mat vpToMat((int)src.getRows(), (int)src.getCols(), CV_8UC4, (void*)src.bitmap);
760 
761  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC3);
762  cv::Mat alpha((int)src.getRows(), (int)src.getCols(), CV_8UC1);
763 
764  cv::Mat out[] = {dest, alpha};
765  int from_to[] = { 0,2, 1,1, 2,0, 3,3 };
766  cv::mixChannels(&vpToMat, 1, out, 2, from_to, 4);
767 }
768 
810 void
811 vpImageConvert::convert(const vpImage<unsigned char> & src, cv::Mat& dest, const bool copyData)
812 {
813  if(copyData){
814  cv::Mat tmpMap((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void*)src.bitmap);
815  dest = tmpMap.clone();
816  }else{
817  dest = cv::Mat((int)src.getRows(), (int)src.getCols(), CV_8UC1, (void*)src.bitmap);
818  }
819 }
820 
821 #endif
822 #endif
823 
824 #ifdef VISP_HAVE_YARP
825 
858  yarp::sig::ImageOf< yarp::sig::PixelMono > *dest, const bool copyData)
859 {
860  if(copyData)
861  {
862  dest->resize(src.getWidth(),src.getHeight());
863  memcpy(dest->getRawImage(), src.bitmap, src.getHeight()*src.getWidth());
864  }
865  else
866  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
867 }
868 
905 void vpImageConvert::convert(const yarp::sig::ImageOf< yarp::sig::PixelMono > *src,
906  vpImage<unsigned char> & dest,const bool copyData)
907 {
908  dest.resize(src->height(),src->width());
909  if(copyData)
910  memcpy(dest.bitmap, src->getRawImage(), src->height()*src->width()*sizeof(yarp::sig::PixelMono));
911  else
912  dest.bitmap = src->getRawImage();
913 }
914 
949  yarp::sig::ImageOf< yarp::sig::PixelRgba > *dest, const bool copyData)
950 {
951  if(copyData){
952  dest->resize(src.getWidth(),src.getHeight());
953  memcpy(dest->getRawImage(), src.bitmap, src.getHeight()*src.getWidth()*sizeof(vpRGBa));
954  }
955  else
956  dest->setExternal(src.bitmap, (int)src.getCols(), (int)src.getRows());
957 }
958 
996 void vpImageConvert::convert(const yarp::sig::ImageOf< yarp::sig::PixelRgba > *src,
997  vpImage<vpRGBa> & dest,const bool copyData)
998 {
999  dest.resize(src->height(),src->width());
1000  if(copyData)
1001  memcpy(dest.bitmap, src->getRawImage(),src->height()*src->width()*sizeof(yarp::sig::PixelRgba));
1002  else
1003  dest.bitmap = (vpRGBa*)src->getRawImage();
1004 }
1005 
1038 void vpImageConvert::convert(const vpImage<vpRGBa> & src, yarp::sig::ImageOf< yarp::sig::PixelRgb > *dest)
1039 {
1040  dest->resize(src.getWidth(),src.getHeight());
1041  for(unsigned int i = 0 ; i < src.getRows() ; i++){
1042  for(unsigned int j = 0 ; j < src.getWidth() ; j++){
1043  dest->pixel(j,i).r = src[i][j].R;
1044  dest->pixel(j,i).g = src[i][j].G;
1045  dest->pixel(j,i).b = src[i][j].B;
1046  }
1047  }
1048 }
1049 
1086 void vpImageConvert::convert(const yarp::sig::ImageOf< yarp::sig::PixelRgb > *src, vpImage<vpRGBa> & dest)
1087 {
1088  dest.resize(src->height(),src->width());
1089  for(int i = 0 ; i < src->height() ; i++){
1090  for(int j = 0 ; j < src->width() ; j++){
1091  dest[i][j].R = src->pixel(j,i).r;
1092  dest[i][j].G = src->pixel(j,i).g;
1093  dest[i][j].B = src->pixel(j,i).b;
1094  dest[i][j].A = 0;
1095  }
1096  }
1097 }
1098 
1099 #endif
1100 
1101 #define vpSAT(c) \
1102  if (c & (~255)) { if (c < 0) c = 0; else c = 255; }
1103 
1109 void vpImageConvert::YUYVToRGBa(unsigned char* yuyv, unsigned char* rgba,
1110  unsigned int width, unsigned int height)
1111 {
1112  unsigned char *s;
1113  unsigned char *d;
1114  int w, h, c;
1115  int r, g, b, cr, cg, cb, y1, y2;
1116 
1117  h = (int)height;
1118  w = (int)width;
1119  s = yuyv;
1120  d = rgba;
1121  while (h--) {
1122  c = w >> 1;
1123  while (c--) {
1124  y1 = *s++;
1125  cb = ((*s - 128) * 454) >> 8;
1126  cg = (*s++ - 128) * 88;
1127  y2 = *s++;
1128  cr = ((*s - 128) * 359) >> 8;
1129  cg = (cg + (*s++ - 128) * 183) >> 8;
1130 
1131  r = y1 + cr;
1132  b = y1 + cb;
1133  g = y1 - cg;
1134  vpSAT(r);
1135  vpSAT(g);
1136  vpSAT(b);
1137 
1138  *d++ = static_cast<unsigned char>(r);
1139  *d++ = static_cast<unsigned char>(g);
1140  *d++ = static_cast<unsigned char>(b);
1141  *d++ = 0;
1142 
1143  r = y2 + cr;
1144  b = y2 + cb;
1145  g = y2 - cg;
1146  vpSAT(r);
1147  vpSAT(g);
1148  vpSAT(b);
1149 
1150  *d++ = static_cast<unsigned char>(r);
1151  *d++ = static_cast<unsigned char>(g);
1152  *d++ = static_cast<unsigned char>(b);
1153  *d++ = 0;
1154 
1155  }
1156  }
1157 }
1165 void vpImageConvert::YUYVToRGB(unsigned char* yuyv, unsigned char* rgb,
1166  unsigned int width, unsigned int height)
1167 {
1168  unsigned char *s;
1169  unsigned char *d;
1170  int h, w, c;
1171  int r, g, b, cr, cg, cb, y1, y2;
1172 
1173  h = (int)height;
1174  w = (int)width;
1175  s = yuyv;
1176  d = rgb;
1177  while (h--) {
1178  c = w >> 1;
1179  while (c--) {
1180  y1 = *s++;
1181  cb = ((*s - 128) * 454) >> 8;
1182  cg = (*s++ - 128) * 88;
1183  y2 = *s++;
1184  cr = ((*s - 128) * 359) >> 8;
1185  cg = (cg + (*s++ - 128) * 183) >> 8;
1186 
1187  r = y1 + cr;
1188  b = y1 + cb;
1189  g = y1 - cg;
1190  vpSAT(r);
1191  vpSAT(g);
1192  vpSAT(b);
1193 
1194  *d++ = static_cast<unsigned char>(r);
1195  *d++ = static_cast<unsigned char>(g);
1196  *d++ = static_cast<unsigned char>(b);
1197 
1198  r = y2 + cr;
1199  b = y2 + cb;
1200  g = y2 - cg;
1201  vpSAT(r);
1202  vpSAT(g);
1203  vpSAT(b);
1204 
1205  *d++ = static_cast<unsigned char>(r);
1206  *d++ = static_cast<unsigned char>(g);
1207  *d++ = static_cast<unsigned char>(b);
1208  }
1209  }
1210 }
1218 void vpImageConvert::YUYVToGrey(unsigned char* yuyv, unsigned char* grey, unsigned int size)
1219 {
1220  unsigned int i=0,j=0;
1221 
1222  while( j < size*2)
1223  {
1224  grey[i++] = yuyv[j];
1225  grey[i++] = yuyv[j+2];
1226  j+=4;
1227  }
1228 }
1229 
1230 
1237 void vpImageConvert::YUV411ToRGBa(unsigned char* yuv, unsigned char* rgba, unsigned int size)
1238 {
1239 #if 1
1240  // std::cout << "call optimized ConvertYUV411ToRGBa()" << std::endl;
1241  register int U, V, R, G, B, V2, U5, UV;
1242  register int Y0, Y1, Y2, Y3;
1243  for(unsigned int i = size / 4; i; i--) {
1244  U = (int)((*yuv++ - 128) * 0.354);
1245  U5 = 5*U;
1246  Y0 = *yuv++;
1247  Y1 = *yuv++;
1248  V = (int)((*yuv++ - 128) * 0.707);
1249  V2 = 2*V;
1250  Y2 = *yuv++;
1251  Y3 = *yuv++;
1252  UV = - U - V;
1253 
1254  // Original equations
1255  // R = Y + 1.402 V
1256  // G = Y - 0.344 U - 0.714 V
1257  // B = Y + 1.772 U
1258  R = Y0 + V2;
1259  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1260 
1261  G = Y0 + UV;
1262  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1263 
1264  B = Y0 + U5;
1265  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1266 
1267  *rgba++ = (unsigned char)R;
1268  *rgba++ = (unsigned char)G;
1269  *rgba++ = (unsigned char)B;
1270  rgba++;
1271 
1272  //---
1273  R = Y1 + V2;
1274  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1275 
1276  G = Y1 + UV;
1277  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1278 
1279  B = Y1 + U5;
1280  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1281 
1282  *rgba++ = (unsigned char)R;
1283  *rgba++ = (unsigned char)G;
1284  *rgba++ = (unsigned char)B;
1285  rgba++;
1286 
1287  //---
1288  R = Y2 + V2;
1289  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1290 
1291  G = Y2 + UV;
1292  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1293 
1294  B = Y2 + U5;
1295  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1296 
1297  *rgba++ = (unsigned char)R;
1298  *rgba++ = (unsigned char)G;
1299  *rgba++ = (unsigned char)B;
1300  rgba++;
1301 
1302  //---
1303  R = Y3 + V2;
1304  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1305 
1306  G = Y3 + UV;
1307  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1308 
1309  B = Y3 + U5;
1310  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1311 
1312  *rgba++ = (unsigned char)R;
1313  *rgba++ = (unsigned char)G;
1314  *rgba++ = (unsigned char)B;
1315  rgba++;
1316  }
1317 #else
1318  // tres tres lent ....
1319  unsigned int i=0,j=0;
1320  unsigned char r, g, b;
1321  while( j < numpixels*3/2)
1322  {
1323 
1324  YUVToRGB (yuv[j+1], yuv[j], yuv[j+3], r, g, b);
1325  rgba[i] = r;
1326  rgba[i+1] = g;
1327  rgba[i+2] = b;
1328  rgba[i+3] = 0;
1329  i+=4;
1330 
1331  YUVToRGB (yuv[j+2], yuv[j], yuv[j+3], r, g, b);
1332  rgba[i] = r;
1333  rgba[i+1] = g;
1334  rgba[i+2] = b;
1335  rgba[i+3] = 0;
1336  i+=4;
1337 
1338  YUVToRGB (yuv[j+4], yuv[j], yuv[j+3], r, g, b);
1339  rgba[i] = r;
1340  rgba[i+1] = g;
1341  rgba[i+2] = b;
1342  rgba[i+3] = 0;
1343  i+=4;
1344 
1345  YUVToRGB (yuv[j+5], yuv[j], yuv[j+3], r, g, b);
1346  rgba[i] = r;
1347  rgba[i+1] = g;
1348  rgba[i+2] = b;
1349  rgba[i+3] = 0;
1350  i+=4;
1351 
1352  j+=6;
1353  }
1354 #endif
1355 
1356 }
1357 
1364 void vpImageConvert::YUV422ToRGBa(unsigned char* yuv, unsigned char* rgba, unsigned int size)
1365 {
1366 
1367 #if 1
1368  // std::cout << "call optimized convertYUV422ToRGBa()" << std::endl;
1369  register int U, V, R, G, B, V2, U5, UV;
1370  register int Y0, Y1;
1371  for( unsigned int i = size / 2; i; i-- ) {
1372  U = (int)((*yuv++ - 128) * 0.354);
1373  U5 = 5*U;
1374  Y0 = *yuv++;
1375  V = (int)((*yuv++ - 128) * 0.707);
1376  V2 = 2*V;
1377  Y1 = *yuv++;
1378  UV = - U - V;
1379 
1380  //---
1381  R = Y0 + V2;
1382  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1383 
1384  G = Y0 + UV;
1385  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1386 
1387  B = Y0 + U5;
1388  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1389 
1390  *rgba++ = (unsigned char)R;
1391  *rgba++ = (unsigned char)G;
1392  *rgba++ = (unsigned char)B;
1393  rgba++;
1394 
1395  //---
1396  R = Y1 + V2;
1397  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1398 
1399  G = Y1 + UV;
1400  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1401 
1402  B = Y1 + U5;
1403  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1404 
1405  *rgba++ = (unsigned char)R;
1406  *rgba++ = (unsigned char)G;
1407  *rgba++ = (unsigned char)B;
1408  rgba++;
1409  }
1410 
1411 #else
1412  // tres tres lent ....
1413  unsigned int i=0,j=0;
1414  unsigned char r, g, b;
1415 
1416  while( j < size*2)
1417  {
1418 
1419  YUVToRGB (yuv[j+1], yuv[j], yuv[j+2], r, g, b);
1420  rgba[i] = r;
1421  rgba[i+1] = g;
1422  rgba[i+2] = b;
1423  rgba[i+3] = 0;
1424  i+=4;
1425 
1426  YUVToRGB (yuv[j+3], yuv[j], yuv[j+2], r, g, b);
1427  rgba[i] = r;
1428  rgba[i+1] = g;
1429  rgba[i+2] = b;
1430  rgba[i+3] = 0;
1431  i+=4;
1432  j+=4;
1433 
1434  }
1435 #endif
1436 }
1437 
1444 void vpImageConvert::YUV411ToGrey(unsigned char* yuv, unsigned char* grey, unsigned int size)
1445 {
1446  unsigned int i=0,j=0;
1447  while( j < size*3/2)
1448  {
1449 
1450  grey[i ] = yuv[j+1];
1451  grey[i+1] = yuv[j+2];
1452  grey[i+2] = yuv[j+4];
1453  grey[i+3] = yuv[j+5];
1454 
1455  i+=4;
1456 
1457  j+=6;
1458  }
1459 }
1460 
1469 void vpImageConvert::YUV422ToRGB(unsigned char* yuv, unsigned char* rgb, unsigned int size)
1470 {
1471 #if 1
1472  // std::cout << "call optimized convertYUV422ToRGB()" << std::endl;
1473  register int U, V, R, G, B, V2, U5, UV;
1474  register int Y0, Y1;
1475  for( unsigned int i = size / 2; i; i-- ) {
1476  U = (int)((*yuv++ - 128) * 0.354);
1477  U5 = 5*U;
1478  Y0 = *yuv++;
1479  V = (int)((*yuv++ - 128) * 0.707);
1480  V2 = 2*V;
1481  Y1 = *yuv++;
1482  UV = - U - V;
1483 
1484  //---
1485  R = Y0 + V2;
1486  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1487 
1488  G = Y0 + UV;
1489  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1490 
1491  B = Y0 + U5;
1492  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1493 
1494  *rgb++ = (unsigned char)R;
1495  *rgb++ = (unsigned char)G;
1496  *rgb++ = (unsigned char)B;
1497 
1498  //---
1499  R = Y1 + V2;
1500  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1501 
1502  G = Y1 + UV;
1503  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1504 
1505  B = Y1 + U5;
1506  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1507 
1508  *rgb++ = (unsigned char)R;
1509  *rgb++ = (unsigned char)G;
1510  *rgb++ = (unsigned char)B;
1511 
1512  }
1513 
1514 #else
1515  // tres tres lent ....
1516  unsigned int i=0,j=0;
1517  unsigned char r, g, b;
1518 
1519  while( j < size*2)
1520  {
1521 
1522  YUVToRGB (yuv[j+1], yuv[j], yuv[j+2], r, g, b);
1523  rgb[i] = r;
1524  rgb[i+1] = g;
1525  rgb[i+2] = b;
1526  i+=3;
1527 
1528  YUVToRGB (yuv[j+3], yuv[j], yuv[j+2], r, g, b);
1529  rgb[i] = r;
1530  rgb[i+1] = g;
1531  rgb[i+2] = b;
1532  i+=3;
1533  j+=4;
1534 
1535  }
1536 #endif
1537 }
1538 
1547 void vpImageConvert::YUV422ToGrey(unsigned char* yuv, unsigned char* grey, unsigned int size)
1548 {
1549  unsigned int i=0,j=0;
1550 
1551  while( j < size*2)
1552  {
1553  grey[i++] = yuv[j+1];
1554  grey[i++] = yuv[j+3];
1555  j+=4;
1556  }
1557 }
1558 
1565 void vpImageConvert::YUV411ToRGB(unsigned char* yuv, unsigned char* rgb, unsigned int size)
1566 {
1567 #if 1
1568  // std::cout << "call optimized ConvertYUV411ToRGB()" << std::endl;
1569  register int U, V, R, G, B, V2, U5, UV;
1570  register int Y0, Y1, Y2, Y3;
1571  for(unsigned int i = size / 4; i; i--) {
1572  U = (int)((*yuv++ - 128) * 0.354);
1573  U5 = 5*U;
1574  Y0 = *yuv++;
1575  Y1 = *yuv++;
1576  V = (int)((*yuv++ - 128) * 0.707);
1577  V2 = 2*V;
1578  Y2 = *yuv++;
1579  Y3 = *yuv++;
1580  UV = - U - V;
1581 
1582  // Original equations
1583  // R = Y + 1.402 V
1584  // G = Y - 0.344 U - 0.714 V
1585  // B = Y + 1.772 U
1586  R = Y0 + V2;
1587  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1588 
1589  G = Y0 + UV;
1590  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1591 
1592  B = Y0 + U5;
1593  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1594 
1595  *rgb++ = (unsigned char)R;
1596  *rgb++ = (unsigned char)G;
1597  *rgb++ = (unsigned char)B;
1598 
1599  //---
1600  R = Y1 + V2;
1601  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1602 
1603  G = Y1 + UV;
1604  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1605 
1606  B = Y1 + U5;
1607  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1608 
1609  *rgb++ = (unsigned char)R;
1610  *rgb++ = (unsigned char)G;
1611  *rgb++ = (unsigned char)B;
1612 
1613  //---
1614  R = Y2 + V2;
1615  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1616 
1617  G = Y2 + UV;
1618  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1619 
1620  B = Y2 + U5;
1621  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1622 
1623  *rgb++ = (unsigned char)R;
1624  *rgb++ = (unsigned char)G;
1625  *rgb++ = (unsigned char)B;
1626 
1627  //---
1628  R = Y3 + V2;
1629  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1630 
1631  G = Y3 + UV;
1632  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1633 
1634  B = Y3 + U5;
1635  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1636 
1637  *rgb++ = (unsigned char)R;
1638  *rgb++ = (unsigned char)G;
1639  *rgb++ = (unsigned char)B;
1640  }
1641 #else
1642  // tres tres lent ....
1643 
1644  unsigned int i=0,j=0;
1645  unsigned char r, g, b;
1646 
1647  while( j < size*3/2)
1648  {
1649  YUVToRGB (yuv[j+1], yuv[j], yuv[j+3], r, g, b);
1650  rgb[i] = r;
1651  rgb[i+1] = g;
1652  rgb[i+2] = b;
1653  i+=3;
1654 
1655  YUVToRGB (yuv[j+2], yuv[j], yuv[j+3], r, g, b);
1656  rgb[i] = r;
1657  rgb[i+1] = g;
1658  rgb[i+2] = b;
1659  i+=3;
1660 
1661  YUVToRGB (yuv[j+4], yuv[j], yuv[j+3], r, g, b);
1662  rgb[i] = r;
1663  rgb[i+1] = g;
1664  rgb[i+2] = b;
1665  i+=3;
1666 
1667  YUVToRGB (yuv[j+5], yuv[j], yuv[j+3], r, g, b);
1668  rgb[i] = r;
1669  rgb[i+1] = g;
1670  rgb[i+2] = b;
1671  i+=3;
1672  //TRACE("r= %d g=%d b=%d", r, g, b);
1673 
1674  j+=6;
1675  }
1676 #endif
1677 
1678 }
1679 
1680 
1681 
1688 void vpImageConvert::YUV420ToRGBa(unsigned char* yuv, unsigned char* rgba,
1689  unsigned int width, unsigned int height)
1690 {
1691  // std::cout << "call optimized ConvertYUV420ToRGBa()" << std::endl;
1692  register int U, V, R, G, B, V2, U5, UV;
1693  register int Y0, Y1, Y2, Y3;
1694  unsigned int size = width*height;
1695  unsigned char* iU = yuv + size;
1696  unsigned char* iV = yuv + 5*size/4;
1697  for(unsigned int i = 0; i<height/2; i++)
1698  {
1699  for(unsigned int j = 0; j < width/2 ; j++)
1700  {
1701  U = (int)((*iU++ - 128) * 0.354);
1702  U5 = 5*U;
1703  V = (int)((*iV++ - 128) * 0.707);
1704  V2 = 2*V;
1705  UV = - U - V;
1706  Y0 = *yuv++;
1707  Y1 = *yuv;
1708  yuv = yuv+width-1;
1709  Y2 = *yuv++;
1710  Y3 = *yuv;
1711  yuv = yuv-width+1;
1712 
1713  // Original equations
1714  // R = Y + 1.402 V
1715  // G = Y - 0.344 U - 0.714 V
1716  // B = Y + 1.772 U
1717  R = Y0 + V2;
1718  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1719 
1720  G = Y0 + UV;
1721  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1722 
1723  B = Y0 + U5;
1724  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1725 
1726  *rgba++ = (unsigned char)R;
1727  *rgba++ = (unsigned char)G;
1728  *rgba++ = (unsigned char)B;
1729  *rgba++ = 0;
1730 
1731  //---
1732  R = Y1 + V2;
1733  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1734 
1735  G = Y1 + UV;
1736  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1737 
1738  B = Y1 + U5;
1739  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1740 
1741  *rgba++ = (unsigned char)R;
1742  *rgba++ = (unsigned char)G;
1743  *rgba++ = (unsigned char)B;
1744  *rgba = 0;
1745  rgba = rgba + 4*width-7;
1746 
1747  //---
1748  R = Y2 + V2;
1749  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1750 
1751  G = Y2 + UV;
1752  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1753 
1754  B = Y2 + U5;
1755  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1756 
1757  *rgba++ = (unsigned char)R;
1758  *rgba++ = (unsigned char)G;
1759  *rgba++ = (unsigned char)B;
1760  *rgba++ = 0;
1761 
1762  //---
1763  R = Y3 + V2;
1764  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1765 
1766  G = Y3 + UV;
1767  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1768 
1769  B = Y3 + U5;
1770  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1771 
1772  *rgba++ = (unsigned char)R;
1773  *rgba++ = (unsigned char)G;
1774  *rgba++ = (unsigned char)B;
1775  *rgba = 0;
1776  rgba = rgba -4*width+1;
1777  }
1778  yuv+=width;
1779  rgba+=4*width;
1780  }
1781 }
1788 void vpImageConvert::YUV420ToRGB(unsigned char* yuv,
1789  unsigned char* rgb,
1790  unsigned int width, unsigned int height)
1791 {
1792  // std::cout << "call optimized ConvertYUV420ToRGB()" << std::endl;
1793  register int U, V, R, G, B, V2, U5, UV;
1794  register int Y0, Y1, Y2, Y3;
1795  unsigned int size = width*height;
1796  unsigned char* iU = yuv + size;
1797  unsigned char* iV = yuv + 5*size/4;
1798  for(unsigned int i = 0; i<height/2; i++)
1799  {
1800  for(unsigned int j = 0; j < width/2 ; j++)
1801  {
1802  U = (int)((*iU++ - 128) * 0.354);
1803  U5 = 5*U;
1804  V = (int)((*iV++ - 128) * 0.707);
1805  V2 = 2*V;
1806  UV = - U - V;
1807  Y0 = *yuv++;
1808  Y1 = *yuv;
1809  yuv = yuv+width-1;
1810  Y2 = *yuv++;
1811  Y3 = *yuv;
1812  yuv = yuv-width+1;
1813 
1814  // Original equations
1815  // R = Y + 1.402 V
1816  // G = Y - 0.344 U - 0.714 V
1817  // B = Y + 1.772 U
1818  R = Y0 + V2;
1819  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1820 
1821  G = Y0 + UV;
1822  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1823 
1824  B = Y0 + U5;
1825  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1826 
1827  *rgb++ = (unsigned char)R;
1828  *rgb++ = (unsigned char)G;
1829  *rgb++ = (unsigned char)B;
1830 
1831  //---
1832  R = Y1 + V2;
1833  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1834 
1835  G = Y1 + UV;
1836  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1837 
1838  B = Y1 + U5;
1839  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1840 
1841  *rgb++ = (unsigned char)R;
1842  *rgb++ = (unsigned char)G;
1843  *rgb = (unsigned char)B;
1844  rgb = rgb + 3*width-5;
1845 
1846  //---
1847  R = Y2 + V2;
1848  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1849 
1850  G = Y2 + UV;
1851  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1852 
1853  B = Y2 + U5;
1854  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1855 
1856  *rgb++ = (unsigned char)R;
1857  *rgb++ = (unsigned char)G;
1858  *rgb++ = (unsigned char)B;
1859 
1860  //---
1861  R = Y3 + V2;
1862  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1863 
1864  G = Y3 + UV;
1865  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1866 
1867  B = Y3 + U5;
1868  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1869 
1870  *rgb++ = (unsigned char)R;
1871  *rgb++ = (unsigned char)G;
1872  *rgb = (unsigned char)B;
1873  rgb = rgb -3*width+1;
1874  }
1875  yuv+=width;
1876  rgb+=3*width;
1877  }
1878 }
1879 
1886 void vpImageConvert::YUV420ToGrey(unsigned char* yuv, unsigned char* grey, unsigned int size)
1887 {
1888  for(unsigned int i=0 ; i < size ; i++)
1889  {
1890  *grey++ = *yuv++;
1891  }
1892 
1893 }
1900 void vpImageConvert::YUV444ToRGBa(unsigned char* yuv, unsigned char* rgba, unsigned int size)
1901 {
1902  register int U, V, R, G, B, V2, U5, UV;
1903  register int Y;
1904  for(unsigned int i = 0; i<size; i++)
1905  {
1906  U = (int)((*yuv++ - 128) * 0.354);
1907  U5 = 5*U;
1908  Y = *yuv++;
1909  V = (int)((*yuv++ - 128) * 0.707);
1910  V2 = 2*V;
1911  UV = - U - V;
1912 
1913 
1914  // Original equations
1915  // R = Y + 1.402 V
1916  // G = Y - 0.344 U - 0.714 V
1917  // B = Y + 1.772 U
1918  R = Y + V2;
1919  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1920 
1921  G = Y + UV;
1922  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1923 
1924  B = Y + U5;
1925  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1926 
1927  *rgba++ = (unsigned char)R;
1928  *rgba++ = (unsigned char)G;
1929  *rgba++ = (unsigned char)B;
1930  *rgba++ = 0;
1931  }
1932 }
1939 void vpImageConvert::YUV444ToRGB(unsigned char* yuv, unsigned char* rgb, unsigned int size)
1940 {
1941  register int U, V, R, G, B, V2, U5, UV;
1942  register int Y;
1943  for(unsigned int i = 0; i<size; i++)
1944  {
1945 
1946  U = (int)((*yuv++ - 128) * 0.354);
1947  U5 = 5*U;
1948  Y = *yuv++;
1949  V = (int)((*yuv++ - 128) * 0.707);
1950  V2 = 2*V;
1951  UV = - U - V;
1952 
1953  // Original equations
1954  // R = Y + 1.402 V
1955  // G = Y - 0.344 U - 0.714 V
1956  // B = Y + 1.772 U
1957  R = Y + V2;
1958  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
1959 
1960  G = Y + UV;
1961  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
1962 
1963  B = Y + U5;
1964  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
1965 
1966  *rgb++ = (unsigned char)R;
1967  *rgb++ = (unsigned char)G;
1968  *rgb++ = (unsigned char)B;
1969  }
1970 }
1971 
1978 void vpImageConvert::YUV444ToGrey(unsigned char* yuv, unsigned char* grey, unsigned int size)
1979 {
1980  yuv++;
1981  for(unsigned int i=0 ; i < size ; i++)
1982  {
1983  *grey++ = *yuv;
1984  yuv = yuv + 3;
1985  }
1986 }
1987 
1994 void vpImageConvert::YV12ToRGBa(unsigned char* yuv, unsigned char* rgba,
1995  unsigned int width, unsigned int height)
1996 {
1997  // std::cout << "call optimized ConvertYV12ToRGBa()" << std::endl;
1998  register int U, V, R, G, B, V2, U5, UV;
1999  register int Y0, Y1, Y2, Y3;
2000  unsigned int size = width*height;
2001  unsigned char* iV = yuv + size;
2002  unsigned char* iU = yuv + 5*size/4;
2003  for(unsigned int i = 0; i<height/2; i++)
2004  {
2005  for(unsigned int j = 0; j < width/2 ; j++)
2006  {
2007  U = (int)((*iU++ - 128) * 0.354);
2008  U5 = 5*U;
2009  V = (int)((*iV++ - 128) * 0.707);
2010  V2 = 2*V;
2011  UV = - U - V;
2012  Y0 = *yuv++;
2013  Y1 = *yuv;
2014  yuv = yuv+width-1;
2015  Y2 = *yuv++;
2016  Y3 = *yuv;
2017  yuv = yuv-width+1;
2018 
2019  // Original equations
2020  // R = Y + 1.402 V
2021  // G = Y - 0.344 U - 0.714 V
2022  // B = Y + 1.772 U
2023  R = Y0 + V2;
2024  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2025 
2026  G = Y0 + UV;
2027  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2028 
2029  B = Y0 + U5;
2030  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2031 
2032  *rgba++ = (unsigned char)R;
2033  *rgba++ = (unsigned char)G;
2034  *rgba++ = (unsigned char)B;
2035  *rgba++ = 0;
2036 
2037  //---
2038  R = Y1 + V2;
2039  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2040 
2041  G = Y1 + UV;
2042  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2043 
2044  B = Y1 + U5;
2045  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2046 
2047  *rgba++ = (unsigned char)R;
2048  *rgba++ = (unsigned char)G;
2049  *rgba++ = (unsigned char)B;
2050  *rgba = 0;
2051  rgba = rgba + 4*width-7;
2052 
2053  //---
2054  R = Y2 + V2;
2055  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2056 
2057  G = Y2 + UV;
2058  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2059 
2060  B = Y2 + U5;
2061  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2062 
2063  *rgba++ = (unsigned char)R;
2064  *rgba++ = (unsigned char)G;
2065  *rgba++ = (unsigned char)B;
2066  *rgba++ = 0;
2067 
2068  //---
2069  R = Y3 + V2;
2070  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2071 
2072  G = Y3 + UV;
2073  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2074 
2075  B = Y3 + U5;
2076  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2077 
2078  *rgba++ = (unsigned char)R;
2079  *rgba++ = (unsigned char)G;
2080  *rgba++ = (unsigned char)B;
2081  *rgba = 0;
2082  rgba = rgba -4*width+1;
2083  }
2084  yuv+=width;
2085  rgba+=4*width;
2086  }
2087 }
2094 void vpImageConvert::YV12ToRGB(unsigned char* yuv, unsigned char* rgb,
2095  unsigned int height, unsigned int width)
2096 {
2097  // std::cout << "call optimized ConvertYV12ToRGB()" << std::endl;
2098  register int U, V, R, G, B, V2, U5, UV;
2099  register int Y0, Y1, Y2, Y3;
2100  unsigned int size = width*height;
2101  unsigned char* iV = yuv + size;
2102  unsigned char* iU = yuv + 5*size/4;
2103  for(unsigned int i = 0; i<height/2; i++)
2104  {
2105  for(unsigned int j = 0; j < width/2 ; j++)
2106  {
2107  U = (int)((*iU++ - 128) * 0.354);
2108  U5 = 5*U;
2109  V = (int)((*iV++ - 128) * 0.707);
2110  V2 = 2*V;
2111  UV = - U - V;
2112  Y0 = *yuv++;
2113  Y1 = *yuv;
2114  yuv = yuv+width-1;
2115  Y2 = *yuv++;
2116  Y3 = *yuv;
2117  yuv = yuv-width+1;
2118 
2119  // Original equations
2120  // R = Y + 1.402 V
2121  // G = Y - 0.344 U - 0.714 V
2122  // B = Y + 1.772 U
2123  R = Y0 + V2;
2124  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2125 
2126  G = Y0 + UV;
2127  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2128 
2129  B = Y0 + U5;
2130  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2131 
2132  *rgb++ = (unsigned char)R;
2133  *rgb++ = (unsigned char)G;
2134  *rgb++ = (unsigned char)B;
2135 
2136  //---
2137  R = Y1 + V2;
2138  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2139 
2140  G = Y1 + UV;
2141  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2142 
2143  B = Y1 + U5;
2144  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2145 
2146  *rgb++ = (unsigned char)R;
2147  *rgb++ = (unsigned char)G;
2148  *rgb = (unsigned char)B;
2149  rgb = rgb + 3*width-5;
2150 
2151  //---
2152  R = Y2 + V2;
2153  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2154 
2155  G = Y2 + UV;
2156  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2157 
2158  B = Y2 + U5;
2159  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2160 
2161  *rgb++ = (unsigned char)R;
2162  *rgb++ = (unsigned char)G;
2163  *rgb++ = (unsigned char)B;
2164 
2165  //---
2166  R = Y3 + V2;
2167  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2168 
2169  G = Y3 + UV;
2170  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2171 
2172  B = Y3 + U5;
2173  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2174 
2175  *rgb++ = (unsigned char)R;
2176  *rgb++ = (unsigned char)G;
2177  *rgb = (unsigned char)B;
2178  rgb = rgb -3*width+1;
2179  }
2180  yuv+=width;
2181  rgb+=3*width;
2182  }
2183 }
2184 
2191 void vpImageConvert::YVU9ToRGBa(unsigned char* yuv, unsigned char* rgba,
2192  unsigned int width, unsigned int height)
2193 {
2194  // std::cout << "call optimized ConvertYVU9ToRGBa()" << std::endl;
2195  register int U, V, R, G, B, V2, U5, UV;
2196  register int Y0, Y1, Y2, Y3,Y4, Y5, Y6, Y7,Y8, Y9, Y10, Y11,Y12, Y13, Y14, Y15;
2197  unsigned int size = width*height;
2198  unsigned char* iV = yuv + size;
2199  unsigned char* iU = yuv + 17*size/16;
2200  for(unsigned int i = 0; i<height/4; i++)
2201  {
2202  for(unsigned int j = 0; j < width/4 ; j++)
2203  {
2204  U = (int)((*iU++ - 128) * 0.354);
2205  U5 = 5*U;
2206  V = (int)((*iV++ - 128) * 0.707);
2207  V2 = 2*V;
2208  UV = - U - V;
2209  Y0 = *yuv++;
2210  Y1 = *yuv++;
2211  Y2 = *yuv++;
2212  Y3 = *yuv;
2213  yuv = yuv+width-3;
2214  Y4 = *yuv++;
2215  Y5 = *yuv++;
2216  Y6 = *yuv++;
2217  Y7 = *yuv;
2218  yuv = yuv+width-3;
2219  Y8 = *yuv++;
2220  Y9 = *yuv++;
2221  Y10 = *yuv++;
2222  Y11 = *yuv;
2223  yuv = yuv+width-3;
2224  Y12 = *yuv++;
2225  Y13 = *yuv++;
2226  Y14 = *yuv++;
2227  Y15 = *yuv;
2228  yuv = yuv-3*width+1;
2229 
2230  // Original equations
2231  // R = Y + 1.402 V
2232  // G = Y - 0.344 U - 0.714 V
2233  // B = Y + 1.772 U
2234  R = Y0 + V2;
2235  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2236 
2237  G = Y0 + UV;
2238  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2239 
2240  B = Y0 + U5;
2241  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2242 
2243  *rgba++ = (unsigned char)R;
2244  *rgba++ = (unsigned char)G;
2245  *rgba++ = (unsigned char)B;
2246  *rgba++ = 0;
2247 
2248  //---
2249  R = Y1 + V2;
2250  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2251 
2252  G = Y1 + UV;
2253  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2254 
2255  B = Y1 + U5;
2256  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2257 
2258  *rgba++ = (unsigned char)R;
2259  *rgba++ = (unsigned char)G;
2260  *rgba++ = (unsigned char)B;
2261  *rgba++ = 0;
2262 
2263  //---
2264  R = Y2 + V2;
2265  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2266 
2267  G = Y2 + UV;
2268  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2269 
2270  B = Y2 + U5;
2271  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2272 
2273  *rgba++ = (unsigned char)R;
2274  *rgba++ = (unsigned char)G;
2275  *rgba++ = (unsigned char)B;
2276  *rgba++ = 0;
2277 
2278  //---
2279  R = Y3 + V2;
2280  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2281 
2282  G = Y3 + UV;
2283  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2284 
2285  B = Y3 + U5;
2286  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2287 
2288  *rgba++ = (unsigned char)R;
2289  *rgba++ = (unsigned char)G;
2290  *rgba++ = (unsigned char)B;
2291  *rgba = 0;
2292  rgba = rgba + 4*width-15;
2293 
2294  R = Y4 + V2;
2295  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2296 
2297  G = Y4 + UV;
2298  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2299 
2300  B = Y4 + U5;
2301  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2302 
2303  *rgba++ = (unsigned char)R;
2304  *rgba++ = (unsigned char)G;
2305  *rgba++ = (unsigned char)B;
2306  *rgba++ = 0;
2307 
2308  //---
2309  R = Y5 + V2;
2310  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2311 
2312  G = Y5 + UV;
2313  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2314 
2315  B = Y5 + U5;
2316  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2317 
2318  *rgba++ = (unsigned char)R;
2319  *rgba++ = (unsigned char)G;
2320  *rgba++ = (unsigned char)B;
2321  *rgba++ = 0;
2322 
2323  //---
2324  R = Y6 + V2;
2325  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2326 
2327  G = Y6 + UV;
2328  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2329 
2330  B = Y6 + U5;
2331  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2332 
2333  *rgba++ = (unsigned char)R;
2334  *rgba++ = (unsigned char)G;
2335  *rgba++ = (unsigned char)B;
2336  *rgba++ = 0;
2337 
2338  //---
2339  R = Y7 + V2;
2340  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2341 
2342  G = Y7 + UV;
2343  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2344 
2345  B = Y7 + U5;
2346  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2347 
2348  *rgba++ = (unsigned char)R;
2349  *rgba++ = (unsigned char)G;
2350  *rgba++ = (unsigned char)B;
2351  *rgba = 0;
2352  rgba = rgba + 4*width-15;
2353 
2354  R = Y8 + V2;
2355  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2356 
2357  G = Y8 + UV;
2358  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2359 
2360  B = Y8 + U5;
2361  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2362 
2363  *rgba++ = (unsigned char)R;
2364  *rgba++ = (unsigned char)G;
2365  *rgba++ = (unsigned char)B;
2366  *rgba++ = 0;
2367 
2368  //---
2369  R = Y9 + V2;
2370  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2371 
2372  G = Y9 + UV;
2373  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2374 
2375  B = Y9 + U5;
2376  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2377 
2378  *rgba++ = (unsigned char)R;
2379  *rgba++ = (unsigned char)G;
2380  *rgba++ = (unsigned char)B;
2381  *rgba++ = 0;
2382 
2383  //---
2384  R = Y10 + V2;
2385  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2386 
2387  G = Y10 + UV;
2388  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2389 
2390  B = Y10 + U5;
2391  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2392 
2393  *rgba++ = (unsigned char)R;
2394  *rgba++ = (unsigned char)G;
2395  *rgba++ = (unsigned char)B;
2396  *rgba++ = 0;
2397 
2398  //---
2399  R = Y11 + V2;
2400  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2401 
2402  G = Y11 + UV;
2403  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2404 
2405  B = Y11 + U5;
2406  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2407 
2408  *rgba++ = (unsigned char)R;
2409  *rgba++ = (unsigned char)G;
2410  *rgba++ = (unsigned char)B;
2411  *rgba = 0;
2412  rgba = rgba + 4*width-15;
2413 
2414  R = Y12 + V2;
2415  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2416 
2417  G = Y12 + UV;
2418  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2419 
2420  B = Y12 + U5;
2421  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2422 
2423  *rgba++ = (unsigned char)R;
2424  *rgba++ = (unsigned char)G;
2425  *rgba++ = (unsigned char)B;
2426  *rgba++ = 0;
2427 
2428  //---
2429  R = Y13 + V2;
2430  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2431 
2432  G = Y13 + UV;
2433  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2434 
2435  B = Y13 + U5;
2436  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2437 
2438  *rgba++ = (unsigned char)R;
2439  *rgba++ = (unsigned char)G;
2440  *rgba++ = (unsigned char)B;
2441  *rgba++ = 0;
2442 
2443  //---
2444  R = Y14 + V2;
2445  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2446 
2447  G = Y14 + UV;
2448  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2449 
2450  B = Y14 + U5;
2451  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2452 
2453  *rgba++ = (unsigned char)R;
2454  *rgba++ = (unsigned char)G;
2455  *rgba++ = (unsigned char)B;
2456  *rgba++ = 0;
2457 
2458  //---
2459  R = Y15 + V2;
2460  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2461 
2462  G = Y15 + UV;
2463  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2464 
2465  B = Y15 + U5;
2466  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2467 
2468  *rgba++ = (unsigned char)R;
2469  *rgba++ = (unsigned char)G;
2470  *rgba++ = (unsigned char)B;
2471  *rgba = 0;
2472  rgba = rgba -12*width+1;
2473  }
2474  yuv+=3*width;
2475  rgba+=12*width;
2476  }
2477 }
2484 void vpImageConvert::YVU9ToRGB(unsigned char* yuv, unsigned char* rgb,
2485  unsigned int height, unsigned int width)
2486 {
2487  // std::cout << "call optimized ConvertYVU9ToRGB()" << std::endl;
2488  register int U, V, R, G, B, V2, U5, UV;
2489  register int Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9, Y10, Y11, Y12, Y13, Y14, Y15;
2490  unsigned int size = width*height;
2491  unsigned char* iV = yuv + size;
2492  unsigned char* iU = yuv + 17*size/16;
2493  for(unsigned int i = 0; i<height/4; i++)
2494  {
2495  for(unsigned int j = 0; j < width/4 ; j++)
2496  {
2497  U = (int)((*iU++ - 128) * 0.354);
2498  U5 = 5*U;
2499  V = (int)((*iV++ - 128) * 0.707);
2500  V2 = 2*V;
2501  UV = - U - V;
2502  Y0 = *yuv++;
2503  Y1 = *yuv++;
2504  Y2 = *yuv++;
2505  Y3 = *yuv;
2506  yuv = yuv+width-3;
2507  Y4 = *yuv++;
2508  Y5 = *yuv++;
2509  Y6 = *yuv++;
2510  Y7 = *yuv;
2511  yuv = yuv+width-3;
2512  Y8 = *yuv++;
2513  Y9 = *yuv++;
2514  Y10 = *yuv++;
2515  Y11 = *yuv;
2516  yuv = yuv+width-3;
2517  Y12 = *yuv++;
2518  Y13 = *yuv++;
2519  Y14 = *yuv++;
2520  Y15 = *yuv;
2521  yuv = yuv-3*width+1;
2522 
2523  // Original equations
2524  // R = Y + 1.402 V
2525  // G = Y - 0.344 U - 0.714 V
2526  // B = Y + 1.772 U
2527  R = Y0 + V2;
2528  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2529 
2530  G = Y0 + UV;
2531  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2532 
2533  B = Y0 + U5;
2534  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2535 
2536  *rgb++ = (unsigned char)R;
2537  *rgb++ = (unsigned char)G;
2538  *rgb++ = (unsigned char)B;
2539 
2540  //---
2541  R = Y1 + V2;
2542  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2543 
2544  G = Y1 + UV;
2545  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2546 
2547  B = Y1 + U5;
2548  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2549 
2550  *rgb++ = (unsigned char)R;
2551  *rgb++ = (unsigned char)G;
2552  *rgb++ = (unsigned char)B;
2553 
2554  //---
2555  R = Y2 + V2;
2556  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2557 
2558  G = Y2 + UV;
2559  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2560 
2561  B = Y2 + U5;
2562  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2563 
2564  *rgb++ = (unsigned char)R;
2565  *rgb++ = (unsigned char)G;
2566  *rgb++ = (unsigned char)B;
2567 
2568  //---
2569  R = Y3 + V2;
2570  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2571 
2572  G = Y3 + UV;
2573  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2574 
2575  B = Y3 + U5;
2576  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2577 
2578  *rgb++ = (unsigned char)R;
2579  *rgb++ = (unsigned char)G;
2580  *rgb = (unsigned char)B;
2581  rgb = rgb + 3*width-11;
2582 
2583  R = Y4 + V2;
2584  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2585 
2586  G = Y4 + UV;
2587  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2588 
2589  B = Y4 + U5;
2590  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2591 
2592  *rgb++ = (unsigned char)R;
2593  *rgb++ = (unsigned char)G;
2594  *rgb++ = (unsigned char)B;
2595 
2596  //---
2597  R = Y5 + V2;
2598  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2599 
2600  G = Y5 + UV;
2601  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2602 
2603  B = Y5 + U5;
2604  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2605 
2606  *rgb++ = (unsigned char)R;
2607  *rgb++ = (unsigned char)G;
2608  *rgb++ = (unsigned char)B;
2609 
2610  //---
2611  R = Y6 + V2;
2612  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2613 
2614  G = Y6 + UV;
2615  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2616 
2617  B = Y6 + U5;
2618  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2619 
2620  *rgb++ = (unsigned char)R;
2621  *rgb++ = (unsigned char)G;
2622  *rgb++ = (unsigned char)B;
2623 
2624  //---
2625  R = Y7 + V2;
2626  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2627 
2628  G = Y7 + UV;
2629  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2630 
2631  B = Y7 + U5;
2632  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2633 
2634  *rgb++ = (unsigned char)R;
2635  *rgb++ = (unsigned char)G;
2636  *rgb = (unsigned char)B;
2637  rgb = rgb + 3*width-11;
2638 
2639  R = Y8 + V2;
2640  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2641 
2642  G = Y8 + UV;
2643  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2644 
2645  B = Y8 + U5;
2646  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2647 
2648  *rgb++ = (unsigned char)R;
2649  *rgb++ = (unsigned char)G;
2650  *rgb++ = (unsigned char)B;
2651 
2652  //---
2653  R = Y9 + V2;
2654  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2655 
2656  G = Y9 + UV;
2657  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2658 
2659  B = Y9 + U5;
2660  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2661 
2662  *rgb++ = (unsigned char)R;
2663  *rgb++ = (unsigned char)G;
2664  *rgb++ = (unsigned char)B;
2665 
2666  //---
2667  R = Y10 + V2;
2668  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2669 
2670  G = Y10 + UV;
2671  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2672 
2673  B = Y10 + U5;
2674  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2675 
2676  *rgb++ = (unsigned char)R;
2677  *rgb++ = (unsigned char)G;
2678  *rgb++ = (unsigned char)B;
2679 
2680  //---
2681  R = Y11 + V2;
2682  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2683 
2684  G = Y11 + UV;
2685  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2686 
2687  B = Y11 + U5;
2688  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2689 
2690  *rgb++ = (unsigned char)R;
2691  *rgb++ = (unsigned char)G;
2692  *rgb = (unsigned char)B;
2693  rgb = rgb + 3*width-11;
2694 
2695  R = Y12 + V2;
2696  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2697 
2698  G = Y12 + UV;
2699  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2700 
2701  B = Y12 + U5;
2702  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2703 
2704  *rgb++ = (unsigned char)R;
2705  *rgb++ = (unsigned char)G;
2706  *rgb++ = (unsigned char)B;
2707 
2708  //---
2709  R = Y13 + V2;
2710  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2711 
2712  G = Y13 + UV;
2713  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2714 
2715  B = Y13 + U5;
2716  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2717 
2718  *rgb++ = (unsigned char)R;
2719  *rgb++ = (unsigned char)G;
2720  *rgb++ = (unsigned char)B;
2721 
2722  //---
2723  R = Y14 + V2;
2724  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2725 
2726  G = Y14 + UV;
2727  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2728 
2729  B = Y14 + U5;
2730  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2731 
2732  *rgb++ = (unsigned char)R;
2733  *rgb++ = (unsigned char)G;
2734  *rgb++ = (unsigned char)B;
2735 
2736  //---
2737  R = Y15 + V2;
2738  if ((R >> 8) > 0) R = 255; else if (R < 0) R = 0;
2739 
2740  G = Y15 + UV;
2741  if ((G >> 8) > 0) G = 255; else if (G < 0) G = 0;
2742 
2743  B = Y15 + U5;
2744  if ((B >> 8) > 0) B = 255; else if (B < 0) B = 0;
2745 
2746  *rgb++ = (unsigned char)R;
2747  *rgb++ = (unsigned char)G;
2748  *rgb++ = (unsigned char)B;
2749  rgb = rgb -9*width+1;
2750  }
2751  yuv+=3*width;
2752  rgb+=9*width;
2753  }
2754 }
2755 
2761 void vpImageConvert::RGBToRGBa(unsigned char* rgb, unsigned char* rgba, unsigned int size)
2762 {
2763  unsigned char *pt_input = rgb;
2764  unsigned char *pt_end = rgb + 3*size;
2765  unsigned char *pt_output = rgba;
2766 
2767  while(pt_input != pt_end) {
2768  *(pt_output++) = *(pt_input++) ; // R
2769  *(pt_output++) = *(pt_input++) ; // G
2770  *(pt_output++) = *(pt_input++) ; // B
2771  *(pt_output++) = 0 ; // A
2772  }
2773 }
2774 
2780 void vpImageConvert::RGBaToRGB(unsigned char* rgba, unsigned char* rgb, unsigned int size)
2781 {
2782  unsigned char *pt_input = rgba;
2783  unsigned char *pt_end = rgba + 4*size;
2784  unsigned char *pt_output = rgb;
2785 
2786  while(pt_input != pt_end) {
2787  *(pt_output++) = *(pt_input++) ; // R
2788  *(pt_output++) = *(pt_input++) ; // G
2789  *(pt_output++) = *(pt_input++) ; // B
2790  pt_input++ ;
2791  }
2792 }
2799 void vpImageConvert::RGBToGrey(unsigned char* rgb, unsigned char* grey, unsigned int size)
2800 {
2801  unsigned char *pt_input = rgb;
2802  unsigned char* pt_end = rgb + size*3;
2803  unsigned char *pt_output = grey;
2804  while(pt_input != pt_end) {
2805  *pt_output = (unsigned char) (0.2126 * (*pt_input)
2806  + 0.7152 * (*(pt_input + 1))
2807  + 0.0722 * (*(pt_input + 2)) );
2808  pt_input += 3;
2809  pt_output ++;
2810  }
2811 }
2819 void vpImageConvert::RGBaToGrey(unsigned char* rgba, unsigned char* grey, unsigned int size)
2820 {
2821  unsigned char *pt_input = rgba;
2822  unsigned char* pt_end = rgba + size*4;
2823  unsigned char *pt_output = grey;
2824 
2825  while(pt_input != pt_end) {
2826  *pt_output = (unsigned char) (0.2126 * (*pt_input)
2827  + 0.7152 * (*(pt_input + 1))
2828  + 0.0722 * (*(pt_input + 2)) );
2829  pt_input += 4;
2830  pt_output ++;
2831  }
2832 }
2833 
2838 void
2839 vpImageConvert::GreyToRGBa(unsigned char* grey, unsigned char* rgba, unsigned int size)
2840 {
2841  unsigned char *pt_input = grey;
2842  unsigned char *pt_end = grey + size;
2843  unsigned char *pt_output = rgba;
2844 
2845  while(pt_input != pt_end) {
2846  unsigned char p = *pt_input ;
2847  *(pt_output ) = p ; // R
2848  *(pt_output + 1) = p ; // G
2849  *(pt_output + 2) = p ; // B
2850  *(pt_output + 3) = p ; // A
2851 
2852  pt_input ++;
2853  pt_output += 4;
2854  }
2855 }
2856 
2861 void
2862 vpImageConvert::GreyToRGB(unsigned char* grey, unsigned char* rgb, unsigned int size)
2863 {
2864  unsigned char *pt_input = grey;
2865  unsigned char* pt_end = grey + size;
2866  unsigned char *pt_output = rgb;
2867 
2868  while(pt_input != pt_end) {
2869  unsigned char p = *pt_input ;
2870  *(pt_output ) = p ; // R
2871  *(pt_output + 1) = p ; // G
2872  *(pt_output + 2) = p ; // B
2873 
2874  pt_input ++;
2875  pt_output += 3;
2876  }
2877 }
2878 
2879 
2885 void
2886 vpImageConvert::BGRToRGBa(unsigned char * bgr, unsigned char * rgba,
2887  unsigned int width, unsigned int height, bool flip)
2888 {
2889  //if we have to flip the image, we start from the end last scanline so the
2890  //step is negative
2891  int lineStep = (flip) ? -(int)(width*3) : (int)(width*3);
2892 
2893  //starting source address = last line if we need to flip the image
2894  unsigned char * src = (flip) ? (bgr+(width*height*3)+lineStep) : bgr;
2895  unsigned char * line;
2896 
2897  unsigned int j=0;
2898  unsigned int i=0;
2899 
2900  for(i=0 ; i < height ; i++)
2901  {
2902  line = src;
2903  for( j=0 ; j < width ; j++)
2904  {
2905  *rgba++ = *(line+2);
2906  *rgba++ = *(line+1);
2907  *rgba++ = *(line+0);
2908  *rgba++ = 0;
2909 
2910  line+=3;
2911  }
2912  //go to the next line
2913  src+=lineStep;
2914  }
2915 
2916 }
2917 
2923 void
2924 vpImageConvert::BGRToGrey(unsigned char * bgr, unsigned char * grey,
2925  unsigned int width, unsigned int height, bool flip)
2926 {
2927  //if we have to flip the image, we start from the end last scanline so the
2928  //step is negative
2929  int lineStep = (flip) ? -(int)(width*3) : (int)(width*3);
2930 
2931  //starting source address = last line if we need to flip the image
2932  unsigned char * src = (flip) ? bgr+(width*height*3)+lineStep : bgr;
2933  unsigned char * line;
2934 
2935  unsigned int j=0;
2936  unsigned int i=0;
2937 
2938  for(i=0 ; i < height ; i++)
2939  {
2940  line = src;
2941  for( j=0 ; j < width ; j++)
2942  {
2943  *grey++ = (unsigned char)( 0.2126 * *(line+2)
2944  + 0.7152 * *(line+1)
2945  + 0.0722 * *(line+0)) ;
2946  line+=3;
2947  }
2948 
2949  //go to the next line
2950  src+=lineStep;
2951  }
2952 }
2958 void
2959 vpImageConvert::RGBToRGBa(unsigned char * rgb, unsigned char * rgba,
2960  unsigned int width, unsigned int height, bool flip)
2961 {
2962  //if we have to flip the image, we start from the end last scanline so the
2963  //step is negative
2964  int lineStep = (flip) ? -(int)(width*3) : (int)(width*3);
2965 
2966  //starting source address = last line if we need to flip the image
2967  unsigned char * src = (flip) ? (rgb+(width*height*3)+lineStep) : rgb;
2968  unsigned char * line;
2969 
2970  unsigned int j=0;
2971  unsigned int i=0;
2972 
2973  for(i=0 ; i < height ; i++)
2974  {
2975  line = src;
2976  for( j=0 ; j < width ; j++)
2977  {
2978  *rgba++ = *(line++);
2979  *rgba++ = *(line++);
2980  *rgba++ = *(line++);
2981  *rgba++ = 0;
2982  }
2983  //go to the next line
2984  src+=lineStep;
2985  }
2986 }
2987 
2993 void
2994 vpImageConvert::RGBToGrey(unsigned char * rgb, unsigned char * grey,
2995  unsigned int width, unsigned int height, bool flip)
2996 {
2997  //if we have to flip the image, we start from the end last scanline so the
2998  //step is negative
2999  int lineStep = (flip) ? -(int)(width*3) : (int)(width*3);
3000 
3001  //starting source address = last line if we need to flip the image
3002  unsigned char * src = (flip) ? rgb+(width*height*3)+lineStep : rgb;
3003  unsigned char * line;
3004 
3005  unsigned int j=0;
3006  unsigned int i=0;
3007 
3008  unsigned r,g,b;
3009 
3010  for(i=0 ; i < height ; i++)
3011  {
3012  line = src;
3013  for( j=0 ; j < width ; j++)
3014  {
3015  r = *(line++);
3016  g = *(line++);
3017  b = *(line++);
3018  *grey++ = (unsigned char)( 0.2126 * r + 0.7152 * g + 0.0722 * b) ;
3019  }
3020 
3021  //go to the next line
3022  src+=lineStep;
3023  }
3024 }
3025 
3031 void vpImageConvert::computeYCbCrLUT()
3032 {
3033  if (YCbCrLUTcomputed == false) {
3034  int index = 256, aux;
3035 
3036  while (index-- ) {
3037 
3038  aux = index - 128;
3039  vpImageConvert::vpCrr[index] = (int)( 364.6610 * aux) >> 8;
3040  vpImageConvert::vpCgb[index] = (int)( -89.8779 * aux) >> 8;
3041  vpImageConvert::vpCgr[index] = (int)(-185.8154 * aux) >> 8;
3042  vpImageConvert::vpCbb[index] = (int)( 460.5724 * aux) >> 8;
3043  }
3044 
3045  YCbCrLUTcomputed = true;
3046  }
3047 }
3048 
3049 
3069 void vpImageConvert::YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
3070 {
3071  unsigned char *cbv;
3072  unsigned char *crv;
3073  unsigned char *pt_ycbcr = ycbcr;
3074  unsigned char *pt_rgb = rgb;
3075  cbv = pt_ycbcr + 1;
3076  crv = pt_ycbcr + 3;
3077 
3078  vpImageConvert::computeYCbCrLUT();
3079 
3080  int col = 0;
3081 
3082  while (size--) {
3083  register int val_r, val_g, val_b;
3084  if (!(col++ % 2)) {
3085  cbv = pt_ycbcr + 1;
3086  crv = pt_ycbcr + 3;
3087  }
3088 
3089  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3090  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3091  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3092 
3093  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3094 
3095  *pt_rgb++ = (val_r < 0) ? 0u :
3096  ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3097  *pt_rgb++ = (val_g < 0) ? 0u :
3098  ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3099  *pt_rgb++ = (val_b < 0) ? 0u :
3100  ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3101 
3102  pt_ycbcr += 2;
3103  }
3104 }
3105 
3127 void vpImageConvert::YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgba, unsigned int size)
3128 {
3129  unsigned char *cbv;
3130  unsigned char *crv;
3131  unsigned char *pt_ycbcr = ycbcr;
3132  unsigned char *pt_rgba = rgba;
3133  cbv = pt_ycbcr + 1;
3134  crv = pt_ycbcr + 3;
3135 
3136  vpImageConvert::computeYCbCrLUT();
3137 
3138  int col = 0;
3139 
3140  while (size--) {
3141  register int val_r, val_g, val_b;
3142  if (!(col++ % 2)) {
3143  cbv = pt_ycbcr + 1;
3144  crv = pt_ycbcr + 3;
3145  }
3146 
3147  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3148  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3149  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3150 
3151  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3152 
3153  *pt_rgba++ = (val_r < 0) ? 0u :
3154  ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3155  *pt_rgba++ = (val_g < 0) ? 0u :
3156  ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3157  *pt_rgba++ = (val_b < 0) ? 0u :
3158  ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3159  *pt_rgba++ = 0;
3160 
3161  pt_ycbcr += 2;
3162  }
3163 }
3164 
3165 
3182 void vpImageConvert::YCbCrToGrey(unsigned char* yuv, unsigned char* grey, unsigned int size)
3183 {
3184  unsigned int i=0,j=0;
3185 
3186  while( j < size*2)
3187  {
3188  grey[i++] = yuv[j];
3189  grey[i++] = yuv[j+2];
3190  j+=4;
3191  }
3192 }
3193 
3212 void vpImageConvert::YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
3213 {
3214  unsigned char *cbv;
3215  unsigned char *crv;
3216  unsigned char *pt_ycbcr = ycrcb;
3217  unsigned char *pt_rgb = rgb;
3218  crv = pt_ycbcr + 1;
3219  cbv = pt_ycbcr + 3;
3220 
3221  vpImageConvert::computeYCbCrLUT();
3222 
3223  int col = 0;
3224 
3225  while (size--) {
3226  register int val_r, val_g, val_b;
3227  if (!(col++ % 2)) {
3228  crv = pt_ycbcr + 1;
3229  cbv = pt_ycbcr + 3;
3230  }
3231 
3232  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3233  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3234  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3235 
3236  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3237 
3238  *pt_rgb++ = (val_r < 0) ? 0u :
3239  ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3240  *pt_rgb++ = (val_g < 0) ? 0u :
3241  ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3242  *pt_rgb++ = (val_b < 0) ? 0u :
3243  ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3244 
3245  pt_ycbcr += 2;
3246  }
3247 }
3268 void vpImageConvert::YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgba, unsigned int size)
3269 {
3270  unsigned char *cbv;
3271  unsigned char *crv;
3272  unsigned char *pt_ycbcr = ycrcb;
3273  unsigned char *pt_rgba = rgba;
3274  crv = pt_ycbcr + 1;
3275  cbv = pt_ycbcr + 3;
3276 
3277  vpImageConvert::computeYCbCrLUT();
3278 
3279  int col = 0;
3280 
3281  while (size--) {
3282  register int val_r, val_g, val_b;
3283  if (!(col++ % 2)) {
3284  crv = pt_ycbcr + 1;
3285  cbv = pt_ycbcr + 3;
3286  }
3287 
3288  val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
3289  val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
3290  val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
3291 
3292  vpDEBUG_TRACE(5, "[%d] R: %d G: %d B: %d\n", size, val_r, val_g, val_b);
3293 
3294  *pt_rgba++ = (val_r < 0) ? 0u :
3295  ((val_r > 255) ? 255u : (unsigned char)val_r); // Red component.
3296  *pt_rgba++ = (val_g < 0) ? 0u :
3297  ((val_g > 255) ? 255u : (unsigned char)val_g); // Green component.
3298  *pt_rgba++ = (val_b < 0) ? 0u :
3299  ((val_b > 255) ? 255u : (unsigned char)val_b); // Blue component.
3300  *pt_rgba++ = 0;
3301 
3302  pt_ycbcr += 2;
3303  }
3304 }
3305 
3346 {
3347  register size_t n = src.getNumberOfPixel();
3348  unsigned int height = src.getHeight();
3349  unsigned int width = src.getWidth();
3350  unsigned char* input;
3351  unsigned char* dst ;
3352 
3353  vpImage<unsigned char>* tabChannel[4];
3354 
3355 /* incrsrc[0] = 0; //init
3356  incrsrc[1] = 0; //step after the first used channel
3357  incrsrc[2] = 0; //step after the second used channel
3358  incrsrc[3] = 0;
3359  incrsrc[4] = 0;
3360  */
3361  tabChannel[0] = pR;
3362  tabChannel[1] = pG;
3363  tabChannel[2] = pB;
3364  tabChannel[3] = pa;
3365 
3366  register size_t i; /* ordre */
3367  for(unsigned int j = 0;j < 4;j++){
3368  if(tabChannel[j]!=NULL){
3369  if(tabChannel[j]->getHeight() != height ||
3370  tabChannel[j]->getWidth() != width){
3371  tabChannel[j]->resize(height,width);
3372  }
3373  dst = (unsigned char*)tabChannel[j]->bitmap;
3374 
3375  input = (unsigned char*)src.bitmap+j;
3376  i = 0;
3377 #if 1 //optimization
3378  if (n >= 4) { /* boucle deroulee lsize fois */
3379  n -= 3;
3380  for (; i < n; i += 4) {
3381  *dst = *input; input += 4; dst++;
3382  *dst = *input; input += 4; dst++;
3383  *dst = *input; input += 4; dst++;
3384  *dst = *input; input += 4; dst++;
3385  }
3386  n += 3;
3387  }
3388 #endif
3389  for (; i < n; i++) {
3390  *dst = *input; input += 4; dst ++;
3391  }
3392  }
3393  }
3394 }
3395 
3405  const vpImage<unsigned char> *G,
3406  const vpImage<unsigned char> *B,
3407  const vpImage<unsigned char> *a,
3408  vpImage<vpRGBa> &RGBa) {
3409  //Check if the input channels have all the same dimensions
3410  std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
3411  if(R != NULL) {
3412  mapOfWidths[R->getWidth()]++;
3413  mapOfHeights[R->getHeight()]++;
3414  }
3415 
3416  if(G != NULL) {
3417  mapOfWidths[G->getWidth()]++;
3418  mapOfHeights[G->getHeight()]++;
3419  }
3420 
3421  if(B != NULL) {
3422  mapOfWidths[B->getWidth()]++;
3423  mapOfHeights[B->getHeight()]++;
3424  }
3425 
3426  if(a != NULL) {
3427  mapOfWidths[a->getWidth()]++;
3428  mapOfHeights[a->getHeight()]++;
3429  }
3430 
3431  if(mapOfWidths.size() == 1 && mapOfHeights.size() == 1) {
3432  unsigned int width = mapOfWidths.begin()->first;
3433  unsigned int height = mapOfHeights.begin()->first;
3434 
3435  RGBa.resize(height, width);
3436 
3437  unsigned int size = width*height;
3438  for(unsigned int i = 0; i < size; i++) {
3439  if(R != NULL) {
3440  RGBa.bitmap[i].R = R->bitmap[i];
3441  }
3442 
3443  if(G != NULL) {
3444  RGBa.bitmap[i].G = G->bitmap[i];
3445  }
3446 
3447  if(B != NULL) {
3448  RGBa.bitmap[i].B = B->bitmap[i];
3449  }
3450 
3451  if(a != NULL) {
3452  RGBa.bitmap[i].A = a->bitmap[i];
3453  }
3454  }
3455  } else {
3456  throw vpException(vpException::dimensionError, "Mismatch dimensions !");
3457  }
3458 }
3459 
3470 void vpImageConvert::MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
3471 {
3472  register int i = (((int)size)<<1)-1;
3473  register int j = (int)size-1;
3474  register int y;
3475 
3476  while (i >= 0) {
3477  y = grey16[i--];
3478  grey[j--] = static_cast<unsigned char>( (y+(grey16[i--]<<8))>>8 );
3479  }
3480 }
3481 
3492 void vpImageConvert::MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
3493 {
3494  register int i = (((int)size)<<1)-1;
3495  register int j = (int)(size*4-1);
3496  register int y;
3497  register unsigned char v;
3498 
3499  while (i >= 0) {
3500  y = grey16[i--];
3501  v = static_cast<unsigned char>( (y+(grey16[i--]<<8))>>8 );
3502  rgba[j--] = 0;
3503  rgba[j--] = v;
3504  rgba[j--] = v;
3505  rgba[j--] = v;
3506  }
3507 }
3508 
3509 void vpImageConvert::HSV2RGB(const double *hue_, const double *saturation_, const double *value_, unsigned char *rgb,
3510  const unsigned int size, const unsigned int step) {
3511  for(unsigned int i = 0; i < size; i++) {
3512  double h, s, v;
3513  double f, p, q, t;
3514  double hue = hue_[i], saturation = saturation_[i], value = value_[i];
3515 
3516  if (vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
3517  hue = value;
3518  saturation = value;
3519  } else {
3520  h = hue * 6.0;
3521  s = saturation;
3522  v = value;
3523 
3524  if (vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
3525  h = 0.0;
3526  }
3527 
3528  f = h - (int) h;
3529  p = v * (1.0 - s);
3530  q = v * (1.0 - s * f);
3531  t = v * (1.0 - s * (1.0 - f));
3532 
3533  switch ((int) h) {
3534  case 0:
3535  hue = v;
3536  saturation = t;
3537  value = p;
3538  break;
3539 
3540  case 1:
3541  hue = q;
3542  saturation = v;
3543  value = p;
3544  break;
3545 
3546  case 2:
3547  hue = p;
3548  saturation = v;
3549  value = t;
3550  break;
3551 
3552  case 3:
3553  hue = p;
3554  saturation = q;
3555  value = v;
3556  break;
3557 
3558  case 4:
3559  hue = t;
3560  saturation = p;
3561  value = v;
3562  break;
3563 
3564  default: //case 5:
3565  hue = v;
3566  saturation = p;
3567  value = q;
3568  break;
3569  }
3570  }
3571 
3572  rgb[i*step] = (unsigned char) vpMath::round(hue * 255.0);
3573  rgb[i*step + 1] = (unsigned char) vpMath::round(saturation * 255.0);
3574  rgb[i*step + 2] = (unsigned char) vpMath::round(value * 255.0);
3575  }
3576 }
3577 
3578 void vpImageConvert::RGB2HSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
3579  const unsigned int size, const unsigned int step) {
3580  for(unsigned int i = 0; i < size; i++) {
3581  double red, green, blue;
3582  double h, s, v;
3583  double min, max;
3584  double delta;
3585 
3586  red = rgb[i*step] / 255.0;
3587  green = rgb[i*step + 1] / 255.0;
3588  blue = rgb[i*step + 2] / 255.0;
3589 
3590  if (red > green) {
3591  max = (std::max)(red, blue);
3592  min = (std::min)(green, blue);
3593  } else {
3594  max = (std::max)(green, blue);
3595  min = (std::min)(red, blue);
3596  }
3597 
3598  v = max;
3599 
3600  if (!vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
3601  s = (max - min) / max;
3602  } else {
3603  s = 0.0;
3604  }
3605 
3606  if (vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
3607  h = 0.0;
3608  } else {
3609  delta = max - min;
3610  if (vpMath::equal(delta, 0.0, std::numeric_limits<double>::epsilon())) {
3611  delta = 1.0;
3612  }
3613 
3614  if (vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
3615  h = (green - blue) / delta;
3616  } else if (vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
3617  h = 2 + (blue - red) / delta;
3618  } else {
3619  h = 4 + (red - green) / delta;
3620  }
3621 
3622  h /= 6.0;
3623  if (h < 0.0) {
3624  h += 1.0;
3625  } else if (h > 1.0) {
3626  h -= 1.0;
3627  }
3628  }
3629 
3630  hue[i] = h;
3631  saturation[i] = s;
3632  value[i] = v;
3633  }
3634 }
3635 
3645 void vpImageConvert::HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba,
3646  const unsigned int size) {
3647  vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
3648 }
3649 
3659 void vpImageConvert::HSVToRGBa(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
3660  unsigned char *rgba, const unsigned int size) {
3661  for(unsigned int i = 0; i < size; i++) {
3662  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
3663 
3664  vpImageConvert::HSVToRGBa(&h, &s, &v, (rgba + i*4), 1);
3665  }
3666 }
3667 
3678 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value,
3679  const unsigned int size) {
3680  vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
3681 }
3682 
3693 void vpImageConvert::RGBaToHSV(const unsigned char *rgba, unsigned char *hue, unsigned char *saturation,
3694  unsigned char *value, const unsigned int size) {
3695  for(unsigned int i = 0; i < size; i++) {
3696  double h, s, v;
3697  vpImageConvert::RGBaToHSV((rgba + i*4), &h, &s, &v, 1);
3698 
3699  hue[i] = (unsigned char) (255.0 * h);
3700  saturation[i] = (unsigned char) (255.0 * s);
3701  value[i] = (unsigned char) (255.0 * v);
3702  }
3703 }
3704 
3714 void vpImageConvert::HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb,
3715  const unsigned int size) {
3716  vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
3717 }
3718 
3728 void vpImageConvert::HSVToRGB(const unsigned char *hue, const unsigned char *saturation, const unsigned char *value,
3729  unsigned char *rgb, const unsigned int size) {
3730  for(unsigned int i = 0; i < size; i++) {
3731  double h = hue[i] / 255.0, s = saturation[i] / 255.0, v = value[i] / 255.0;
3732 
3733  vpImageConvert::HSVToRGB(&h, &s, &v, (rgb + i*3), 1);
3734  }
3735 }
3736 
3746 void vpImageConvert::RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value,
3747  const unsigned int size) {
3748  vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
3749 }
3750 
3760 void vpImageConvert::RGBToHSV(const unsigned char *rgb, unsigned char *hue, unsigned char *saturation, unsigned char *value,
3761  const unsigned int size) {
3762  for(unsigned int i = 0; i < size; i++) {
3763  double h, s, v;
3764 
3765  vpImageConvert::RGBToHSV((rgb + i*3), &h, &s, &v, 1);
3766 
3767  hue[i] = (unsigned char) (255.0 * h);
3768  saturation[i] = (unsigned char) (255.0 * s);
3769  value[i] = (unsigned char) (255.0 * v);
3770  }
3771 }
3772 
3773 /*
3774  * Local variables:
3775  * c-basic-offset: 2
3776  * End:
3777  */
unsigned int getCols() const
Definition: vpImage.h:180
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void YUYVToRGBa(unsigned char *yuyv, unsigned char *rgba, unsigned int width, unsigned int height)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int size)
unsigned int getWidth() const
Definition: vpImage.h:161
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
void getMinMaxValue(Type &min, Type &max) const
Look for the minimum and the maximum value within the bitmap.
Definition: vpImage.h:768
static void RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value, const unsigned int size)
unsigned char B
Blue component.
Definition: vpRGBa.h:144
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
Type * bitmap
points toward the bitmap
Definition: vpImage.h:116
static void MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:297
static void YUV422ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV420ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int size)
error that can be emited by ViSP classes.
Definition: vpException.h:73
static void YUV422ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YUV411ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
static void YUVToRGB(unsigned char y, unsigned char u, unsigned char v, unsigned char &r, unsigned char &g, unsigned char &b)
unsigned char G
Green component.
Definition: vpRGBa.h:143
static void GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
static int round(const double x)
Definition: vpMath.h:248
Class that defines a RGB 32 bits structure.
Definition: vpRGBa.h:64
static void YUV444ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
static void YUV420ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YVU9ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YUV422ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
unsigned int getRows() const
Definition: vpImage.h:171
static void YVU9ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YV12ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int width, unsigned int height)
static void YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
unsigned char A
Additionnal component.
Definition: vpRGBa.h:145
static void YUYVToGrey(unsigned char *yuyv, unsigned char *grey, unsigned int size)
static void MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
unsigned int getNumberOfPixel() const
Definition: vpImage.h:214
void resize(const unsigned int h, const unsigned int w)
set the size of the image without initializing it.
Definition: vpImage.h:616
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, const unsigned int size)
static void YUYVToRGB(unsigned char *yuyv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV444ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int size)
static void YUV444ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void YUV411ToRGBa(unsigned char *yuv, unsigned char *rgba, unsigned int size)
unsigned char R
Red component.
Definition: vpRGBa.h:142
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, const unsigned int size)
#define vpDEBUG_TRACE
Definition: vpDebug.h:478
unsigned int getHeight() const
Definition: vpImage.h:152
static void YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void YUV411ToGrey(unsigned char *yuv, unsigned char *grey, unsigned int size)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
static void YCrCbToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb, const unsigned int size)
static void YCrCbToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int size)
static void YV12ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
static void YUV420ToRGB(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)