1 /*M/////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // Intel License Agreement 10 // For Open Source Computer Vision Library 11 // 12 // Copyright (C) 2000, Intel Corporation, all rights reserved. 13 // Third party copyrights are property of their respective owners. 14 // 15 // Redistribution and use in source and binary forms, with or without modification, 16 // are permitted provided that the following conditions are met: 17 // 18 // * Redistribution's of source code must retain the above copyright notice, 19 // this list of conditions and the following disclaimer. 20 // 21 // * Redistribution's in binary form must reproduce the above copyright notice, 22 // this list of conditions and the following disclaimer in the documentation 23 // and/or other materials provided with the distribution. 24 // 25 // * The name of Intel Corporation may not be used to endorse or promote products 26 // derived from this software without specific prior written permission. 27 // 28 // This software is provided by the copyright holders and contributors "as is" and 29 // any express or implied warranties, including, but not limited to, the implied 30 // warranties of merchantability and fitness for a particular purpose are disclaimed. 31 // In no event shall the Intel Corporation or contributors be liable for any direct, 32 // indirect, incidental, special, exemplary, or consequential damages 33 // (including, but not limited to, procurement of substitute goods or services; 34 // loss of use, data, or profits; or business interruption) however caused 35 // and on any theory of liability, whether in contract, strict liability, 36 // or tort (including negligence or otherwise) arising in any way out of 37 // the use of this software, even if advised of the possibility of such damage. 38 // 39 //M*/ 40 41 /********************************* COPYRIGHT NOTICE *******************************\ 42 The function for RGB to Lab conversion is based on the MATLAB script 43 RGB2Lab.m translated by Mark Ruzon from C code by Yossi Rubner, 23 September 1997. 44 See the page [http://vision.stanford.edu/~ruzon/software/rgblab.html] 45 \**********************************************************************************/ 46 47 /********************************* COPYRIGHT NOTICE *******************************\ 48 Original code for Bayer->BGR/RGB conversion is provided by Dirk Schaefer 49 from MD-Mathematische Dienste GmbH. Below is the copyright notice: 50 51 IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 52 By downloading, copying, installing or using the software you agree 53 to this license. If you do not agree to this license, do not download, 54 install, copy or use the software. 55 56 Contributors License Agreement: 57 58 Copyright (c) 2002, 59 MD-Mathematische Dienste GmbH 60 Im Defdahl 5-10 61 44141 Dortmund 62 Germany 63 www.md-it.de 64 65 Redistribution and use in source and binary forms, 66 with or without modification, are permitted provided 67 that the following conditions are met: 68 69 Redistributions of source code must retain 70 the above copyright notice, this list of conditions and the following disclaimer. 71 Redistributions in binary form must reproduce the above copyright notice, 72 this list of conditions and the following disclaimer in the documentation 73 and/or other materials provided with the distribution. 74 The name of Contributor may not be used to endorse or promote products 75 derived from this software without specific prior written permission. 76 77 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 78 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 79 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 80 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE 81 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 82 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 83 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 84 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 85 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 86 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 87 THE POSSIBILITY OF SUCH DAMAGE. 88 \**********************************************************************************/ 89 90 #include "_cv.h" 91 92 typedef CvStatus (CV_STDCALL * CvColorCvtFunc0)( 93 const void* src, int srcstep, void* dst, int dststep, CvSize size ); 94 95 typedef CvStatus (CV_STDCALL * CvColorCvtFunc1)( 96 const void* src, int srcstep, void* dst, int dststep, 97 CvSize size, int param0 ); 98 99 typedef CvStatus (CV_STDCALL * CvColorCvtFunc2)( 100 const void* src, int srcstep, void* dst, int dststep, 101 CvSize size, int param0, int param1 ); 102 103 typedef CvStatus (CV_STDCALL * CvColorCvtFunc3)( 104 const void* src, int srcstep, void* dst, int dststep, 105 CvSize size, int param0, int param1, int param2 ); 106 107 /****************************************************************************************\ 108 * Various 3/4-channel to 3/4-channel RGB transformations * 109 \****************************************************************************************/ 110 111 #define CV_IMPL_BGRX2BGR( flavor, arrtype ) \ 112 static CvStatus CV_STDCALL \ 113 icvBGRx2BGR_##flavor##_CnC3R( const arrtype* src, int srcstep, \ 114 arrtype* dst, int dststep, \ 115 CvSize size, int src_cn, int blue_idx ) \ 116 { \ 117 int i; \ 118 \ 119 srcstep /= sizeof(src[0]); \ 120 dststep /= sizeof(dst[0]); \ 121 srcstep -= size.width*src_cn; \ 122 size.width *= 3; \ 123 \ 124 for( ; size.height--; src += srcstep, dst += dststep ) \ 125 { \ 126 for( i = 0; i < size.width; i += 3, src += src_cn ) \ 127 { \ 128 arrtype t0=src[blue_idx], t1=src[1], t2=src[blue_idx^2]; \ 129 dst[i] = t0; \ 130 dst[i+1] = t1; \ 131 dst[i+2] = t2; \ 132 } \ 133 } \ 134 \ 135 return CV_OK; \ 136 } 137 138 139 #define CV_IMPL_BGR2BGRX( flavor, arrtype ) \ 140 static CvStatus CV_STDCALL \ 141 icvBGR2BGRx_##flavor##_C3C4R( const arrtype* src, int srcstep, \ 142 arrtype* dst, int dststep, \ 143 CvSize size, int blue_idx ) \ 144 { \ 145 int i; \ 146 \ 147 srcstep /= sizeof(src[0]); \ 148 dststep /= sizeof(dst[0]); \ 149 srcstep -= size.width*3; \ 150 size.width *= 4; \ 151 \ 152 for( ; size.height--; src += srcstep, dst += dststep ) \ 153 { \ 154 for( i = 0; i < size.width; i += 4, src += 3 ) \ 155 { \ 156 arrtype t0=src[blue_idx], t1=src[1], t2=src[blue_idx^2]; \ 157 dst[i] = t0; \ 158 dst[i+1] = t1; \ 159 dst[i+2] = t2; \ 160 dst[i+3] = 0; \ 161 } \ 162 } \ 163 \ 164 return CV_OK; \ 165 } 166 167 168 #define CV_IMPL_BGRA2RGBA( flavor, arrtype ) \ 169 static CvStatus CV_STDCALL \ 170 icvBGRA2RGBA_##flavor##_C4R( const arrtype* src, int srcstep, \ 171 arrtype* dst, int dststep, CvSize size ) \ 172 { \ 173 int i; \ 174 \ 175 srcstep /= sizeof(src[0]); \ 176 dststep /= sizeof(dst[0]); \ 177 size.width *= 4; \ 178 \ 179 for( ; size.height--; src += srcstep, dst += dststep ) \ 180 { \ 181 for( i = 0; i < size.width; i += 4 ) \ 182 { \ 183 arrtype t0 = src[2], t1 = src[1], t2 = src[0], t3 = src[3]; \ 184 dst[i] = t0; \ 185 dst[i+1] = t1; \ 186 dst[i+2] = t2; \ 187 dst[i+3] = t3; \ 188 } \ 189 } \ 190 \ 191 return CV_OK; \ 192 } 193 194 195 CV_IMPL_BGRX2BGR( 8u, uchar ) 196 CV_IMPL_BGRX2BGR( 16u, ushort ) 197 CV_IMPL_BGRX2BGR( 32f, int ) 198 CV_IMPL_BGR2BGRX( 8u, uchar ) 199 CV_IMPL_BGR2BGRX( 16u, ushort ) 200 CV_IMPL_BGR2BGRX( 32f, int ) 201 CV_IMPL_BGRA2RGBA( 8u, uchar ) 202 CV_IMPL_BGRA2RGBA( 16u, ushort ) 203 CV_IMPL_BGRA2RGBA( 32f, int ) 204 205 206 /****************************************************************************************\ 207 * Transforming 16-bit (565 or 555) RGB to/from 24/32-bit (888[8]) RGB * 208 \****************************************************************************************/ 209 210 static CvStatus CV_STDCALL 211 icvBGR5x52BGRx_8u_C2CnR( const uchar* src, int srcstep, 212 uchar* dst, int dststep, 213 CvSize size, int dst_cn, 214 int blue_idx, int green_bits ) 215 { 216 int i; 217 assert( green_bits == 5 || green_bits == 6 ); 218 dststep -= size.width*dst_cn; 219 220 for( ; size.height--; src += srcstep, dst += dststep ) 221 { 222 if( green_bits == 6 ) 223 for( i = 0; i < size.width; i++, dst += dst_cn ) 224 { 225 unsigned t = ((const ushort*)src)[i]; 226 dst[blue_idx] = (uchar)(t << 3); 227 dst[1] = (uchar)((t >> 3) & ~3); 228 dst[blue_idx ^ 2] = (uchar)((t >> 8) & ~7); 229 if( dst_cn == 4 ) 230 dst[3] = 0; 231 } 232 else 233 for( i = 0; i < size.width; i++, dst += dst_cn ) 234 { 235 unsigned t = ((const ushort*)src)[i]; 236 dst[blue_idx] = (uchar)(t << 3); 237 dst[1] = (uchar)((t >> 2) & ~7); 238 dst[blue_idx ^ 2] = (uchar)((t >> 7) & ~7); 239 if( dst_cn == 4 ) 240 dst[3] = 0; 241 } 242 } 243 244 return CV_OK; 245 } 246 247 248 static CvStatus CV_STDCALL 249 icvBGRx2BGR5x5_8u_CnC2R( const uchar* src, int srcstep, 250 uchar* dst, int dststep, 251 CvSize size, int src_cn, 252 int blue_idx, int green_bits ) 253 { 254 int i; 255 srcstep -= size.width*src_cn; 256 257 for( ; size.height--; src += srcstep, dst += dststep ) 258 { 259 if( green_bits == 6 ) 260 for( i = 0; i < size.width; i++, src += src_cn ) 261 { 262 int t = (src[blue_idx] >> 3)|((src[1]&~3) << 3)|((src[blue_idx^2]&~7) << 8); 263 ((ushort*)dst)[i] = (ushort)t; 264 } 265 else 266 for( i = 0; i < size.width; i++, src += src_cn ) 267 { 268 int t = (src[blue_idx] >> 3)|((src[1]&~7) << 2)|((src[blue_idx^2]&~7) << 7); 269 ((ushort*)dst)[i] = (ushort)t; 270 } 271 } 272 273 return CV_OK; 274 } 275 276 277 278 /////////////////////////// IPP Color Conversion Functions ////////////////////////////// 279 280 icvRGB2XYZ_8u_C3R_t icvRGB2XYZ_8u_C3R_p = 0; 281 icvRGB2XYZ_16u_C3R_t icvRGB2XYZ_16u_C3R_p = 0; 282 icvRGB2XYZ_32f_C3R_t icvRGB2XYZ_32f_C3R_p = 0; 283 icvXYZ2RGB_8u_C3R_t icvXYZ2RGB_8u_C3R_p = 0; 284 icvXYZ2RGB_16u_C3R_t icvXYZ2RGB_16u_C3R_p = 0; 285 icvXYZ2RGB_32f_C3R_t icvXYZ2RGB_32f_C3R_p = 0; 286 287 icvRGB2HSV_8u_C3R_t icvRGB2HSV_8u_C3R_p = 0; 288 icvHSV2RGB_8u_C3R_t icvHSV2RGB_8u_C3R_p = 0; 289 290 icvBGR2Lab_8u_C3R_t icvBGR2Lab_8u_C3R_p = 0; 291 icvLab2BGR_8u_C3R_t icvLab2BGR_8u_C3R_p = 0; 292 293 icvRGB2HLS_8u_C3R_t icvRGB2HLS_8u_C3R_p = 0; 294 icvRGB2HLS_32f_C3R_t icvRGB2HLS_32f_C3R_p = 0; 295 icvHLS2RGB_8u_C3R_t icvHLS2RGB_8u_C3R_p = 0; 296 icvHLS2RGB_32f_C3R_t icvHLS2RGB_32f_C3R_p = 0; 297 298 icvRGB2Luv_8u_C3R_t icvRGB2Luv_8u_C3R_p = 0; 299 icvLuv2RGB_8u_C3R_t icvLuv2RGB_8u_C3R_p = 0; 300 301 //icvRGB2Luv_32f_C3R_t icvRGB2Luv_32f_C3R_p = 0; 302 //icvLuv2RGB_32f_C3R_t icvLuv2RGB_32f_C3R_p = 0; 303 //icvRGB2Luv_32f_C3R_t icvRGB2Luv_32f_C3R_p = 0; 304 //icvLuv2RGB_32f_C3R_t icvLuv2RGB_32f_C3R_p = 0; 305 306 307 #define CV_IMPL_BGRx2ABC_IPP( flavor, arrtype ) \ 308 static CvStatus CV_STDCALL \ 309 icvBGRx2ABC_IPP_##flavor##_CnC3R( const arrtype* src, int srcstep, \ 310 arrtype* dst, int dststep, CvSize size, int src_cn, \ 311 int blue_idx, CvColorCvtFunc0 ipp_func ) \ 312 { \ 313 int block_size = MIN(1 << 14, size.width); \ 314 arrtype* buffer; \ 315 int i, di, k; \ 316 int do_copy = src_cn > 3 || blue_idx != 2 || src == dst; \ 317 CvStatus status = CV_OK; \ 318 \ 319 if( !do_copy ) \ 320 return ipp_func( src, srcstep, dst, dststep, size ); \ 321 \ 322 srcstep /= sizeof(src[0]); \ 323 dststep /= sizeof(dst[0]); \ 324 \ 325 buffer = (arrtype*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); \ 326 srcstep -= size.width*src_cn; \ 327 \ 328 for( ; size.height--; src += srcstep, dst += dststep ) \ 329 { \ 330 for( i = 0; i < size.width; i += block_size ) \ 331 { \ 332 arrtype* dst1 = dst + i*3; \ 333 di = MIN(block_size, size.width - i); \ 334 \ 335 for( k = 0; k < di*3; k += 3, src += src_cn ) \ 336 { \ 337 arrtype b = src[blue_idx]; \ 338 arrtype g = src[1]; \ 339 arrtype r = src[blue_idx^2]; \ 340 buffer[k] = r; \ 341 buffer[k+1] = g; \ 342 buffer[k+2] = b; \ 343 } \ 344 \ 345 status = ipp_func( buffer, CV_STUB_STEP, \ 346 dst1, CV_STUB_STEP, cvSize(di,1) ); \ 347 if( status < 0 ) \ 348 return status; \ 349 } \ 350 } \ 351 \ 352 return CV_OK; \ 353 } 354 355 356 static CvStatus CV_STDCALL 357 icvBGRx2ABC_IPP_8u_CnC3R( const uchar* src, int srcstep, 358 uchar* dst, int dststep, CvSize size, int src_cn, 359 int blue_idx, CvColorCvtFunc0 ipp_func ) 360 { 361 int block_size = MIN(1 << 14, size.width); 362 uchar* buffer; 363 int i, di, k; 364 int do_copy = src_cn > 3 || blue_idx != 2 || src == dst; 365 CvStatus status = CV_OK; 366 367 if( !do_copy ) 368 return ipp_func( src, srcstep, dst, dststep, size ); 369 370 srcstep /= sizeof(src[0]); 371 dststep /= sizeof(dst[0]); 372 373 buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); 374 srcstep -= size.width*src_cn; 375 376 for( ; size.height--; src += srcstep, dst += dststep ) 377 { 378 for( i = 0; i < size.width; i += block_size ) 379 { 380 uchar* dst1 = dst + i*3; 381 di = MIN(block_size, size.width - i); 382 383 for( k = 0; k < di*3; k += 3, src += src_cn ) 384 { 385 uchar b = src[blue_idx]; 386 uchar g = src[1]; 387 uchar r = src[blue_idx^2]; 388 buffer[k] = r; 389 buffer[k+1] = g; 390 buffer[k+2] = b; 391 } 392 393 status = ipp_func( buffer, CV_STUB_STEP, 394 dst1, CV_STUB_STEP, cvSize(di,1) ); 395 if( status < 0 ) 396 return status; 397 } 398 } 399 400 return CV_OK; 401 } 402 403 404 405 //CV_IMPL_BGRx2ABC_IPP( 8u, uchar ) 406 CV_IMPL_BGRx2ABC_IPP( 16u, ushort ) 407 CV_IMPL_BGRx2ABC_IPP( 32f, float ) 408 409 #define CV_IMPL_ABC2BGRx_IPP( flavor, arrtype ) \ 410 static CvStatus CV_STDCALL \ 411 icvABC2BGRx_IPP_##flavor##_C3CnR( const arrtype* src, int srcstep, \ 412 arrtype* dst, int dststep, CvSize size, int dst_cn, \ 413 int blue_idx, CvColorCvtFunc0 ipp_func ) \ 414 { \ 415 int block_size = MIN(1 << 10, size.width); \ 416 arrtype* buffer; \ 417 int i, di, k; \ 418 int do_copy = dst_cn > 3 || blue_idx != 2 || src == dst; \ 419 CvStatus status = CV_OK; \ 420 \ 421 if( !do_copy ) \ 422 return ipp_func( src, srcstep, dst, dststep, size ); \ 423 \ 424 srcstep /= sizeof(src[0]); \ 425 dststep /= sizeof(dst[0]); \ 426 \ 427 buffer = (arrtype*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); \ 428 dststep -= size.width*dst_cn; \ 429 \ 430 for( ; size.height--; src += srcstep, dst += dststep ) \ 431 { \ 432 for( i = 0; i < size.width; i += block_size ) \ 433 { \ 434 const arrtype* src1 = src + i*3; \ 435 di = MIN(block_size, size.width - i); \ 436 \ 437 status = ipp_func( src1, CV_STUB_STEP, \ 438 buffer, CV_STUB_STEP, cvSize(di,1) ); \ 439 if( status < 0 ) \ 440 return status; \ 441 \ 442 for( k = 0; k < di*3; k += 3, dst += dst_cn ) \ 443 { \ 444 arrtype r = buffer[k]; \ 445 arrtype g = buffer[k+1]; \ 446 arrtype b = buffer[k+2]; \ 447 dst[blue_idx] = b; \ 448 dst[1] = g; \ 449 dst[blue_idx^2] = r; \ 450 if( dst_cn == 4 ) \ 451 dst[3] = 0; \ 452 } \ 453 } \ 454 } \ 455 \ 456 return CV_OK; \ 457 } 458 459 CV_IMPL_ABC2BGRx_IPP( 8u, uchar ) 460 CV_IMPL_ABC2BGRx_IPP( 16u, ushort ) 461 CV_IMPL_ABC2BGRx_IPP( 32f, float ) 462 463 464 ///////////////////////////////////////////////////////////////////////////////////////// 465 466 467 /****************************************************************************************\ 468 * Color to/from Grayscale * 469 \****************************************************************************************/ 470 471 #define fix(x,n) (int)((x)*(1 << (n)) + 0.5) 472 #define descale CV_DESCALE 473 474 #define cscGr_32f 0.299f 475 #define cscGg_32f 0.587f 476 #define cscGb_32f 0.114f 477 478 /* BGR/RGB -> Gray */ 479 #define csc_shift 14 480 #define cscGr fix(cscGr_32f,csc_shift) 481 #define cscGg fix(cscGg_32f,csc_shift) 482 #define cscGb /*fix(cscGb_32f,csc_shift)*/ ((1 << csc_shift) - cscGr - cscGg) 483 484 #define CV_IMPL_GRAY2BGRX( flavor, arrtype ) \ 485 static CvStatus CV_STDCALL \ 486 icvGray2BGRx_##flavor##_C1CnR( const arrtype* src, int srcstep, \ 487 arrtype* dst, int dststep, CvSize size, \ 488 int dst_cn ) \ 489 { \ 490 int i; \ 491 srcstep /= sizeof(src[0]); \ 492 dststep /= sizeof(src[0]); \ 493 dststep -= size.width*dst_cn; \ 494 \ 495 for( ; size.height--; src += srcstep, dst += dststep ) \ 496 { \ 497 if( dst_cn == 3 ) \ 498 for( i = 0; i < size.width; i++, dst += 3 ) \ 499 dst[0] = dst[1] = dst[2] = src[i]; \ 500 else \ 501 for( i = 0; i < size.width; i++, dst += 4 ) \ 502 { \ 503 dst[0] = dst[1] = dst[2] = src[i]; \ 504 dst[3] = 0; \ 505 } \ 506 } \ 507 \ 508 return CV_OK; \ 509 } 510 511 512 CV_IMPL_GRAY2BGRX( 8u, uchar ) 513 CV_IMPL_GRAY2BGRX( 16u, ushort ) 514 CV_IMPL_GRAY2BGRX( 32f, float ) 515 516 517 static CvStatus CV_STDCALL 518 icvBGR5x52Gray_8u_C2C1R( const uchar* src, int srcstep, 519 uchar* dst, int dststep, 520 CvSize size, int green_bits ) 521 { 522 int i; 523 assert( green_bits == 5 || green_bits == 6 ); 524 525 for( ; size.height--; src += srcstep, dst += dststep ) 526 { 527 if( green_bits == 6 ) 528 for( i = 0; i < size.width; i++ ) 529 { 530 int t = ((ushort*)src)[i]; 531 t = ((t << 3) & 0xf8)*cscGb + ((t >> 3) & 0xfc)*cscGg + 532 ((t >> 8) & 0xf8)*cscGr; 533 dst[i] = (uchar)CV_DESCALE(t,csc_shift); 534 } 535 else 536 for( i = 0; i < size.width; i++ ) 537 { 538 int t = ((ushort*)src)[i]; 539 t = ((t << 3) & 0xf8)*cscGb + ((t >> 2) & 0xf8)*cscGg + 540 ((t >> 7) & 0xf8)*cscGr; 541 dst[i] = (uchar)CV_DESCALE(t,csc_shift); 542 } 543 } 544 545 return CV_OK; 546 } 547 548 549 static CvStatus CV_STDCALL 550 icvGray2BGR5x5_8u_C1C2R( const uchar* src, int srcstep, 551 uchar* dst, int dststep, 552 CvSize size, int green_bits ) 553 { 554 int i; 555 assert( green_bits == 5 || green_bits == 6 ); 556 557 for( ; size.height--; src += srcstep, dst += dststep ) 558 { 559 if( green_bits == 6 ) 560 for( i = 0; i < size.width; i++ ) 561 { 562 int t = src[i]; 563 ((ushort*)dst)[i] = (ushort)((t >> 3)|((t & ~3) << 3)|((t & ~7) << 8)); 564 } 565 else 566 for( i = 0; i < size.width; i++ ) 567 { 568 int t = src[i] >> 3; 569 ((ushort*)dst)[i] = (ushort)(t|(t << 5)|(t << 10)); 570 } 571 } 572 573 return CV_OK; 574 } 575 576 577 static CvStatus CV_STDCALL 578 icvBGRx2Gray_8u_CnC1R( const uchar* src, int srcstep, 579 uchar* dst, int dststep, CvSize size, 580 int src_cn, int blue_idx ) 581 { 582 int i; 583 srcstep -= size.width*src_cn; 584 585 if( size.width*size.height >= 1024 ) 586 { 587 int* tab = (int*)cvStackAlloc( 256*3*sizeof(tab[0]) ); 588 int r = 0, g = 0, b = (1 << (csc_shift-1)); 589 590 for( i = 0; i < 256; i++ ) 591 { 592 tab[i] = b; 593 tab[i+256] = g; 594 tab[i+512] = r; 595 g += cscGg; 596 if( !blue_idx ) 597 b += cscGb, r += cscGr; 598 else 599 b += cscGr, r += cscGb; 600 } 601 602 for( ; size.height--; src += srcstep, dst += dststep ) 603 { 604 for( i = 0; i < size.width; i++, src += src_cn ) 605 { 606 int t0 = tab[src[0]] + tab[src[1] + 256] + tab[src[2] + 512]; 607 dst[i] = (uchar)(t0 >> csc_shift); 608 } 609 } 610 } 611 else 612 { 613 for( ; size.height--; src += srcstep, dst += dststep ) 614 { 615 for( i = 0; i < size.width; i++, src += src_cn ) 616 { 617 int t0 = src[blue_idx]*cscGb + src[1]*cscGg + src[blue_idx^2]*cscGr; 618 dst[i] = (uchar)CV_DESCALE(t0, csc_shift); 619 } 620 } 621 } 622 return CV_OK; 623 } 624 625 626 static CvStatus CV_STDCALL 627 icvBGRx2Gray_16u_CnC1R( const ushort* src, int srcstep, 628 ushort* dst, int dststep, CvSize size, 629 int src_cn, int blue_idx ) 630 { 631 int i; 632 int cb = cscGb, cr = cscGr; 633 srcstep /= sizeof(src[0]); 634 dststep /= sizeof(dst[0]); 635 srcstep -= size.width*src_cn; 636 637 if( blue_idx ) 638 cb = cscGr, cr = cscGb; 639 640 for( ; size.height--; src += srcstep, dst += dststep ) 641 for( i = 0; i < size.width; i++, src += src_cn ) 642 dst[i] = (ushort)CV_DESCALE((unsigned)(src[0]*cb + 643 src[1]*cscGg + src[2]*cr), csc_shift); 644 645 return CV_OK; 646 } 647 648 649 static CvStatus CV_STDCALL 650 icvBGRx2Gray_32f_CnC1R( const float* src, int srcstep, 651 float* dst, int dststep, CvSize size, 652 int src_cn, int blue_idx ) 653 { 654 int i; 655 float cb = cscGb_32f, cr = cscGr_32f; 656 if( blue_idx ) 657 cb = cscGr_32f, cr = cscGb_32f; 658 659 srcstep /= sizeof(src[0]); 660 dststep /= sizeof(dst[0]); 661 srcstep -= size.width*src_cn; 662 for( ; size.height--; src += srcstep, dst += dststep ) 663 for( i = 0; i < size.width; i++, src += src_cn ) 664 dst[i] = src[0]*cb + src[1]*cscGg_32f + src[2]*cr; 665 666 return CV_OK; 667 } 668 669 670 /****************************************************************************************\ 671 * RGB <-> YCrCb * 672 \****************************************************************************************/ 673 674 /* BGR/RGB -> YCrCb */ 675 #define yuvYr_32f cscGr_32f 676 #define yuvYg_32f cscGg_32f 677 #define yuvYb_32f cscGb_32f 678 #define yuvCr_32f 0.713f 679 #define yuvCb_32f 0.564f 680 681 #define yuv_shift 14 682 #define yuvYr fix(yuvYr_32f,yuv_shift) 683 #define yuvYg fix(yuvYg_32f,yuv_shift) 684 #define yuvYb fix(yuvYb_32f,yuv_shift) 685 #define yuvCr fix(yuvCr_32f,yuv_shift) 686 #define yuvCb fix(yuvCb_32f,yuv_shift) 687 688 #define yuv_descale(x) CV_DESCALE((x), yuv_shift) 689 #define yuv_prescale(x) ((x) << yuv_shift) 690 691 #define yuvRCr_32f 1.403f 692 #define yuvGCr_32f (-0.714f) 693 #define yuvGCb_32f (-0.344f) 694 #define yuvBCb_32f 1.773f 695 696 #define yuvRCr fix(yuvRCr_32f,yuv_shift) 697 #define yuvGCr (-fix(-yuvGCr_32f,yuv_shift)) 698 #define yuvGCb (-fix(-yuvGCb_32f,yuv_shift)) 699 #define yuvBCb fix(yuvBCb_32f,yuv_shift) 700 701 #define CV_IMPL_BGRx2YCrCb( flavor, arrtype, worktype, scale_macro, cast_macro, \ 702 YUV_YB, YUV_YG, YUV_YR, YUV_CR, YUV_CB, YUV_Cx_BIAS ) \ 703 static CvStatus CV_STDCALL \ 704 icvBGRx2YCrCb_##flavor##_CnC3R( const arrtype* src, int srcstep, \ 705 arrtype* dst, int dststep, CvSize size, int src_cn, int blue_idx ) \ 706 { \ 707 int i; \ 708 srcstep /= sizeof(src[0]); \ 709 dststep /= sizeof(src[0]); \ 710 srcstep -= size.width*src_cn; \ 711 size.width *= 3; \ 712 \ 713 for( ; size.height--; src += srcstep, dst += dststep ) \ 714 { \ 715 for( i = 0; i < size.width; i += 3, src += src_cn ) \ 716 { \ 717 worktype b = src[blue_idx], r = src[2^blue_idx], y; \ 718 y = scale_macro(b*YUV_YB + src[1]*YUV_YG + r*YUV_YR); \ 719 r = scale_macro((r - y)*YUV_CR) + YUV_Cx_BIAS; \ 720 b = scale_macro((b - y)*YUV_CB) + YUV_Cx_BIAS; \ 721 dst[i] = cast_macro(y); \ 722 dst[i+1] = cast_macro(r); \ 723 dst[i+2] = cast_macro(b); \ 724 } \ 725 } \ 726 \ 727 return CV_OK; \ 728 } 729 730 731 CV_IMPL_BGRx2YCrCb( 8u, uchar, int, yuv_descale, CV_CAST_8U, 732 yuvYb, yuvYg, yuvYr, yuvCr, yuvCb, 128 ) 733 734 CV_IMPL_BGRx2YCrCb( 16u, ushort, int, yuv_descale, CV_CAST_16U, 735 yuvYb, yuvYg, yuvYr, yuvCr, yuvCb, 32768 ) 736 737 CV_IMPL_BGRx2YCrCb( 32f, float, float, CV_NOP, CV_NOP, 738 yuvYb_32f, yuvYg_32f, yuvYr_32f, yuvCr_32f, yuvCb_32f, 0.5f ) 739 740 741 #define CV_IMPL_YCrCb2BGRx( flavor, arrtype, worktype, prescale_macro, \ 742 scale_macro, cast_macro, YUV_BCb, YUV_GCr, YUV_GCb, YUV_RCr, YUV_Cx_BIAS)\ 743 static CvStatus CV_STDCALL \ 744 icvYCrCb2BGRx_##flavor##_C3CnR( const arrtype* src, int srcstep, \ 745 arrtype* dst, int dststep, CvSize size, \ 746 int dst_cn, int blue_idx ) \ 747 { \ 748 int i; \ 749 srcstep /= sizeof(src[0]); \ 750 dststep /= sizeof(src[0]); \ 751 dststep -= size.width*dst_cn; \ 752 size.width *= 3; \ 753 \ 754 for( ; size.height--; src += srcstep, dst += dststep ) \ 755 { \ 756 for( i = 0; i < size.width; i += 3, dst += dst_cn ) \ 757 { \ 758 worktype Y = prescale_macro(src[i]), \ 759 Cr = src[i+1] - YUV_Cx_BIAS, \ 760 Cb = src[i+2] - YUV_Cx_BIAS; \ 761 worktype b, g, r; \ 762 b = scale_macro( Y + YUV_BCb*Cb ); \ 763 g = scale_macro( Y + YUV_GCr*Cr + YUV_GCb*Cb ); \ 764 r = scale_macro( Y + YUV_RCr*Cr ); \ 765 \ 766 dst[blue_idx] = cast_macro(b); \ 767 dst[1] = cast_macro(g); \ 768 dst[blue_idx^2] = cast_macro(r); \ 769 if( dst_cn == 4 ) \ 770 dst[3] = 0; \ 771 } \ 772 } \ 773 \ 774 return CV_OK; \ 775 } 776 777 778 CV_IMPL_YCrCb2BGRx( 8u, uchar, int, yuv_prescale, yuv_descale, CV_CAST_8U, 779 yuvBCb, yuvGCr, yuvGCb, yuvRCr, 128 ) 780 781 CV_IMPL_YCrCb2BGRx( 16u, ushort, int, yuv_prescale, yuv_descale, CV_CAST_16U, 782 yuvBCb, yuvGCr, yuvGCb, yuvRCr, 32768 ) 783 784 CV_IMPL_YCrCb2BGRx( 32f, float, float, CV_NOP, CV_NOP, CV_NOP, 785 yuvBCb_32f, yuvGCr_32f, yuvGCb_32f, yuvRCr_32f, 0.5f ) 786 787 788 /****************************************************************************************\ 789 * RGB <-> XYZ * 790 \****************************************************************************************/ 791 792 #define xyzXr_32f 0.412453f 793 #define xyzXg_32f 0.357580f 794 #define xyzXb_32f 0.180423f 795 796 #define xyzYr_32f 0.212671f 797 #define xyzYg_32f 0.715160f 798 #define xyzYb_32f 0.072169f 799 800 #define xyzZr_32f 0.019334f 801 #define xyzZg_32f 0.119193f 802 #define xyzZb_32f 0.950227f 803 804 #define xyzRx_32f 3.240479f 805 #define xyzRy_32f (-1.53715f) 806 #define xyzRz_32f (-0.498535f) 807 808 #define xyzGx_32f (-0.969256f) 809 #define xyzGy_32f 1.875991f 810 #define xyzGz_32f 0.041556f 811 812 #define xyzBx_32f 0.055648f 813 #define xyzBy_32f (-0.204043f) 814 #define xyzBz_32f 1.057311f 815 816 #define xyz_shift 10 817 #define xyzXr_32s fix(xyzXr_32f, xyz_shift ) 818 #define xyzXg_32s fix(xyzXg_32f, xyz_shift ) 819 #define xyzXb_32s fix(xyzXb_32f, xyz_shift ) 820 821 #define xyzYr_32s fix(xyzYr_32f, xyz_shift ) 822 #define xyzYg_32s fix(xyzYg_32f, xyz_shift ) 823 #define xyzYb_32s fix(xyzYb_32f, xyz_shift ) 824 825 #define xyzZr_32s fix(xyzZr_32f, xyz_shift ) 826 #define xyzZg_32s fix(xyzZg_32f, xyz_shift ) 827 #define xyzZb_32s fix(xyzZb_32f, xyz_shift ) 828 829 #define xyzRx_32s fix(3.240479f, xyz_shift ) 830 #define xyzRy_32s -fix(1.53715f, xyz_shift ) 831 #define xyzRz_32s -fix(0.498535f, xyz_shift ) 832 833 #define xyzGx_32s -fix(0.969256f, xyz_shift ) 834 #define xyzGy_32s fix(1.875991f, xyz_shift ) 835 #define xyzGz_32s fix(0.041556f, xyz_shift ) 836 837 #define xyzBx_32s fix(0.055648f, xyz_shift ) 838 #define xyzBy_32s -fix(0.204043f, xyz_shift ) 839 #define xyzBz_32s fix(1.057311f, xyz_shift ) 840 841 #define xyz_descale(x) CV_DESCALE((x),xyz_shift) 842 843 #define CV_IMPL_BGRx2XYZ( flavor, arrtype, worktype, \ 844 scale_macro, cast_macro, suffix ) \ 845 static CvStatus CV_STDCALL \ 846 icvBGRx2XYZ_##flavor##_CnC3R( const arrtype* src, int srcstep, \ 847 arrtype* dst, int dststep, CvSize size, \ 848 int src_cn, int blue_idx ) \ 849 { \ 850 int i; \ 851 worktype t, matrix[] = \ 852 { \ 853 xyzXb##suffix, xyzXg##suffix, xyzXr##suffix, \ 854 xyzYb##suffix, xyzYg##suffix, xyzYr##suffix, \ 855 xyzZb##suffix, xyzZg##suffix, xyzZr##suffix \ 856 }; \ 857 \ 858 if( icvRGB2XYZ_##flavor##_C3R_p ) \ 859 return icvBGRx2ABC_IPP_##flavor##_CnC3R( src, srcstep, \ 860 dst, dststep, size, src_cn, blue_idx, \ 861 icvRGB2XYZ_##flavor##_C3R_p ); \ 862 \ 863 srcstep /= sizeof(src[0]); \ 864 dststep /= sizeof(dst[0]); \ 865 srcstep -= size.width*src_cn; \ 866 size.width *= 3; \ 867 \ 868 if( blue_idx ) \ 869 { \ 870 CV_SWAP( matrix[0], matrix[2], t ); \ 871 CV_SWAP( matrix[3], matrix[5], t ); \ 872 CV_SWAP( matrix[6], matrix[8], t ); \ 873 } \ 874 \ 875 for( ; size.height--; src += srcstep, dst += dststep ) \ 876 { \ 877 for( i = 0; i < size.width; i += 3, src += src_cn ) \ 878 { \ 879 worktype x = scale_macro(src[0]*matrix[0] + \ 880 src[1]*matrix[1] + src[2]*matrix[2]); \ 881 worktype y = scale_macro(src[0]*matrix[3] + \ 882 src[1]*matrix[4] + src[2]*matrix[5]); \ 883 worktype z = scale_macro(src[0]*matrix[6] + \ 884 src[1]*matrix[7] + src[2]*matrix[8]); \ 885 \ 886 dst[i] = (arrtype)(x); \ 887 dst[i+1] = (arrtype)(y); \ 888 dst[i+2] = cast_macro(z); /*sum of weights for z > 1*/ \ 889 } \ 890 } \ 891 \ 892 return CV_OK; \ 893 } 894 895 896 CV_IMPL_BGRx2XYZ( 8u, uchar, int, xyz_descale, CV_CAST_8U, _32s ) 897 CV_IMPL_BGRx2XYZ( 16u, ushort, int, xyz_descale, CV_CAST_16U, _32s ) 898 CV_IMPL_BGRx2XYZ( 32f, float, float, CV_NOP, CV_NOP, _32f ) 899 900 901 #define CV_IMPL_XYZ2BGRx( flavor, arrtype, worktype, scale_macro, \ 902 cast_macro, suffix ) \ 903 static CvStatus CV_STDCALL \ 904 icvXYZ2BGRx_##flavor##_C3CnR( const arrtype* src, int srcstep, \ 905 arrtype* dst, int dststep, CvSize size, \ 906 int dst_cn, int blue_idx ) \ 907 { \ 908 int i; \ 909 worktype t, matrix[] = \ 910 { \ 911 xyzBx##suffix, xyzBy##suffix, xyzBz##suffix, \ 912 xyzGx##suffix, xyzGy##suffix, xyzGz##suffix, \ 913 xyzRx##suffix, xyzRy##suffix, xyzRz##suffix \ 914 }; \ 915 \ 916 if( icvXYZ2RGB_##flavor##_C3R_p ) \ 917 return icvABC2BGRx_IPP_##flavor##_C3CnR( src, srcstep, \ 918 dst, dststep, size, dst_cn, blue_idx, \ 919 icvXYZ2RGB_##flavor##_C3R_p ); \ 920 \ 921 srcstep /= sizeof(src[0]); \ 922 dststep /= sizeof(dst[0]); \ 923 dststep -= size.width*dst_cn; \ 924 size.width *= 3; \ 925 \ 926 if( blue_idx ) \ 927 { \ 928 CV_SWAP( matrix[0], matrix[6], t ); \ 929 CV_SWAP( matrix[1], matrix[7], t ); \ 930 CV_SWAP( matrix[2], matrix[8], t ); \ 931 } \ 932 \ 933 for( ; size.height--; src += srcstep, dst += dststep ) \ 934 { \ 935 for( i = 0; i < size.width; i += 3, dst += dst_cn ) \ 936 { \ 937 worktype b = scale_macro(src[i]*matrix[0] + \ 938 src[i+1]*matrix[1] + src[i+2]*matrix[2]); \ 939 worktype g = scale_macro(src[i]*matrix[3] + \ 940 src[i+1]*matrix[4] + src[i+2]*matrix[5]); \ 941 worktype r = scale_macro(src[i]*matrix[6] + \ 942 src[i+1]*matrix[7] + src[i+2]*matrix[8]); \ 943 \ 944 dst[0] = cast_macro(b); \ 945 dst[1] = cast_macro(g); \ 946 dst[2] = cast_macro(r); \ 947 \ 948 if( dst_cn == 4 ) \ 949 dst[3] = 0; \ 950 } \ 951 } \ 952 \ 953 return CV_OK; \ 954 } 955 956 CV_IMPL_XYZ2BGRx( 8u, uchar, int, xyz_descale, CV_CAST_8U, _32s ) 957 CV_IMPL_XYZ2BGRx( 16u, ushort, int, xyz_descale, CV_CAST_16U, _32s ) 958 CV_IMPL_XYZ2BGRx( 32f, float, float, CV_NOP, CV_NOP, _32f ) 959 960 961 /****************************************************************************************\ 962 * Non-linear Color Space Transformations * 963 \****************************************************************************************/ 964 965 // driver color space conversion function for 8u arrays that uses 32f function 966 // with appropriate pre- and post-scaling. 967 static CvStatus CV_STDCALL 968 icvABC2BGRx_8u_C3CnR( const uchar* src, int srcstep, uchar* dst, int dststep, 969 CvSize size, int dst_cn, int blue_idx, CvColorCvtFunc2 cvtfunc_32f, 970 const float* pre_coeffs, int postscale ) 971 { 972 int block_size = MIN(1 << 8, size.width); 973 float* buffer = (float*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); 974 int i, di, k; 975 CvStatus status = CV_OK; 976 977 dststep -= size.width*dst_cn; 978 979 for( ; size.height--; src += srcstep, dst += dststep ) 980 { 981 for( i = 0; i < size.width; i += block_size ) 982 { 983 const uchar* src1 = src + i*3; 984 di = MIN(block_size, size.width - i); 985 986 for( k = 0; k < di*3; k += 3 ) 987 { 988 float a = CV_8TO32F(src1[k])*pre_coeffs[0] + pre_coeffs[1]; 989 float b = CV_8TO32F(src1[k+1])*pre_coeffs[2] + pre_coeffs[3]; 990 float c = CV_8TO32F(src1[k+2])*pre_coeffs[4] + pre_coeffs[5]; 991 buffer[k] = a; 992 buffer[k+1] = b; 993 buffer[k+2] = c; 994 } 995 996 status = cvtfunc_32f( buffer, 0, buffer, 0, cvSize(di,1), 3, blue_idx ); 997 if( status < 0 ) 998 return status; 999 1000 if( postscale ) 1001 { 1002 for( k = 0; k < di*3; k += 3, dst += dst_cn ) 1003 { 1004 int b = cvRound(buffer[k]*255.); 1005 int g = cvRound(buffer[k+1]*255.); 1006 int r = cvRound(buffer[k+2]*255.); 1007 1008 dst[0] = CV_CAST_8U(b); 1009 dst[1] = CV_CAST_8U(g); 1010 dst[2] = CV_CAST_8U(r); 1011 if( dst_cn == 4 ) 1012 dst[3] = 0; 1013 } 1014 } 1015 else 1016 { 1017 for( k = 0; k < di*3; k += 3, dst += dst_cn ) 1018 { 1019 int b = cvRound(buffer[k]); 1020 int g = cvRound(buffer[k+1]); 1021 int r = cvRound(buffer[k+2]); 1022 1023 dst[0] = CV_CAST_8U(b); 1024 dst[1] = CV_CAST_8U(g); 1025 dst[2] = CV_CAST_8U(r); 1026 if( dst_cn == 4 ) 1027 dst[3] = 0; 1028 } 1029 } 1030 } 1031 } 1032 1033 return CV_OK; 1034 } 1035 1036 1037 // driver color space conversion function for 8u arrays that uses 32f function 1038 // with appropriate pre- and post-scaling. 1039 static CvStatus CV_STDCALL 1040 icvBGRx2ABC_8u_CnC3R( const uchar* src, int srcstep, uchar* dst, int dststep, 1041 CvSize size, int src_cn, int blue_idx, CvColorCvtFunc2 cvtfunc_32f, 1042 int prescale, const float* post_coeffs ) 1043 { 1044 int block_size = MIN(1 << 8, size.width); 1045 float* buffer = (float*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); 1046 int i, di, k; 1047 CvStatus status = CV_OK; 1048 1049 srcstep -= size.width*src_cn; 1050 1051 for( ; size.height--; src += srcstep, dst += dststep ) 1052 { 1053 for( i = 0; i < size.width; i += block_size ) 1054 { 1055 uchar* dst1 = dst + i*3; 1056 di = MIN(block_size, size.width - i); 1057 1058 if( prescale ) 1059 { 1060 for( k = 0; k < di*3; k += 3, src += src_cn ) 1061 { 1062 float b = CV_8TO32F(src[0])*0.0039215686274509803f; 1063 float g = CV_8TO32F(src[1])*0.0039215686274509803f; 1064 float r = CV_8TO32F(src[2])*0.0039215686274509803f; 1065 1066 buffer[k] = b; 1067 buffer[k+1] = g; 1068 buffer[k+2] = r; 1069 } 1070 } 1071 else 1072 { 1073 for( k = 0; k < di*3; k += 3, src += src_cn ) 1074 { 1075 float b = CV_8TO32F(src[0]); 1076 float g = CV_8TO32F(src[1]); 1077 float r = CV_8TO32F(src[2]); 1078 1079 buffer[k] = b; 1080 buffer[k+1] = g; 1081 buffer[k+2] = r; 1082 } 1083 } 1084 1085 status = cvtfunc_32f( buffer, 0, buffer, 0, cvSize(di,1), 3, blue_idx ); 1086 if( status < 0 ) 1087 return status; 1088 1089 for( k = 0; k < di*3; k += 3 ) 1090 { 1091 int a = cvRound( buffer[k]*post_coeffs[0] + post_coeffs[1] ); 1092 int b = cvRound( buffer[k+1]*post_coeffs[2] + post_coeffs[3] ); 1093 int c = cvRound( buffer[k+2]*post_coeffs[4] + post_coeffs[5] ); 1094 dst1[k] = CV_CAST_8U(a); 1095 dst1[k+1] = CV_CAST_8U(b); 1096 dst1[k+2] = CV_CAST_8U(c); 1097 } 1098 } 1099 } 1100 1101 return CV_OK; 1102 } 1103 1104 1105 /****************************************************************************************\ 1106 * RGB <-> HSV * 1107 \****************************************************************************************/ 1108 1109 static const uchar icvHue255To180[] = 1110 { 1111 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 1112 11, 12, 13, 13, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 1113 23, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 1114 34, 35, 35, 36, 37, 37, 38, 39, 40, 40, 41, 42, 42, 43, 44, 44, 1115 45, 46, 47, 47, 48, 49, 49, 50, 51, 52, 52, 53, 54, 54, 55, 56, 1116 56, 57, 58, 59, 59, 60, 61, 61, 62, 63, 64, 64, 65, 66, 66, 67, 1117 68, 68, 69, 70, 71, 71, 72, 73, 73, 74, 75, 76, 76, 77, 78, 78, 1118 79, 80, 80, 81, 82, 83, 83, 84, 85, 85, 86, 87, 88, 88, 89, 90, 1119 90, 91, 92, 92, 93, 94, 95, 95, 96, 97, 97, 98, 99, 100, 100, 101, 1120 102, 102, 103, 104, 104, 105, 106, 107, 107, 108, 109, 109, 110, 111, 112, 112, 1121 113, 114, 114, 115, 116, 116, 117, 118, 119, 119, 120, 121, 121, 122, 123, 124, 1122 124, 125, 126, 126, 127, 128, 128, 129, 130, 131, 131, 132, 133, 133, 134, 135, 1123 136, 136, 137, 138, 138, 139, 140, 140, 141, 142, 143, 143, 144, 145, 145, 146, 1124 147, 148, 148, 149, 150, 150, 151, 152, 152, 153, 154, 155, 155, 156, 157, 157, 1125 158, 159, 160, 160, 161, 162, 162, 163, 164, 164, 165, 166, 167, 167, 168, 169, 1126 169, 170, 171, 172, 172, 173, 174, 174, 175, 176, 176, 177, 178, 179, 179, 180 1127 }; 1128 1129 1130 static const uchar icvHue180To255[] = 1131 { 1132 0, 1, 3, 4, 6, 7, 9, 10, 11, 13, 14, 16, 17, 18, 20, 21, 1133 23, 24, 26, 27, 28, 30, 31, 33, 34, 35, 37, 38, 40, 41, 43, 44, 1134 45, 47, 48, 50, 51, 52, 54, 55, 57, 58, 60, 61, 62, 64, 65, 67, 1135 68, 69, 71, 72, 74, 75, 77, 78, 79, 81, 82, 84, 85, 86, 88, 89, 1136 91, 92, 94, 95, 96, 98, 99, 101, 102, 103, 105, 106, 108, 109, 111, 112, 1137 113, 115, 116, 118, 119, 120, 122, 123, 125, 126, 128, 129, 130, 132, 133, 135, 1138 136, 137, 139, 140, 142, 143, 145, 146, 147, 149, 150, 152, 153, 154, 156, 157, 1139 159, 160, 162, 163, 164, 166, 167, 169, 170, 171, 173, 174, 176, 177, 179, 180, 1140 181, 183, 184, 186, 187, 188, 190, 191, 193, 194, 196, 197, 198, 200, 201, 203, 1141 204, 205, 207, 208, 210, 211, 213, 214, 215, 217, 218, 220, 221, 222, 224, 225, 1142 227, 228, 230, 231, 232, 234, 235, 237, 238, 239, 241, 242, 244, 245, 247, 248, 1143 249, 251, 252, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1144 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1145 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1146 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1147 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1148 }; 1149 1150 1151 static CvStatus CV_STDCALL 1152 icvBGRx2HSV_8u_CnC3R( const uchar* src, int srcstep, uchar* dst, int dststep, 1153 CvSize size, int src_cn, int blue_idx ) 1154 { 1155 const int hsv_shift = 12; 1156 1157 static const int div_table[] = { 1158 0, 1044480, 522240, 348160, 261120, 208896, 174080, 149211, 1159 130560, 116053, 104448, 94953, 87040, 80345, 74606, 69632, 1160 65280, 61440, 58027, 54973, 52224, 49737, 47476, 45412, 1161 43520, 41779, 40172, 38684, 37303, 36017, 34816, 33693, 1162 32640, 31651, 30720, 29842, 29013, 28229, 27486, 26782, 1163 26112, 25475, 24869, 24290, 23738, 23211, 22706, 22223, 1164 21760, 21316, 20890, 20480, 20086, 19707, 19342, 18991, 1165 18651, 18324, 18008, 17703, 17408, 17123, 16846, 16579, 1166 16320, 16069, 15825, 15589, 15360, 15137, 14921, 14711, 1167 14507, 14308, 14115, 13926, 13743, 13565, 13391, 13221, 1168 13056, 12895, 12738, 12584, 12434, 12288, 12145, 12006, 1169 11869, 11736, 11605, 11478, 11353, 11231, 11111, 10995, 1170 10880, 10768, 10658, 10550, 10445, 10341, 10240, 10141, 1171 10043, 9947, 9854, 9761, 9671, 9582, 9495, 9410, 1172 9326, 9243, 9162, 9082, 9004, 8927, 8852, 8777, 1173 8704, 8632, 8561, 8492, 8423, 8356, 8290, 8224, 1174 8160, 8097, 8034, 7973, 7913, 7853, 7795, 7737, 1175 7680, 7624, 7569, 7514, 7461, 7408, 7355, 7304, 1176 7253, 7203, 7154, 7105, 7057, 7010, 6963, 6917, 1177 6872, 6827, 6782, 6739, 6695, 6653, 6611, 6569, 1178 6528, 6487, 6447, 6408, 6369, 6330, 6292, 6254, 1179 6217, 6180, 6144, 6108, 6073, 6037, 6003, 5968, 1180 5935, 5901, 5868, 5835, 5803, 5771, 5739, 5708, 1181 5677, 5646, 5615, 5585, 5556, 5526, 5497, 5468, 1182 5440, 5412, 5384, 5356, 5329, 5302, 5275, 5249, 1183 5222, 5196, 5171, 5145, 5120, 5095, 5070, 5046, 1184 5022, 4998, 4974, 4950, 4927, 4904, 4881, 4858, 1185 4836, 4813, 4791, 4769, 4748, 4726, 4705, 4684, 1186 4663, 4642, 4622, 4601, 4581, 4561, 4541, 4522, 1187 4502, 4483, 4464, 4445, 4426, 4407, 4389, 4370, 1188 4352, 4334, 4316, 4298, 4281, 4263, 4246, 4229, 1189 4212, 4195, 4178, 4161, 4145, 4128, 4112, 4096 1190 }; 1191 1192 int i; 1193 if( icvRGB2HSV_8u_C3R_p ) 1194 { 1195 CvStatus status = icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size, 1196 src_cn, blue_idx, icvRGB2HSV_8u_C3R_p ); 1197 if( status >= 0 ) 1198 { 1199 size.width *= 3; 1200 for( ; size.height--; dst += dststep ) 1201 { 1202 for( i = 0; i <= size.width - 12; i += 12 ) 1203 { 1204 uchar t0 = icvHue255To180[dst[i]], t1 = icvHue255To180[dst[i+3]]; 1205 dst[i] = t0; dst[i+3] = t1; 1206 t0 = icvHue255To180[dst[i+6]]; t1 = icvHue255To180[dst[i+9]]; 1207 dst[i+6] = t0; dst[i+9] = t1; 1208 } 1209 for( ; i < size.width; i += 3 ) 1210 dst[i] = icvHue255To180[dst[i]]; 1211 } 1212 } 1213 return status; 1214 } 1215 1216 srcstep -= size.width*src_cn; 1217 size.width *= 3; 1218 1219 for( ; size.height--; src += srcstep, dst += dststep ) 1220 { 1221 for( i = 0; i < size.width; i += 3, src += src_cn ) 1222 { 1223 int b = (src)[blue_idx], g = (src)[1], r = (src)[2^blue_idx]; 1224 int h, s, v = b; 1225 int vmin = b, diff; 1226 int vr, vg; 1227 1228 CV_CALC_MAX_8U( v, g ); 1229 CV_CALC_MAX_8U( v, r ); 1230 CV_CALC_MIN_8U( vmin, g ); 1231 CV_CALC_MIN_8U( vmin, r ); 1232 1233 diff = v - vmin; 1234 vr = v == r ? -1 : 0; 1235 vg = v == g ? -1 : 0; 1236 1237 s = diff * div_table[v] >> hsv_shift; 1238 h = (vr & (g - b)) + 1239 (~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff)))); 1240 h = ((h * div_table[diff] * 15 + (1 << (hsv_shift + 6))) >> (7 + hsv_shift))\ 1241 + (h < 0 ? 30*6 : 0); 1242 1243 dst[i] = (uchar)h; 1244 dst[i+1] = (uchar)s; 1245 dst[i+2] = (uchar)v; 1246 } 1247 } 1248 1249 return CV_OK; 1250 } 1251 1252 1253 static CvStatus CV_STDCALL 1254 icvBGRx2HSV_32f_CnC3R( const float* src, int srcstep, 1255 float* dst, int dststep, 1256 CvSize size, int src_cn, int blue_idx ) 1257 { 1258 int i; 1259 srcstep /= sizeof(src[0]); 1260 dststep /= sizeof(dst[0]); 1261 srcstep -= size.width*src_cn; 1262 size.width *= 3; 1263 1264 for( ; size.height--; src += srcstep, dst += dststep ) 1265 { 1266 for( i = 0; i < size.width; i += 3, src += src_cn ) 1267 { 1268 float b = src[blue_idx], g = src[1], r = src[2^blue_idx]; 1269 float h, s, v; 1270 1271 float vmin, diff; 1272 1273 v = vmin = r; 1274 if( v < g ) v = g; 1275 if( v < b ) v = b; 1276 if( vmin > g ) vmin = g; 1277 if( vmin > b ) vmin = b; 1278 1279 diff = v - vmin; 1280 s = diff/(float)(fabs(v) + FLT_EPSILON); 1281 diff = (float)(60./(diff + FLT_EPSILON)); 1282 if( v == r ) 1283 h = (g - b)*diff; 1284 else if( v == g ) 1285 h = (b - r)*diff + 120.f; 1286 else 1287 h = (r - g)*diff + 240.f; 1288 1289 if( h < 0 ) h += 360.f; 1290 1291 dst[i] = h; 1292 dst[i+1] = s; 1293 dst[i+2] = v; 1294 } 1295 } 1296 1297 return CV_OK; 1298 } 1299 1300 1301 static CvStatus CV_STDCALL 1302 icvHSV2BGRx_32f_C3CnR( const float* src, int srcstep, float* dst, 1303 int dststep, CvSize size, int dst_cn, int blue_idx ) 1304 { 1305 int i; 1306 srcstep /= sizeof(src[0]); 1307 dststep /= sizeof(dst[0]); 1308 dststep -= size.width*dst_cn; 1309 size.width *= 3; 1310 1311 for( ; size.height--; src += srcstep, dst += dststep ) 1312 { 1313 for( i = 0; i < size.width; i += 3, dst += dst_cn ) 1314 { 1315 float h = src[i], s = src[i+1], v = src[i+2]; 1316 float b, g, r; 1317 1318 if( s == 0 ) 1319 b = g = r = v; 1320 else 1321 { 1322 static const int sector_data[][3]= 1323 {{1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0}}; 1324 float tab[4]; 1325 int sector; 1326 h *= 0.016666666666666666f; // h /= 60; 1327 if( h < 0 ) 1328 do h += 6; while( h < 0 ); 1329 else if( h >= 6 ) 1330 do h -= 6; while( h >= 6 ); 1331 sector = cvFloor(h); 1332 h -= sector; 1333 1334 tab[0] = v; 1335 tab[1] = v*(1.f - s); 1336 tab[2] = v*(1.f - s*h); 1337 tab[3] = v*(1.f - s*(1.f - h)); 1338 1339 b = tab[sector_data[sector][0]]; 1340 g = tab[sector_data[sector][1]]; 1341 r = tab[sector_data[sector][2]]; 1342 } 1343 1344 dst[blue_idx] = b; 1345 dst[1] = g; 1346 dst[blue_idx^2] = r; 1347 if( dst_cn == 4 ) 1348 dst[3] = 0; 1349 } 1350 } 1351 1352 return CV_OK; 1353 } 1354 1355 1356 static CvStatus CV_STDCALL 1357 icvHSV2BGRx_8u_C3CnR( const uchar* src, int srcstep, uchar* dst, int dststep, 1358 CvSize size, int dst_cn, int blue_idx ) 1359 { 1360 static const float pre_coeffs[] = { 2.f, 0.f, 0.0039215686274509803f, 0.f, 1.f, 0.f }; 1361 1362 if( icvHSV2RGB_8u_C3R_p ) 1363 { 1364 int block_size = MIN(1 << 14, size.width); 1365 uchar* buffer; 1366 int i, di, k; 1367 CvStatus status = CV_OK; 1368 1369 buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); 1370 dststep -= size.width*dst_cn; 1371 1372 for( ; size.height--; src += srcstep, dst += dststep ) 1373 { 1374 for( i = 0; i < size.width; i += block_size ) 1375 { 1376 const uchar* src1 = src + i*3; 1377 di = MIN(block_size, size.width - i); 1378 for( k = 0; k < di*3; k += 3 ) 1379 { 1380 uchar h = icvHue180To255[src1[k]]; 1381 uchar s = src1[k+1]; 1382 uchar v = src1[k+2]; 1383 buffer[k] = h; 1384 buffer[k+1] = s; 1385 buffer[k+2] = v; 1386 } 1387 1388 status = icvHSV2RGB_8u_C3R_p( buffer, di*3, 1389 buffer, di*3, cvSize(di,1) ); 1390 if( status < 0 ) 1391 return status; 1392 1393 for( k = 0; k < di*3; k += 3, dst += dst_cn ) 1394 { 1395 uchar r = buffer[k]; 1396 uchar g = buffer[k+1]; 1397 uchar b = buffer[k+2]; 1398 dst[blue_idx] = b; 1399 dst[1] = g; 1400 dst[blue_idx^2] = r; 1401 if( dst_cn == 4 ) 1402 dst[3] = 0; 1403 } 1404 } 1405 } 1406 1407 return CV_OK; 1408 } 1409 1410 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx, 1411 (CvColorCvtFunc2)icvHSV2BGRx_32f_C3CnR, pre_coeffs, 0 ); 1412 } 1413 1414 1415 /****************************************************************************************\ 1416 * RGB <-> HLS * 1417 \****************************************************************************************/ 1418 1419 static CvStatus CV_STDCALL 1420 icvBGRx2HLS_32f_CnC3R( const float* src, int srcstep, float* dst, int dststep, 1421 CvSize size, int src_cn, int blue_idx ) 1422 { 1423 int i; 1424 1425 if( icvRGB2HLS_32f_C3R_p ) 1426 { 1427 CvStatus status = icvBGRx2ABC_IPP_32f_CnC3R( src, srcstep, dst, dststep, size, 1428 src_cn, blue_idx, icvRGB2HLS_32f_C3R_p ); 1429 if( status >= 0 ) 1430 { 1431 size.width *= 3; 1432 dststep /= sizeof(dst[0]); 1433 1434 for( ; size.height--; dst += dststep ) 1435 { 1436 for( i = 0; i <= size.width - 12; i += 12 ) 1437 { 1438 float t0 = dst[i]*360.f, t1 = dst[i+3]*360.f; 1439 dst[i] = t0; dst[i+3] = t1; 1440 t0 = dst[i+6]*360.f; t1 = dst[i+9]*360.f; 1441 dst[i+6] = t0; dst[i+9] = t1; 1442 } 1443 for( ; i < size.width; i += 3 ) 1444 dst[i] = dst[i]*360.f; 1445 } 1446 } 1447 return status; 1448 } 1449 1450 srcstep /= sizeof(src[0]); 1451 dststep /= sizeof(dst[0]); 1452 srcstep -= size.width*src_cn; 1453 size.width *= 3; 1454 1455 for( ; size.height--; src += srcstep, dst += dststep ) 1456 { 1457 for( i = 0; i < size.width; i += 3, src += src_cn ) 1458 { 1459 float b = src[blue_idx], g = src[1], r = src[2^blue_idx]; 1460 float h = 0.f, s = 0.f, l; 1461 float vmin, vmax, diff; 1462 1463 vmax = vmin = r; 1464 if( vmax < g ) vmax = g; 1465 if( vmax < b ) vmax = b; 1466 if( vmin > g ) vmin = g; 1467 if( vmin > b ) vmin = b; 1468 1469 diff = vmax - vmin; 1470 l = (vmax + vmin)*0.5f; 1471 1472 if( diff > FLT_EPSILON ) 1473 { 1474 s = l < 0.5f ? diff/(vmax + vmin) : diff/(2 - vmax - vmin); 1475 diff = 60.f/diff; 1476 1477 if( vmax == r ) 1478 h = (g - b)*diff; 1479 else if( vmax == g ) 1480 h = (b - r)*diff + 120.f; 1481 else 1482 h = (r - g)*diff + 240.f; 1483 1484 if( h < 0.f ) h += 360.f; 1485 } 1486 1487 dst[i] = h; 1488 dst[i+1] = l; 1489 dst[i+2] = s; 1490 } 1491 } 1492 1493 return CV_OK; 1494 } 1495 1496 1497 static CvStatus CV_STDCALL 1498 icvHLS2BGRx_32f_C3CnR( const float* src, int srcstep, float* dst, int dststep, 1499 CvSize size, int dst_cn, int blue_idx ) 1500 { 1501 int i; 1502 srcstep /= sizeof(src[0]); 1503 dststep /= sizeof(dst[0]); 1504 1505 if( icvHLS2RGB_32f_C3R_p ) 1506 { 1507 int block_size = MIN(1 << 10, size.width); 1508 float* buffer; 1509 int di, k; 1510 CvStatus status = CV_OK; 1511 1512 buffer = (float*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); 1513 dststep -= size.width*dst_cn; 1514 1515 for( ; size.height--; src += srcstep, dst += dststep ) 1516 { 1517 for( i = 0; i < size.width; i += block_size ) 1518 { 1519 const float* src1 = src + i*3; 1520 di = MIN(block_size, size.width - i); 1521 for( k = 0; k < di*3; k += 3 ) 1522 { 1523 float h = src1[k]*0.0027777777777777779f; // /360. 1524 float s = src1[k+1], v = src1[k+2]; 1525 buffer[k] = h; buffer[k+1] = s; buffer[k+2] = v; 1526 } 1527 1528 status = icvHLS2RGB_32f_C3R_p( buffer, di*3*sizeof(dst[0]), 1529 buffer, di*3*sizeof(dst[0]), cvSize(di,1) ); 1530 if( status < 0 ) 1531 return status; 1532 1533 for( k = 0; k < di*3; k += 3, dst += dst_cn ) 1534 { 1535 float r = buffer[k], g = buffer[k+1], b = buffer[k+2]; 1536 dst[blue_idx] = b; dst[1] = g; dst[blue_idx^2] = r; 1537 if( dst_cn == 4 ) 1538 dst[3] = 0; 1539 } 1540 } 1541 } 1542 1543 return CV_OK; 1544 } 1545 1546 dststep -= size.width*dst_cn; 1547 size.width *= 3; 1548 1549 for( ; size.height--; src += srcstep, dst += dststep ) 1550 { 1551 for( i = 0; i < size.width; i += 3, dst += dst_cn ) 1552 { 1553 float h = src[i], l = src[i+1], s = src[i+2]; 1554 float b, g, r; 1555 1556 if( s == 0 ) 1557 b = g = r = l; 1558 else 1559 { 1560 static const int sector_data[][3]= 1561 {{1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0}}; 1562 float tab[4]; 1563 int sector; 1564 1565 float p2 = l <= 0.5f ? l*(1 + s) : l + s - l*s; 1566 float p1 = 2*l - p2; 1567 1568 h *= 0.016666666666666666f; // h /= 60; 1569 if( h < 0 ) 1570 do h += 6; while( h < 0 ); 1571 else if( h >= 6 ) 1572 do h -= 6; while( h >= 6 ); 1573 1574 assert( 0 <= h && h < 6 ); 1575 sector = cvFloor(h); 1576 h -= sector; 1577 1578 tab[0] = p2; 1579 tab[1] = p1; 1580 tab[2] = p1 + (p2 - p1)*(1-h); 1581 tab[3] = p1 + (p2 - p1)*h; 1582 1583 b = tab[sector_data[sector][0]]; 1584 g = tab[sector_data[sector][1]]; 1585 r = tab[sector_data[sector][2]]; 1586 } 1587 1588 dst[blue_idx] = b; 1589 dst[1] = g; 1590 dst[blue_idx^2] = r; 1591 if( dst_cn == 4 ) 1592 dst[3] = 0; 1593 } 1594 } 1595 1596 return CV_OK; 1597 } 1598 1599 static CvStatus CV_STDCALL 1600 icvBGRx2HLS_8u_CnC3R( const uchar* src, int srcstep, uchar* dst, int dststep, 1601 CvSize size, int src_cn, int blue_idx ) 1602 { 1603 static const float post_coeffs[] = { 0.5f, 0.f, 255.f, 0.f, 255.f, 0.f }; 1604 1605 if( icvRGB2HLS_8u_C3R_p ) 1606 { 1607 CvStatus status = icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size, 1608 src_cn, blue_idx, icvRGB2HLS_8u_C3R_p ); 1609 if( status >= 0 ) 1610 { 1611 size.width *= 3; 1612 for( ; size.height--; dst += dststep ) 1613 { 1614 int i; 1615 for( i = 0; i <= size.width - 12; i += 12 ) 1616 { 1617 uchar t0 = icvHue255To180[dst[i]], t1 = icvHue255To180[dst[i+3]]; 1618 dst[i] = t0; dst[i+3] = t1; 1619 t0 = icvHue255To180[dst[i+6]]; t1 = icvHue255To180[dst[i+9]]; 1620 dst[i+6] = t0; dst[i+9] = t1; 1621 } 1622 for( ; i < size.width; i += 3 ) 1623 dst[i] = icvHue255To180[dst[i]]; 1624 } 1625 } 1626 return status; 1627 } 1628 1629 return icvBGRx2ABC_8u_CnC3R( src, srcstep, dst, dststep, size, src_cn, blue_idx, 1630 (CvColorCvtFunc2)icvBGRx2HLS_32f_CnC3R, 1, post_coeffs ); 1631 } 1632 1633 1634 static CvStatus CV_STDCALL 1635 icvHLS2BGRx_8u_C3CnR( const uchar* src, int srcstep, uchar* dst, int dststep, 1636 CvSize size, int dst_cn, int blue_idx ) 1637 { 1638 static const float pre_coeffs[] = { 2.f, 0.f, 0.0039215686274509803f, 0.f, 1639 0.0039215686274509803f, 0.f }; 1640 1641 if( icvHLS2RGB_8u_C3R_p ) 1642 { 1643 int block_size = MIN(1 << 14, size.width); 1644 uchar* buffer; 1645 int i, di, k; 1646 CvStatus status = CV_OK; 1647 1648 buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); 1649 dststep -= size.width*dst_cn; 1650 1651 for( ; size.height--; src += srcstep, dst += dststep ) 1652 { 1653 for( i = 0; i < size.width; i += block_size ) 1654 { 1655 const uchar* src1 = src + i*3; 1656 di = MIN(block_size, size.width - i); 1657 for( k = 0; k < di*3; k += 3 ) 1658 { 1659 uchar h = icvHue180To255[src1[k]]; 1660 uchar l = src1[k+1]; 1661 uchar s = src1[k+2]; 1662 buffer[k] = h; 1663 buffer[k+1] = l; 1664 buffer[k+2] = s; 1665 } 1666 1667 status = icvHLS2RGB_8u_C3R_p( buffer, di*3, 1668 buffer, di*3, cvSize(di,1) ); 1669 if( status < 0 ) 1670 return status; 1671 1672 for( k = 0; k < di*3; k += 3, dst += dst_cn ) 1673 { 1674 uchar r = buffer[k]; 1675 uchar g = buffer[k+1]; 1676 uchar b = buffer[k+2]; 1677 dst[blue_idx] = b; 1678 dst[1] = g; 1679 dst[blue_idx^2] = r; 1680 if( dst_cn == 4 ) 1681 dst[3] = 0; 1682 } 1683 } 1684 } 1685 1686 return CV_OK; 1687 } 1688 1689 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx, 1690 (CvColorCvtFunc2)icvHLS2BGRx_32f_C3CnR, pre_coeffs, 1 ); 1691 } 1692 1693 1694 /****************************************************************************************\ 1695 * RGB <-> L*a*b* * 1696 \****************************************************************************************/ 1697 1698 #define labXr_32f 0.433953f /* = xyzXr_32f / 0.950456 */ 1699 #define labXg_32f 0.376219f /* = xyzXg_32f / 0.950456 */ 1700 #define labXb_32f 0.189828f /* = xyzXb_32f / 0.950456 */ 1701 1702 #define labYr_32f 0.212671f /* = xyzYr_32f */ 1703 #define labYg_32f 0.715160f /* = xyzYg_32f */ 1704 #define labYb_32f 0.072169f /* = xyzYb_32f */ 1705 1706 #define labZr_32f 0.017758f /* = xyzZr_32f / 1.088754 */ 1707 #define labZg_32f 0.109477f /* = xyzZg_32f / 1.088754 */ 1708 #define labZb_32f 0.872766f /* = xyzZb_32f / 1.088754 */ 1709 1710 #define labRx_32f 3.0799327f /* = xyzRx_32f * 0.950456 */ 1711 #define labRy_32f (-1.53715f) /* = xyzRy_32f */ 1712 #define labRz_32f (-0.542782f)/* = xyzRz_32f * 1.088754 */ 1713 1714 #define labGx_32f (-0.921235f)/* = xyzGx_32f * 0.950456 */ 1715 #define labGy_32f 1.875991f /* = xyzGy_32f */ 1716 #define labGz_32f 0.04524426f /* = xyzGz_32f * 1.088754 */ 1717 1718 #define labBx_32f 0.0528909755f /* = xyzBx_32f * 0.950456 */ 1719 #define labBy_32f (-0.204043f) /* = xyzBy_32f */ 1720 #define labBz_32f 1.15115158f /* = xyzBz_32f * 1.088754 */ 1721 1722 #define labT_32f 0.008856f 1723 1724 #define labT fix(labT_32f*255,lab_shift) 1725 1726 #undef lab_shift 1727 #define lab_shift 10 1728 #define labXr fix(labXr_32f,lab_shift) 1729 #define labXg fix(labXg_32f,lab_shift) 1730 #define labXb fix(labXb_32f,lab_shift) 1731 1732 #define labYr fix(labYr_32f,lab_shift) 1733 #define labYg fix(labYg_32f,lab_shift) 1734 #define labYb fix(labYb_32f,lab_shift) 1735 1736 #define labZr fix(labZr_32f,lab_shift) 1737 #define labZg fix(labZg_32f,lab_shift) 1738 #define labZb fix(labZb_32f,lab_shift) 1739 1740 #define labSmallScale_32f 7.787f 1741 #define labSmallShift_32f 0.13793103448275862f /* 16/116 */ 1742 #define labLScale_32f 116.f 1743 #define labLShift_32f 16.f 1744 #define labLScale2_32f 903.3f 1745 1746 #define labSmallScale fix(31.27 /* labSmallScale_32f*(1<<lab_shift)/255 */,lab_shift) 1747 #define labSmallShift fix(141.24138 /* labSmallScale_32f*(1<<lab) */,lab_shift) 1748 #define labLScale fix(295.8 /* labLScale_32f*255/100 */,lab_shift) 1749 #define labLShift fix(41779.2 /* labLShift_32f*1024*255/100 */,lab_shift) 1750 #define labLScale2 fix(labLScale2_32f*0.01,lab_shift) 1751 1752 /* 1024*(([0..511]./255)**(1./3)) */ 1753 static ushort icvLabCubeRootTab[] = { 1754 0, 161, 203, 232, 256, 276, 293, 308, 322, 335, 347, 359, 369, 379, 389, 398, 1755 406, 415, 423, 430, 438, 445, 452, 459, 465, 472, 478, 484, 490, 496, 501, 507, 1756 512, 517, 523, 528, 533, 538, 542, 547, 552, 556, 561, 565, 570, 574, 578, 582, 1757 586, 590, 594, 598, 602, 606, 610, 614, 617, 621, 625, 628, 632, 635, 639, 642, 1758 645, 649, 652, 655, 659, 662, 665, 668, 671, 674, 677, 680, 684, 686, 689, 692, 1759 695, 698, 701, 704, 707, 710, 712, 715, 718, 720, 723, 726, 728, 731, 734, 736, 1760 739, 741, 744, 747, 749, 752, 754, 756, 759, 761, 764, 766, 769, 771, 773, 776, 1761 778, 780, 782, 785, 787, 789, 792, 794, 796, 798, 800, 803, 805, 807, 809, 811, 1762 813, 815, 818, 820, 822, 824, 826, 828, 830, 832, 834, 836, 838, 840, 842, 844, 1763 846, 848, 850, 852, 854, 856, 857, 859, 861, 863, 865, 867, 869, 871, 872, 874, 1764 876, 878, 880, 882, 883, 885, 887, 889, 891, 892, 894, 896, 898, 899, 901, 903, 1765 904, 906, 908, 910, 911, 913, 915, 916, 918, 920, 921, 923, 925, 926, 928, 929, 1766 931, 933, 934, 936, 938, 939, 941, 942, 944, 945, 947, 949, 950, 952, 953, 955, 1767 956, 958, 959, 961, 962, 964, 965, 967, 968, 970, 971, 973, 974, 976, 977, 979, 1768 980, 982, 983, 985, 986, 987, 989, 990, 992, 993, 995, 996, 997, 999, 1000, 1002, 1769 1003, 1004, 1006, 1007, 1009, 1010, 1011, 1013, 1014, 1015, 1017, 1018, 1019, 1021, 1022, 1024, 1770 1025, 1026, 1028, 1029, 1030, 1031, 1033, 1034, 1035, 1037, 1038, 1039, 1041, 1042, 1043, 1044, 1771 1046, 1047, 1048, 1050, 1051, 1052, 1053, 1055, 1056, 1057, 1058, 1060, 1061, 1062, 1063, 1065, 1772 1066, 1067, 1068, 1070, 1071, 1072, 1073, 1074, 1076, 1077, 1078, 1079, 1081, 1082, 1083, 1084, 1773 1085, 1086, 1088, 1089, 1090, 1091, 1092, 1094, 1095, 1096, 1097, 1098, 1099, 1101, 1102, 1103, 1774 1104, 1105, 1106, 1107, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1117, 1118, 1119, 1120, 1121, 1775 1122, 1123, 1124, 1125, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1138, 1139, 1776 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1154, 1155, 1156, 1777 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1778 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1779 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1780 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1215, 1216, 1217, 1218, 1219, 1781 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1230, 1231, 1232, 1233, 1234, 1782 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1783 1250, 1251, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1259, 1260, 1261, 1262, 1263, 1784 1264, 1265, 1266, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1273, 1274, 1275, 1276, 1277, 1785 1278, 1279, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1285, 1286, 1287, 1288, 1289, 1290, 1291 1786 }; 1787 1788 1789 static CvStatus CV_STDCALL 1790 icvBGRx2Lab_8u_CnC3R( const uchar* src, int srcstep, uchar* dst, int dststep, 1791 CvSize size, int src_cn, int blue_idx ) 1792 { 1793 int i; 1794 1795 /*if( icvBGR2Lab_8u_C3R_p ) 1796 return icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size, 1797 src_cn, blue_idx^2, icvBGR2Lab_8u_C3R_p );*/ 1798 1799 srcstep -= size.width*src_cn; 1800 size.width *= 3; 1801 1802 for( ; size.height--; src += srcstep, dst += dststep ) 1803 { 1804 for( i = 0; i < size.width; i += 3, src += src_cn ) 1805 { 1806 int b = src[blue_idx], g = src[1], r = src[2^blue_idx]; 1807 int x, y, z, f; 1808 int L, a; 1809 1810 x = b*labXb + g*labXg + r*labXr; 1811 y = b*labYb + g*labYg + r*labYr; 1812 z = b*labZb + g*labZg + r*labZr; 1813 1814 f = x > labT; 1815 x = CV_DESCALE( x, lab_shift ); 1816 1817 if( f ) 1818 assert( (unsigned)x < 512 ), x = icvLabCubeRootTab[x]; 1819 else 1820 x = CV_DESCALE(x*labSmallScale + labSmallShift,lab_shift); 1821 1822 f = z > labT; 1823 z = CV_DESCALE( z, lab_shift ); 1824 1825 if( f ) 1826 assert( (unsigned)z < 512 ), z = icvLabCubeRootTab[z]; 1827 else 1828 z = CV_DESCALE(z*labSmallScale + labSmallShift,lab_shift); 1829 1830 f = y > labT; 1831 y = CV_DESCALE( y, lab_shift ); 1832 1833 if( f ) 1834 { 1835 assert( (unsigned)y < 512 ), y = icvLabCubeRootTab[y]; 1836 L = CV_DESCALE(y*labLScale - labLShift, 2*lab_shift ); 1837 } 1838 else 1839 { 1840 L = CV_DESCALE(y*labLScale2,lab_shift); 1841 y = CV_DESCALE(y*labSmallScale + labSmallShift,lab_shift); 1842 } 1843 1844 a = CV_DESCALE( 500*(x - y), lab_shift ) + 128; 1845 b = CV_DESCALE( 200*(y - z), lab_shift ) + 128; 1846 1847 dst[i] = CV_CAST_8U(L); 1848 dst[i+1] = CV_CAST_8U(a); 1849 dst[i+2] = CV_CAST_8U(b); 1850 } 1851 } 1852 1853 return CV_OK; 1854 } 1855 1856 1857 static CvStatus CV_STDCALL 1858 icvBGRx2Lab_32f_CnC3R( const float* src, int srcstep, float* dst, int dststep, 1859 CvSize size, int src_cn, int blue_idx ) 1860 { 1861 int i; 1862 srcstep /= sizeof(src[0]); 1863 dststep /= sizeof(dst[0]); 1864 srcstep -= size.width*src_cn; 1865 size.width *= 3; 1866 1867 for( ; size.height--; src += srcstep, dst += dststep ) 1868 { 1869 for( i = 0; i < size.width; i += 3, src += src_cn ) 1870 { 1871 float b = src[blue_idx], g = src[1], r = src[2^blue_idx]; 1872 float x, y, z; 1873 float L, a; 1874 1875 x = b*labXb_32f + g*labXg_32f + r*labXr_32f; 1876 y = b*labYb_32f + g*labYg_32f + r*labYr_32f; 1877 z = b*labZb_32f + g*labZg_32f + r*labZr_32f; 1878 1879 if( x > labT_32f ) 1880 x = cvCbrt(x); 1881 else 1882 x = x*labSmallScale_32f + labSmallShift_32f; 1883 1884 if( z > labT_32f ) 1885 z = cvCbrt(z); 1886 else 1887 z = z*labSmallScale_32f + labSmallShift_32f; 1888 1889 if( y > labT_32f ) 1890 { 1891 y = cvCbrt(y); 1892 L = y*labLScale_32f - labLShift_32f; 1893 } 1894 else 1895 { 1896 L = y*labLScale2_32f; 1897 y = y*labSmallScale_32f + labSmallShift_32f; 1898 } 1899 1900 a = 500.f*(x - y); 1901 b = 200.f*(y - z); 1902 1903 dst[i] = L; 1904 dst[i+1] = a; 1905 dst[i+2] = b; 1906 } 1907 } 1908 1909 return CV_OK; 1910 } 1911 1912 1913 static CvStatus CV_STDCALL 1914 icvLab2BGRx_32f_C3CnR( const float* src, int srcstep, float* dst, int dststep, 1915 CvSize size, int dst_cn, int blue_idx ) 1916 { 1917 int i; 1918 srcstep /= sizeof(src[0]); 1919 dststep /= sizeof(dst[0]); 1920 dststep -= size.width*dst_cn; 1921 size.width *= 3; 1922 1923 for( ; size.height--; src += srcstep, dst += dststep ) 1924 { 1925 for( i = 0; i < size.width; i += 3, dst += dst_cn ) 1926 { 1927 float L = src[i], a = src[i+1], b = src[i+2]; 1928 float x, y, z; 1929 float g, r; 1930 1931 L = (L + labLShift_32f)*(1.f/labLScale_32f); 1932 x = (L + a*0.002f); 1933 z = (L - b*0.005f); 1934 y = L*L*L; 1935 x = x*x*x; 1936 z = z*z*z; 1937 1938 b = x*labBx_32f + y*labBy_32f + z*labBz_32f; 1939 g = x*labGx_32f + y*labGy_32f + z*labGz_32f; 1940 r = x*labRx_32f + y*labRy_32f + z*labRz_32f; 1941 1942 dst[blue_idx] = b; 1943 dst[1] = g; 1944 dst[blue_idx^2] = r; 1945 if( dst_cn == 4 ) 1946 dst[3] = 0; 1947 } 1948 } 1949 1950 return CV_OK; 1951 } 1952 1953 1954 static CvStatus CV_STDCALL 1955 icvLab2BGRx_8u_C3CnR( const uchar* src, int srcstep, uchar* dst, int dststep, 1956 CvSize size, int dst_cn, int blue_idx ) 1957 { 1958 // L: [0..255] -> [0..100] 1959 // a: [0..255] -> [-128..127] 1960 // b: [0..255] -> [-128..127] 1961 static const float pre_coeffs[] = { 0.39215686274509809f, 0.f, 1.f, -128.f, 1.f, -128.f }; 1962 1963 if( icvLab2BGR_8u_C3R_p ) 1964 return icvABC2BGRx_IPP_8u_C3CnR( src, srcstep, dst, dststep, size, 1965 dst_cn, blue_idx^2, icvLab2BGR_8u_C3R_p ); 1966 1967 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx, 1968 (CvColorCvtFunc2)icvLab2BGRx_32f_C3CnR, pre_coeffs, 1 ); 1969 } 1970 1971 1972 /****************************************************************************************\ 1973 * RGB <-> L*u*v* * 1974 \****************************************************************************************/ 1975 1976 #define luvUn_32f 0.19793943f 1977 #define luvVn_32f 0.46831096f 1978 #define luvYmin_32f 0.05882353f /* 15/255 */ 1979 1980 static CvStatus CV_STDCALL 1981 icvBGRx2Luv_32f_CnC3R( const float* src, int srcstep, float* dst, int dststep, 1982 CvSize size, int src_cn, int blue_idx ) 1983 { 1984 int i; 1985 1986 /*if( icvRGB2Luv_32f_C3R_p ) 1987 return icvBGRx2ABC_IPP_32f_CnC3R( src, srcstep, dst, dststep, size, 1988 src_cn, blue_idx, icvRGB2Luv_32f_C3R_p );*/ 1989 1990 srcstep /= sizeof(src[0]); 1991 dststep /= sizeof(dst[0]); 1992 srcstep -= size.width*src_cn; 1993 size.width *= 3; 1994 1995 for( ; size.height--; src += srcstep, dst += dststep ) 1996 { 1997 for( i = 0; i < size.width; i += 3, src += src_cn ) 1998 { 1999 float b = src[blue_idx], g = src[1], r = src[2^blue_idx]; 2000 float x, y, z; 2001 float L, u, v, t; 2002 2003 x = b*xyzXb_32f + g*xyzXg_32f + r*xyzXr_32f; 2004 y = b*xyzYb_32f + g*xyzYg_32f + r*xyzYr_32f; 2005 z = b*xyzZb_32f + g*xyzZg_32f + r*xyzZr_32f; 2006 2007 if( !x && !y && !z ) 2008 L = u = v = 0.f; 2009 else 2010 { 2011 if( y > labT_32f ) 2012 L = labLScale_32f * cvCbrt(y) - labLShift_32f; 2013 else 2014 L = labLScale2_32f * y; 2015 2016 t = 1.f / (x + 15 * y + 3 * z); 2017 u = 4.0f * x * t; 2018 v = 9.0f * y * t; 2019 2020 u = 13*L*(u - luvUn_32f); 2021 v = 13*L*(v - luvVn_32f); 2022 } 2023 2024 dst[i] = L; 2025 dst[i+1] = u; 2026 dst[i+2] = v; 2027 } 2028 } 2029 2030 return CV_OK; 2031 } 2032 2033 2034 static CvStatus CV_STDCALL 2035 icvLuv2BGRx_32f_C3CnR( const float* src, int srcstep, float* dst, int dststep, 2036 CvSize size, int dst_cn, int blue_idx ) 2037 { 2038 int i; 2039 2040 /*if( icvLuv2RGB_32f_C3R_p ) 2041 return icvABC2BGRx_IPP_32f_C3CnR( src, srcstep, dst, dststep, size, 2042 dst_cn, blue_idx, icvLuv2RGB_32f_C3R_p );*/ 2043 2044 srcstep /= sizeof(src[0]); 2045 dststep /= sizeof(dst[0]); 2046 dststep -= size.width*dst_cn; 2047 size.width *= 3; 2048 2049 for( ; size.height--; src += srcstep, dst += dststep ) 2050 { 2051 for( i = 0; i < size.width; i += 3, dst += dst_cn ) 2052 { 2053 float L = src[i], u = src[i+1], v = src[i+2]; 2054 float x, y, z, t, u1, v1, b, g, r; 2055 2056 if( L >= 8 ) 2057 { 2058 t = (L + labLShift_32f) * (1.f/labLScale_32f); 2059 y = t*t*t; 2060 } 2061 else 2062 { 2063 y = L * (1.f/labLScale2_32f); 2064 L = MAX( L, 0.001f ); 2065 } 2066 2067 t = 1.f/(13.f * L); 2068 u1 = u*t + luvUn_32f; 2069 v1 = v*t + luvVn_32f; 2070 x = 2.25f * u1 * y / v1 ; 2071 z = (12 - 3 * u1 - 20 * v1) * y / (4 * v1); 2072 2073 b = xyzBx_32f*x + xyzBy_32f*y + xyzBz_32f*z; 2074 g = xyzGx_32f*x + xyzGy_32f*y + xyzGz_32f*z; 2075 r = xyzRx_32f*x + xyzRy_32f*y + xyzRz_32f*z; 2076 2077 dst[blue_idx] = b; 2078 dst[1] = g; 2079 dst[blue_idx^2] = r; 2080 if( dst_cn == 4 ) 2081 dst[3] = 0.f; 2082 } 2083 } 2084 2085 return CV_OK; 2086 } 2087 2088 2089 static CvStatus CV_STDCALL 2090 icvBGRx2Luv_8u_CnC3R( const uchar* src, int srcstep, uchar* dst, int dststep, 2091 CvSize size, int src_cn, int blue_idx ) 2092 { 2093 // L: [0..100] -> [0..255] 2094 // u: [-134..220] -> [0..255] 2095 // v: [-140..122] -> [0..255] 2096 //static const float post_coeffs[] = { 2.55f, 0.f, 1.f, 83.f, 1.f, 140.f }; 2097 static const float post_coeffs[] = { 2.55f, 0.f, 0.72033898305084743f, 96.525423728813564f, 2098 0.99609375f, 139.453125f }; 2099 2100 if( icvRGB2Luv_8u_C3R_p ) 2101 return icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size, 2102 src_cn, blue_idx, icvRGB2Luv_8u_C3R_p ); 2103 2104 return icvBGRx2ABC_8u_CnC3R( src, srcstep, dst, dststep, size, src_cn, blue_idx, 2105 (CvColorCvtFunc2)icvBGRx2Luv_32f_CnC3R, 1, post_coeffs ); 2106 } 2107 2108 2109 static CvStatus CV_STDCALL 2110 icvLuv2BGRx_8u_C3CnR( const uchar* src, int srcstep, uchar* dst, int dststep, 2111 CvSize size, int dst_cn, int blue_idx ) 2112 { 2113 // L: [0..255] -> [0..100] 2114 // u: [0..255] -> [-134..220] 2115 // v: [0..255] -> [-140..122] 2116 static const float pre_coeffs[] = { 0.39215686274509809f, 0.f, 1.388235294117647f, -134.f, 2117 1.003921568627451f, -140.f }; 2118 2119 if( icvLuv2RGB_8u_C3R_p ) 2120 return icvABC2BGRx_IPP_8u_C3CnR( src, srcstep, dst, dststep, size, 2121 dst_cn, blue_idx, icvLuv2RGB_8u_C3R_p ); 2122 2123 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx, 2124 (CvColorCvtFunc2)icvLuv2BGRx_32f_C3CnR, pre_coeffs, 1 ); 2125 } 2126 2127 /****************************************************************************************\ 2128 * Bayer Pattern -> RGB conversion * 2129 \****************************************************************************************/ 2130 2131 static CvStatus CV_STDCALL 2132 icvBayer2BGR_8u_C1C3R( const uchar* bayer0, int bayer_step, 2133 uchar *dst0, int dst_step, 2134 CvSize size, int code ) 2135 { 2136 int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1; 2137 int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR; 2138 2139 memset( dst0, 0, size.width*3*sizeof(dst0[0]) ); 2140 memset( dst0 + (size.height - 1)*dst_step, 0, size.width*3*sizeof(dst0[0]) ); 2141 dst0 += dst_step + 3 + 1; 2142 size.height -= 2; 2143 size.width -= 2; 2144 2145 for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) 2146 { 2147 int t0, t1; 2148 const uchar* bayer = bayer0; 2149 uchar* dst = dst0; 2150 const uchar* bayer_end = bayer + size.width; 2151 2152 dst[-4] = dst[-3] = dst[-2] = dst[size.width*3-1] = 2153 dst[size.width*3] = dst[size.width*3+1] = 0; 2154 2155 if( size.width <= 0 ) 2156 continue; 2157 2158 if( start_with_green ) 2159 { 2160 t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1; 2161 t1 = (bayer[bayer_step] + bayer[bayer_step+2] + 1) >> 1; 2162 dst[-blue] = (uchar)t0; 2163 dst[0] = bayer[bayer_step+1]; 2164 dst[blue] = (uchar)t1; 2165 bayer++; 2166 dst += 3; 2167 } 2168 2169 if( blue > 0 ) 2170 { 2171 for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) 2172 { 2173 t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + 2174 bayer[bayer_step*2+2] + 2) >> 2; 2175 t1 = (bayer[1] + bayer[bayer_step] + 2176 bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; 2177 dst[-1] = (uchar)t0; 2178 dst[0] = (uchar)t1; 2179 dst[1] = bayer[bayer_step+1]; 2180 2181 t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1; 2182 t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1; 2183 dst[2] = (uchar)t0; 2184 dst[3] = bayer[bayer_step+2]; 2185 dst[4] = (uchar)t1; 2186 } 2187 } 2188 else 2189 { 2190 for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) 2191 { 2192 t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + 2193 bayer[bayer_step*2+2] + 2) >> 2; 2194 t1 = (bayer[1] + bayer[bayer_step] + 2195 bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; 2196 dst[1] = (uchar)t0; 2197 dst[0] = (uchar)t1; 2198 dst[-1] = bayer[bayer_step+1]; 2199 2200 t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1; 2201 t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1; 2202 dst[4] = (uchar)t0; 2203 dst[3] = bayer[bayer_step+2]; 2204 dst[2] = (uchar)t1; 2205 } 2206 } 2207 2208 if( bayer < bayer_end ) 2209 { 2210 t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + 2211 bayer[bayer_step*2+2] + 2) >> 2; 2212 t1 = (bayer[1] + bayer[bayer_step] + 2213 bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; 2214 dst[-blue] = (uchar)t0; 2215 dst[0] = (uchar)t1; 2216 dst[blue] = bayer[bayer_step+1]; 2217 bayer++; 2218 dst += 3; 2219 } 2220 2221 blue = -blue; 2222 start_with_green = !start_with_green; 2223 } 2224 2225 return CV_OK; 2226 } 2227 2228 2229 /****************************************************************************************\ 2230 * The main function * 2231 \****************************************************************************************/ 2232 2233 CV_IMPL void 2234 cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code ) 2235 { 2236 CV_FUNCNAME( "cvCvtColor" ); 2237 2238 __BEGIN__; 2239 2240 CvMat srcstub, *src = (CvMat*)srcarr; 2241 CvMat dststub, *dst = (CvMat*)dstarr; 2242 CvSize size; 2243 int src_step, dst_step; 2244 int src_cn, dst_cn, depth; 2245 CvColorCvtFunc0 func0 = 0; 2246 CvColorCvtFunc1 func1 = 0; 2247 CvColorCvtFunc2 func2 = 0; 2248 CvColorCvtFunc3 func3 = 0; 2249 int param[] = { 0, 0, 0, 0 }; 2250 2251 CV_CALL( src = cvGetMat( srcarr, &srcstub )); 2252 CV_CALL( dst = cvGetMat( dstarr, &dststub )); 2253 2254 if( !CV_ARE_SIZES_EQ( src, dst )) 2255 CV_ERROR( CV_StsUnmatchedSizes, "" ); 2256 2257 if( !CV_ARE_DEPTHS_EQ( src, dst )) 2258 CV_ERROR( CV_StsUnmatchedFormats, "" ); 2259 2260 depth = CV_MAT_DEPTH(src->type); 2261 if( depth != CV_8U && depth != CV_16U && depth != CV_32F ) 2262 CV_ERROR( CV_StsUnsupportedFormat, "" ); 2263 2264 src_cn = CV_MAT_CN( src->type ); 2265 dst_cn = CV_MAT_CN( dst->type ); 2266 size = cvGetMatSize( src ); 2267 src_step = src->step; 2268 dst_step = dst->step; 2269 2270 if( CV_IS_MAT_CONT(src->type & dst->type) && 2271 code != CV_BayerBG2BGR && code != CV_BayerGB2BGR && 2272 code != CV_BayerRG2BGR && code != CV_BayerGR2BGR ) 2273 { 2274 size.width *= size.height; 2275 size.height = 1; 2276 src_step = dst_step = CV_STUB_STEP; 2277 } 2278 2279 switch( code ) 2280 { 2281 case CV_BGR2BGRA: 2282 case CV_RGB2BGRA: 2283 if( src_cn != 3 || dst_cn != 4 ) 2284 CV_ERROR( CV_BadNumChannels, 2285 "Incorrect number of channels for this conversion code" ); 2286 2287 func1 = depth == CV_8U ? (CvColorCvtFunc1)icvBGR2BGRx_8u_C3C4R : 2288 depth == CV_16U ? (CvColorCvtFunc1)icvBGR2BGRx_16u_C3C4R : 2289 depth == CV_32F ? (CvColorCvtFunc1)icvBGR2BGRx_32f_C3C4R : 0; 2290 param[0] = code == CV_BGR2BGRA ? 0 : 2; // blue_idx 2291 break; 2292 2293 case CV_BGRA2BGR: 2294 case CV_RGBA2BGR: 2295 case CV_RGB2BGR: 2296 if( (src_cn != 3 && src_cn != 4) || dst_cn != 3 ) 2297 CV_ERROR( CV_BadNumChannels, 2298 "Incorrect number of channels for this conversion code" ); 2299 2300 func2 = depth == CV_8U ? (CvColorCvtFunc2)icvBGRx2BGR_8u_CnC3R : 2301 depth == CV_16U ? (CvColorCvtFunc2)icvBGRx2BGR_16u_CnC3R : 2302 depth == CV_32F ? (CvColorCvtFunc2)icvBGRx2BGR_32f_CnC3R : 0; 2303 param[0] = src_cn; 2304 param[1] = code == CV_BGRA2BGR ? 0 : 2; // blue_idx 2305 break; 2306 2307 case CV_BGRA2RGBA: 2308 if( src_cn != 4 || dst_cn != 4 ) 2309 CV_ERROR( CV_BadNumChannels, 2310 "Incorrect number of channels for this conversion code" ); 2311 2312 func0 = depth == CV_8U ? (CvColorCvtFunc0)icvBGRA2RGBA_8u_C4R : 2313 depth == CV_16U ? (CvColorCvtFunc0)icvBGRA2RGBA_16u_C4R : 2314 depth == CV_32F ? (CvColorCvtFunc0)icvBGRA2RGBA_32f_C4R : 0; 2315 break; 2316 2317 case CV_BGR2BGR565: 2318 case CV_BGR2BGR555: 2319 case CV_RGB2BGR565: 2320 case CV_RGB2BGR555: 2321 case CV_BGRA2BGR565: 2322 case CV_BGRA2BGR555: 2323 case CV_RGBA2BGR565: 2324 case CV_RGBA2BGR555: 2325 if( (src_cn != 3 && src_cn != 4) || dst_cn != 2 ) 2326 CV_ERROR( CV_BadNumChannels, 2327 "Incorrect number of channels for this conversion code" ); 2328 2329 if( depth != CV_8U ) 2330 CV_ERROR( CV_BadDepth, 2331 "Conversion to/from 16-bit packed RGB format " 2332 "is only possible for 8-bit images (8-bit grayscale, 888 BGR/RGB or 8888 BGRA/RGBA)" ); 2333 2334 func3 = (CvColorCvtFunc3)icvBGRx2BGR5x5_8u_CnC2R; 2335 param[0] = src_cn; 2336 param[1] = code == CV_BGR2BGR565 || code == CV_BGR2BGR555 || 2337 code == CV_BGRA2BGR565 || code == CV_BGRA2BGR555 ? 0 : 2; // blue_idx 2338 param[2] = code == CV_BGR2BGR565 || code == CV_RGB2BGR565 || 2339 code == CV_BGRA2BGR565 || code == CV_RGBA2BGR565 ? 6 : 5; // green_bits 2340 break; 2341 2342 case CV_BGR5652BGR: 2343 case CV_BGR5552BGR: 2344 case CV_BGR5652RGB: 2345 case CV_BGR5552RGB: 2346 case CV_BGR5652BGRA: 2347 case CV_BGR5552BGRA: 2348 case CV_BGR5652RGBA: 2349 case CV_BGR5552RGBA: 2350 if( src_cn != 2 || (dst_cn != 3 && dst_cn != 4)) 2351 CV_ERROR( CV_BadNumChannels, 2352 "Incorrect number of channels for this conversion code" ); 2353 2354 if( depth != CV_8U ) 2355 CV_ERROR( CV_BadDepth, 2356 "Conversion to/from 16-bit packed BGR format " 2357 "is only possible for 8-bit images (8-bit grayscale, 888 BGR/BGR or 8888 BGRA/BGRA)" ); 2358 2359 func3 = (CvColorCvtFunc3)icvBGR5x52BGRx_8u_C2CnR; 2360 param[0] = dst_cn; 2361 param[1] = code == CV_BGR5652BGR || code == CV_BGR5552BGR || 2362 code == CV_BGR5652BGRA || code == CV_BGR5552BGRA ? 0 : 2; // blue_idx 2363 param[2] = code == CV_BGR5652BGR || code == CV_BGR5652RGB || 2364 code == CV_BGR5652BGRA || code == CV_BGR5652RGBA ? 6 : 5; // green_bits 2365 break; 2366 2367 case CV_BGR2GRAY: 2368 case CV_BGRA2GRAY: 2369 case CV_RGB2GRAY: 2370 case CV_RGBA2GRAY: 2371 if( (src_cn != 3 && src_cn != 4) || dst_cn != 1 ) 2372 CV_ERROR( CV_BadNumChannels, 2373 "Incorrect number of channels for this conversion code" ); 2374 2375 func2 = depth == CV_8U ? (CvColorCvtFunc2)icvBGRx2Gray_8u_CnC1R : 2376 depth == CV_16U ? (CvColorCvtFunc2)icvBGRx2Gray_16u_CnC1R : 2377 depth == CV_32F ? (CvColorCvtFunc2)icvBGRx2Gray_32f_CnC1R : 0; 2378 2379 param[0] = src_cn; 2380 param[1] = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2; 2381 break; 2382 2383 case CV_BGR5652GRAY: 2384 case CV_BGR5552GRAY: 2385 if( src_cn != 2 || dst_cn != 1 ) 2386 CV_ERROR( CV_BadNumChannels, 2387 "Incorrect number of channels for this conversion code" ); 2388 2389 if( depth != CV_8U ) 2390 CV_ERROR( CV_BadDepth, 2391 "Conversion to/from 16-bit packed BGR format " 2392 "is only possible for 8-bit images (888 BGR/BGR or 8888 BGRA/BGRA)" ); 2393 2394 func2 = (CvColorCvtFunc2)icvBGR5x52Gray_8u_C2C1R; 2395 2396 param[0] = code == CV_BGR5652GRAY ? 6 : 5; // green_bits 2397 break; 2398 2399 case CV_GRAY2BGR: 2400 case CV_GRAY2BGRA: 2401 if( src_cn != 1 || (dst_cn != 3 && dst_cn != 4)) 2402 CV_ERROR( CV_BadNumChannels, 2403 "Incorrect number of channels for this conversion code" ); 2404 2405 func1 = depth == CV_8U ? (CvColorCvtFunc1)icvGray2BGRx_8u_C1CnR : 2406 depth == CV_16U ? (CvColorCvtFunc1)icvGray2BGRx_16u_C1CnR : 2407 depth == CV_32F ? (CvColorCvtFunc1)icvGray2BGRx_32f_C1CnR : 0; 2408 2409 param[0] = dst_cn; 2410 break; 2411 2412 case CV_GRAY2BGR565: 2413 case CV_GRAY2BGR555: 2414 if( src_cn != 1 || dst_cn != 2 ) 2415 CV_ERROR( CV_BadNumChannels, 2416 "Incorrect number of channels for this conversion code" ); 2417 2418 if( depth != CV_8U ) 2419 CV_ERROR( CV_BadDepth, 2420 "Conversion to/from 16-bit packed BGR format " 2421 "is only possible for 8-bit images (888 BGR/BGR or 8888 BGRA/BGRA)" ); 2422 2423 func2 = (CvColorCvtFunc2)icvGray2BGR5x5_8u_C1C2R; 2424 param[0] = code == CV_GRAY2BGR565 ? 6 : 5; // green_bits 2425 break; 2426 2427 case CV_BGR2YCrCb: 2428 case CV_RGB2YCrCb: 2429 case CV_BGR2XYZ: 2430 case CV_RGB2XYZ: 2431 case CV_BGR2HSV: 2432 case CV_RGB2HSV: 2433 case CV_BGR2Lab: 2434 case CV_RGB2Lab: 2435 case CV_BGR2Luv: 2436 case CV_RGB2Luv: 2437 case CV_BGR2HLS: 2438 case CV_RGB2HLS: 2439 if( (src_cn != 3 && src_cn != 4) || dst_cn != 3 ) 2440 CV_ERROR( CV_BadNumChannels, 2441 "Incorrect number of channels for this conversion code" ); 2442 2443 if( depth == CV_8U ) 2444 func2 = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? (CvColorCvtFunc2)icvBGRx2YCrCb_8u_CnC3R : 2445 code == CV_BGR2XYZ || code == CV_RGB2XYZ ? (CvColorCvtFunc2)icvBGRx2XYZ_8u_CnC3R : 2446 code == CV_BGR2HSV || code == CV_RGB2HSV ? (CvColorCvtFunc2)icvBGRx2HSV_8u_CnC3R : 2447 code == CV_BGR2Lab || code == CV_RGB2Lab ? (CvColorCvtFunc2)icvBGRx2Lab_8u_CnC3R : 2448 code == CV_BGR2Luv || code == CV_RGB2Luv ? (CvColorCvtFunc2)icvBGRx2Luv_8u_CnC3R : 2449 code == CV_BGR2HLS || code == CV_RGB2HLS ? (CvColorCvtFunc2)icvBGRx2HLS_8u_CnC3R : 0; 2450 else if( depth == CV_16U ) 2451 func2 = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? (CvColorCvtFunc2)icvBGRx2YCrCb_16u_CnC3R : 2452 code == CV_BGR2XYZ || code == CV_RGB2XYZ ? (CvColorCvtFunc2)icvBGRx2XYZ_16u_CnC3R : 0; 2453 else if( depth == CV_32F ) 2454 func2 = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? (CvColorCvtFunc2)icvBGRx2YCrCb_32f_CnC3R : 2455 code == CV_BGR2XYZ || code == CV_RGB2XYZ ? (CvColorCvtFunc2)icvBGRx2XYZ_32f_CnC3R : 2456 code == CV_BGR2HSV || code == CV_RGB2HSV ? (CvColorCvtFunc2)icvBGRx2HSV_32f_CnC3R : 2457 code == CV_BGR2Lab || code == CV_RGB2Lab ? (CvColorCvtFunc2)icvBGRx2Lab_32f_CnC3R : 2458 code == CV_BGR2Luv || code == CV_RGB2Luv ? (CvColorCvtFunc2)icvBGRx2Luv_32f_CnC3R : 2459 code == CV_BGR2HLS || code == CV_RGB2HLS ? (CvColorCvtFunc2)icvBGRx2HLS_32f_CnC3R : 0; 2460 2461 param[0] = src_cn; 2462 param[1] = code == CV_BGR2XYZ || code == CV_BGR2YCrCb || code == CV_BGR2HSV || 2463 code == CV_BGR2Lab || code == CV_BGR2Luv || code == CV_BGR2HLS ? 0 : 2; 2464 break; 2465 2466 case CV_YCrCb2BGR: 2467 case CV_YCrCb2RGB: 2468 case CV_XYZ2BGR: 2469 case CV_XYZ2RGB: 2470 case CV_HSV2BGR: 2471 case CV_HSV2RGB: 2472 case CV_Lab2BGR: 2473 case CV_Lab2RGB: 2474 case CV_Luv2BGR: 2475 case CV_Luv2RGB: 2476 case CV_HLS2BGR: 2477 case CV_HLS2RGB: 2478 if( src_cn != 3 || (dst_cn != 3 && dst_cn != 4) ) 2479 CV_ERROR( CV_BadNumChannels, 2480 "Incorrect number of channels for this conversion code" ); 2481 2482 if( depth == CV_8U ) 2483 func2 = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? (CvColorCvtFunc2)icvYCrCb2BGRx_8u_C3CnR : 2484 code == CV_XYZ2BGR || code == CV_XYZ2RGB ? (CvColorCvtFunc2)icvXYZ2BGRx_8u_C3CnR : 2485 code == CV_HSV2BGR || code == CV_HSV2RGB ? (CvColorCvtFunc2)icvHSV2BGRx_8u_C3CnR : 2486 code == CV_HLS2BGR || code == CV_HLS2RGB ? (CvColorCvtFunc2)icvHLS2BGRx_8u_C3CnR : 2487 code == CV_Lab2BGR || code == CV_Lab2RGB ? (CvColorCvtFunc2)icvLab2BGRx_8u_C3CnR : 2488 code == CV_Luv2BGR || code == CV_Luv2RGB ? (CvColorCvtFunc2)icvLuv2BGRx_8u_C3CnR : 0; 2489 else if( depth == CV_16U ) 2490 func2 = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? (CvColorCvtFunc2)icvYCrCb2BGRx_16u_C3CnR : 2491 code == CV_XYZ2BGR || code == CV_XYZ2RGB ? (CvColorCvtFunc2)icvXYZ2BGRx_16u_C3CnR : 0; 2492 else if( depth == CV_32F ) 2493 func2 = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? (CvColorCvtFunc2)icvYCrCb2BGRx_32f_C3CnR : 2494 code == CV_XYZ2BGR || code == CV_XYZ2RGB ? (CvColorCvtFunc2)icvXYZ2BGRx_32f_C3CnR : 2495 code == CV_HSV2BGR || code == CV_HSV2RGB ? (CvColorCvtFunc2)icvHSV2BGRx_32f_C3CnR : 2496 code == CV_HLS2BGR || code == CV_HLS2RGB ? (CvColorCvtFunc2)icvHLS2BGRx_32f_C3CnR : 2497 code == CV_Lab2BGR || code == CV_Lab2RGB ? (CvColorCvtFunc2)icvLab2BGRx_32f_C3CnR : 2498 code == CV_Luv2BGR || code == CV_Luv2RGB ? (CvColorCvtFunc2)icvLuv2BGRx_32f_C3CnR : 0; 2499 2500 param[0] = dst_cn; 2501 param[1] = code == CV_XYZ2BGR || code == CV_YCrCb2BGR || code == CV_HSV2BGR || 2502 code == CV_Lab2BGR || code == CV_Luv2BGR || code == CV_HLS2BGR ? 0 : 2; 2503 break; 2504 2505 case CV_BayerBG2BGR: 2506 case CV_BayerGB2BGR: 2507 case CV_BayerRG2BGR: 2508 case CV_BayerGR2BGR: 2509 if( src_cn != 1 || dst_cn != 3 ) 2510 CV_ERROR( CV_BadNumChannels, 2511 "Incorrect number of channels for this conversion code" ); 2512 2513 if( depth != CV_8U ) 2514 CV_ERROR( CV_BadDepth, 2515 "Bayer pattern can be converted only to 8-bit 3-channel BGR/RGB image" ); 2516 2517 func1 = (CvColorCvtFunc1)icvBayer2BGR_8u_C1C3R; 2518 param[0] = code; // conversion code 2519 break; 2520 default: 2521 CV_ERROR( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); 2522 } 2523 2524 if( func0 ) 2525 { 2526 IPPI_CALL( func0( src->data.ptr, src_step, dst->data.ptr, dst_step, size )); 2527 } 2528 else if( func1 ) 2529 { 2530 IPPI_CALL( func1( src->data.ptr, src_step, 2531 dst->data.ptr, dst_step, size, param[0] )); 2532 } 2533 else if( func2 ) 2534 { 2535 IPPI_CALL( func2( src->data.ptr, src_step, 2536 dst->data.ptr, dst_step, size, param[0], param[1] )); 2537 } 2538 else if( func3 ) 2539 { 2540 IPPI_CALL( func3( src->data.ptr, src_step, 2541 dst->data.ptr, dst_step, size, param[0], param[1], param[2] )); 2542 } 2543 else 2544 CV_ERROR( CV_StsUnsupportedFormat, "The image format is not supported" ); 2545 2546 __END__; 2547 } 2548 2549 /* End of file. */ 2550 2551 2552