1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
9 // Intel License Agreement
10 // For Open Source Computer Vision Library
12 // Copyright (C) 2000, Intel Corporation, all rights reserved.
13 // Third party copyrights are property of their respective owners.
15 // Redistribution and use in source and binary forms, with or without modification,
16 // are permitted provided that the following conditions are met:
18 // * Redistribution's of source code must retain the above copyright notice,
19 // this list of conditions and the following disclaimer.
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.
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.
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.
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 \**********************************************************************************/
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:
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.
56 Contributors License Agreement:
59 MD-Mathematische Dienste GmbH
65 Redistribution and use in source and binary forms,
66 with or without modification, are permitted provided
67 that the following conditions are met:
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.
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 \**********************************************************************************/
92 typedef CvStatus (CV_STDCALL * CvColorCvtFunc0)(
93 const void* src, int srcstep, void* dst, int dststep, CvSize size );
95 typedef CvStatus (CV_STDCALL * CvColorCvtFunc1)(
96 const void* src, int srcstep, void* dst, int dststep,
97 CvSize size, int param0 );
99 typedef CvStatus (CV_STDCALL * CvColorCvtFunc2)(
100 const void* src, int srcstep, void* dst, int dststep,
101 CvSize size, int param0, int param1 );
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 );
107 /****************************************************************************************\
108 * Various 3/4-channel to 3/4-channel RGB transformations *
109 \****************************************************************************************/
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 ) \
119 srcstep /= sizeof(src[0]); \
120 dststep /= sizeof(dst[0]); \
121 srcstep -= size.width*src_cn; \
124 for( ; size.height--; src += srcstep, dst += dststep ) \
126 for( i = 0; i < size.width; i += 3, src += src_cn ) \
128 arrtype t0=src[blue_idx], t1=src[1], t2=src[blue_idx^2]; \
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 ) \
147 srcstep /= sizeof(src[0]); \
148 dststep /= sizeof(dst[0]); \
149 srcstep -= size.width*3; \
152 for( ; size.height--; src += srcstep, dst += dststep ) \
154 for( i = 0; i < size.width; i += 4, src += 3 ) \
156 arrtype t0=src[blue_idx], t1=src[1], t2=src[blue_idx^2]; \
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 ) \
175 srcstep /= sizeof(src[0]); \
176 dststep /= sizeof(dst[0]); \
179 for( ; size.height--; src += srcstep, dst += dststep ) \
181 for( i = 0; i < size.width; i += 4 ) \
183 arrtype t0 = src[2], t1 = src[1], t2 = src[0], t3 = src[3]; \
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 )
206 /****************************************************************************************\
207 * Transforming 16-bit (565 or 555) RGB to/from 24/32-bit (888[8]) RGB *
208 \****************************************************************************************/
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 )
217 assert( green_bits == 5 || green_bits == 6 );
218 dststep -= size.width*dst_cn;
220 for( ; size.height--; src += srcstep, dst += dststep )
222 if( green_bits == 6 )
223 for( i = 0; i < size.width; i++, dst += dst_cn )
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);
233 for( i = 0; i < size.width; i++, dst += dst_cn )
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);
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 )
255 srcstep -= size.width*src_cn;
257 for( ; size.height--; src += srcstep, dst += dststep )
259 if( green_bits == 6 )
260 for( i = 0; i < size.width; i++, src += src_cn )
262 int t = (src[blue_idx] >> 3)|((src[1]&~3) << 3)|((src[blue_idx^2]&~7) << 8);
263 ((ushort*)dst)[i] = (ushort)t;
266 for( i = 0; i < size.width; i++, src += src_cn )
268 int t = (src[blue_idx] >> 3)|((src[1]&~7) << 2)|((src[blue_idx^2]&~7) << 7);
269 ((ushort*)dst)[i] = (ushort)t;
278 /////////////////////////// IPP Color Conversion Functions //////////////////////////////
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;
287 icvRGB2HSV_8u_C3R_t icvRGB2HSV_8u_C3R_p = 0;
288 icvHSV2RGB_8u_C3R_t icvHSV2RGB_8u_C3R_p = 0;
290 icvBGR2Lab_8u_C3R_t icvBGR2Lab_8u_C3R_p = 0;
291 icvLab2BGR_8u_C3R_t icvLab2BGR_8u_C3R_p = 0;
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;
298 icvRGB2Luv_8u_C3R_t icvRGB2Luv_8u_C3R_p = 0;
299 icvLuv2RGB_8u_C3R_t icvLuv2RGB_8u_C3R_p = 0;
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;
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 ) \
313 int block_size = MIN(1 << 14, size.width); \
316 int do_copy = src_cn > 3 || blue_idx != 2 || src == dst; \
317 CvStatus status = CV_OK; \
320 return ipp_func( src, srcstep, dst, dststep, size ); \
322 srcstep /= sizeof(src[0]); \
323 dststep /= sizeof(dst[0]); \
325 buffer = (arrtype*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); \
326 srcstep -= size.width*src_cn; \
328 for( ; size.height--; src += srcstep, dst += dststep ) \
330 for( i = 0; i < size.width; i += block_size ) \
332 arrtype* dst1 = dst + i*3; \
333 di = MIN(block_size, size.width - i); \
335 for( k = 0; k < di*3; k += 3, src += src_cn ) \
337 arrtype b = src[blue_idx]; \
338 arrtype g = src[1]; \
339 arrtype r = src[blue_idx^2]; \
345 status = ipp_func( buffer, CV_STUB_STEP, \
346 dst1, CV_STUB_STEP, cvSize(di,1) ); \
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 )
361 int block_size = MIN(1 << 14, size.width);
364 int do_copy = src_cn > 3 || blue_idx != 2 || src == dst;
365 CvStatus status = CV_OK;
368 return ipp_func( src, srcstep, dst, dststep, size );
370 srcstep /= sizeof(src[0]);
371 dststep /= sizeof(dst[0]);
373 buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
374 srcstep -= size.width*src_cn;
376 for( ; size.height--; src += srcstep, dst += dststep )
378 for( i = 0; i < size.width; i += block_size )
380 uchar* dst1 = dst + i*3;
381 di = MIN(block_size, size.width - i);
383 for( k = 0; k < di*3; k += 3, src += src_cn )
385 uchar b = src[blue_idx];
387 uchar r = src[blue_idx^2];
393 status = ipp_func( buffer, CV_STUB_STEP,
394 dst1, CV_STUB_STEP, cvSize(di,1) );
405 //CV_IMPL_BGRx2ABC_IPP( 8u, uchar )
406 CV_IMPL_BGRx2ABC_IPP( 16u, ushort )
407 CV_IMPL_BGRx2ABC_IPP( 32f, float )
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 ) \
415 int block_size = MIN(1 << 10, size.width); \
418 int do_copy = dst_cn > 3 || blue_idx != 2 || src == dst; \
419 CvStatus status = CV_OK; \
422 return ipp_func( src, srcstep, dst, dststep, size ); \
424 srcstep /= sizeof(src[0]); \
425 dststep /= sizeof(dst[0]); \
427 buffer = (arrtype*)cvStackAlloc( block_size*3*sizeof(buffer[0]) ); \
428 dststep -= size.width*dst_cn; \
430 for( ; size.height--; src += srcstep, dst += dststep ) \
432 for( i = 0; i < size.width; i += block_size ) \
434 const arrtype* src1 = src + i*3; \
435 di = MIN(block_size, size.width - i); \
437 status = ipp_func( src1, CV_STUB_STEP, \
438 buffer, CV_STUB_STEP, cvSize(di,1) ); \
442 for( k = 0; k < di*3; k += 3, dst += dst_cn ) \
444 arrtype r = buffer[k]; \
445 arrtype g = buffer[k+1]; \
446 arrtype b = buffer[k+2]; \
449 dst[blue_idx^2] = r; \
459 CV_IMPL_ABC2BGRx_IPP( 8u, uchar )
460 CV_IMPL_ABC2BGRx_IPP( 16u, ushort )
461 CV_IMPL_ABC2BGRx_IPP( 32f, float )
464 /////////////////////////////////////////////////////////////////////////////////////////
467 /****************************************************************************************\
468 * Color to/from Grayscale *
469 \****************************************************************************************/
471 #define fix(x,n) (int)((x)*(1 << (n)) + 0.5)
472 #define descale CV_DESCALE
474 #define cscGr_32f 0.299f
475 #define cscGg_32f 0.587f
476 #define cscGb_32f 0.114f
478 /* BGR/RGB -> Gray */
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)
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, \
491 srcstep /= sizeof(src[0]); \
492 dststep /= sizeof(src[0]); \
493 dststep -= size.width*dst_cn; \
495 for( ; size.height--; src += srcstep, dst += dststep ) \
498 for( i = 0; i < size.width; i++, dst += 3 ) \
499 dst[0] = dst[1] = dst[2] = src[i]; \
501 for( i = 0; i < size.width; i++, dst += 4 ) \
503 dst[0] = dst[1] = dst[2] = src[i]; \
512 CV_IMPL_GRAY2BGRX( 8u, uchar )
513 CV_IMPL_GRAY2BGRX( 16u, ushort )
514 CV_IMPL_GRAY2BGRX( 32f, float )
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 )
523 assert( green_bits == 5 || green_bits == 6 );
525 for( ; size.height--; src += srcstep, dst += dststep )
527 if( green_bits == 6 )
528 for( i = 0; i < size.width; i++ )
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);
536 for( i = 0; i < size.width; i++ )
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);
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 )
555 assert( green_bits == 5 || green_bits == 6 );
557 for( ; size.height--; src += srcstep, dst += dststep )
559 if( green_bits == 6 )
560 for( i = 0; i < size.width; i++ )
563 ((ushort*)dst)[i] = (ushort)((t >> 3)|((t & ~3) << 3)|((t & ~7) << 8));
566 for( i = 0; i < size.width; i++ )
569 ((ushort*)dst)[i] = (ushort)(t|(t << 5)|(t << 10));
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 )
583 srcstep -= size.width*src_cn;
585 if( size.width*size.height >= 1024 )
587 int* tab = (int*)cvStackAlloc( 256*3*sizeof(tab[0]) );
588 int r = 0, g = 0, b = (1 << (csc_shift-1));
590 for( i = 0; i < 256; i++ )
597 b += cscGb, r += cscGr;
599 b += cscGr, r += cscGb;
602 for( ; size.height--; src += srcstep, dst += dststep )
604 for( i = 0; i < size.width; i++, src += src_cn )
606 int t0 = tab[src[0]] + tab[src[1] + 256] + tab[src[2] + 512];
607 dst[i] = (uchar)(t0 >> csc_shift);
613 for( ; size.height--; src += srcstep, dst += dststep )
615 for( i = 0; i < size.width; i++, src += src_cn )
617 int t0 = src[blue_idx]*cscGb + src[1]*cscGg + src[blue_idx^2]*cscGr;
618 dst[i] = (uchar)CV_DESCALE(t0, csc_shift);
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 )
632 int cb = cscGb, cr = cscGr;
633 srcstep /= sizeof(src[0]);
634 dststep /= sizeof(dst[0]);
635 srcstep -= size.width*src_cn;
638 cb = cscGr, cr = cscGb;
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);
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 )
655 float cb = cscGb_32f, cr = cscGr_32f;
657 cb = cscGr_32f, cr = cscGb_32f;
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;
670 /****************************************************************************************\
672 \****************************************************************************************/
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
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)
688 #define yuv_descale(x) CV_DESCALE((x), yuv_shift)
689 #define yuv_prescale(x) ((x) << yuv_shift)
691 #define yuvRCr_32f 1.403f
692 #define yuvGCr_32f (-0.714f)
693 #define yuvGCb_32f (-0.344f)
694 #define yuvBCb_32f 1.773f
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)
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 ) \
708 srcstep /= sizeof(src[0]); \
709 dststep /= sizeof(src[0]); \
710 srcstep -= size.width*src_cn; \
713 for( ; size.height--; src += srcstep, dst += dststep ) \
715 for( i = 0; i < size.width; i += 3, src += src_cn ) \
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); \
731 CV_IMPL_BGRx2YCrCb( 8u, uchar, int, yuv_descale, CV_CAST_8U,
732 yuvYb, yuvYg, yuvYr, yuvCr, yuvCb, 128 )
734 CV_IMPL_BGRx2YCrCb( 16u, ushort, int, yuv_descale, CV_CAST_16U,
735 yuvYb, yuvYg, yuvYr, yuvCr, yuvCb, 32768 )
737 CV_IMPL_BGRx2YCrCb( 32f, float, float, CV_NOP, CV_NOP,
738 yuvYb_32f, yuvYg_32f, yuvYr_32f, yuvCr_32f, yuvCb_32f, 0.5f )
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 ) \
749 srcstep /= sizeof(src[0]); \
750 dststep /= sizeof(src[0]); \
751 dststep -= size.width*dst_cn; \
754 for( ; size.height--; src += srcstep, dst += dststep ) \
756 for( i = 0; i < size.width; i += 3, dst += dst_cn ) \
758 worktype Y = prescale_macro(src[i]), \
759 Cr = src[i+1] - YUV_Cx_BIAS, \
760 Cb = src[i+2] - YUV_Cx_BIAS; \
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 ); \
766 dst[blue_idx] = cast_macro(b); \
767 dst[1] = cast_macro(g); \
768 dst[blue_idx^2] = cast_macro(r); \
778 CV_IMPL_YCrCb2BGRx( 8u, uchar, int, yuv_prescale, yuv_descale, CV_CAST_8U,
779 yuvBCb, yuvGCr, yuvGCb, yuvRCr, 128 )
781 CV_IMPL_YCrCb2BGRx( 16u, ushort, int, yuv_prescale, yuv_descale, CV_CAST_16U,
782 yuvBCb, yuvGCr, yuvGCb, yuvRCr, 32768 )
784 CV_IMPL_YCrCb2BGRx( 32f, float, float, CV_NOP, CV_NOP, CV_NOP,
785 yuvBCb_32f, yuvGCr_32f, yuvGCb_32f, yuvRCr_32f, 0.5f )
788 /****************************************************************************************\
790 \****************************************************************************************/
792 #define xyzXr_32f 0.412453f
793 #define xyzXg_32f 0.357580f
794 #define xyzXb_32f 0.180423f
796 #define xyzYr_32f 0.212671f
797 #define xyzYg_32f 0.715160f
798 #define xyzYb_32f 0.072169f
800 #define xyzZr_32f 0.019334f
801 #define xyzZg_32f 0.119193f
802 #define xyzZb_32f 0.950227f
804 #define xyzRx_32f 3.240479f
805 #define xyzRy_32f (-1.53715f)
806 #define xyzRz_32f (-0.498535f)
808 #define xyzGx_32f (-0.969256f)
809 #define xyzGy_32f 1.875991f
810 #define xyzGz_32f 0.041556f
812 #define xyzBx_32f 0.055648f
813 #define xyzBy_32f (-0.204043f)
814 #define xyzBz_32f 1.057311f
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 )
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 )
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 )
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 )
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 )
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 )
841 #define xyz_descale(x) CV_DESCALE((x),xyz_shift)
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 ) \
851 worktype t, matrix[] = \
853 xyzXb##suffix, xyzXg##suffix, xyzXr##suffix, \
854 xyzYb##suffix, xyzYg##suffix, xyzYr##suffix, \
855 xyzZb##suffix, xyzZg##suffix, xyzZr##suffix \
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 ); \
863 srcstep /= sizeof(src[0]); \
864 dststep /= sizeof(dst[0]); \
865 srcstep -= size.width*src_cn; \
870 CV_SWAP( matrix[0], matrix[2], t ); \
871 CV_SWAP( matrix[3], matrix[5], t ); \
872 CV_SWAP( matrix[6], matrix[8], t ); \
875 for( ; size.height--; src += srcstep, dst += dststep ) \
877 for( i = 0; i < size.width; i += 3, src += src_cn ) \
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]); \
886 dst[i] = (arrtype)(x); \
887 dst[i+1] = (arrtype)(y); \
888 dst[i+2] = cast_macro(z); /*sum of weights for z > 1*/ \
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 )
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 ) \
909 worktype t, matrix[] = \
911 xyzBx##suffix, xyzBy##suffix, xyzBz##suffix, \
912 xyzGx##suffix, xyzGy##suffix, xyzGz##suffix, \
913 xyzRx##suffix, xyzRy##suffix, xyzRz##suffix \
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 ); \
921 srcstep /= sizeof(src[0]); \
922 dststep /= sizeof(dst[0]); \
923 dststep -= size.width*dst_cn; \
928 CV_SWAP( matrix[0], matrix[6], t ); \
929 CV_SWAP( matrix[1], matrix[7], t ); \
930 CV_SWAP( matrix[2], matrix[8], t ); \
933 for( ; size.height--; src += srcstep, dst += dststep ) \
935 for( i = 0; i < size.width; i += 3, dst += dst_cn ) \
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]); \
944 dst[0] = cast_macro(b); \
945 dst[1] = cast_macro(g); \
946 dst[2] = cast_macro(r); \
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 )
961 /****************************************************************************************\
962 * Non-linear Color Space Transformations *
963 \****************************************************************************************/
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 )
972 int block_size = MIN(1 << 8, size.width);
973 float* buffer = (float*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
975 CvStatus status = CV_OK;
977 dststep -= size.width*dst_cn;
979 for( ; size.height--; src += srcstep, dst += dststep )
981 for( i = 0; i < size.width; i += block_size )
983 const uchar* src1 = src + i*3;
984 di = MIN(block_size, size.width - i);
986 for( k = 0; k < di*3; k += 3 )
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];
996 status = cvtfunc_32f( buffer, 0, buffer, 0, cvSize(di,1), 3, blue_idx );
1002 for( k = 0; k < di*3; k += 3, dst += dst_cn )
1004 int b = cvRound(buffer[k]*255.);
1005 int g = cvRound(buffer[k+1]*255.);
1006 int r = cvRound(buffer[k+2]*255.);
1008 dst[0] = CV_CAST_8U(b);
1009 dst[1] = CV_CAST_8U(g);
1010 dst[2] = CV_CAST_8U(r);
1017 for( k = 0; k < di*3; k += 3, dst += dst_cn )
1019 int b = cvRound(buffer[k]);
1020 int g = cvRound(buffer[k+1]);
1021 int r = cvRound(buffer[k+2]);
1023 dst[0] = CV_CAST_8U(b);
1024 dst[1] = CV_CAST_8U(g);
1025 dst[2] = CV_CAST_8U(r);
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 )
1044 int block_size = MIN(1 << 8, size.width);
1045 float* buffer = (float*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
1047 CvStatus status = CV_OK;
1049 srcstep -= size.width*src_cn;
1051 for( ; size.height--; src += srcstep, dst += dststep )
1053 for( i = 0; i < size.width; i += block_size )
1055 uchar* dst1 = dst + i*3;
1056 di = MIN(block_size, size.width - i);
1060 for( k = 0; k < di*3; k += 3, src += src_cn )
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;
1073 for( k = 0; k < di*3; k += 3, src += src_cn )
1075 float b = CV_8TO32F(src[0]);
1076 float g = CV_8TO32F(src[1]);
1077 float r = CV_8TO32F(src[2]);
1085 status = cvtfunc_32f( buffer, 0, buffer, 0, cvSize(di,1), 3, blue_idx );
1089 for( k = 0; k < di*3; k += 3 )
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);
1105 /****************************************************************************************\
1107 \****************************************************************************************/
1109 static const uchar icvHue255To180[] =
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
1130 static const uchar icvHue180To255[] =
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,
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 )
1155 const int hsv_shift = 12;
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
1193 if( icvRGB2HSV_8u_C3R_p )
1195 CvStatus status = icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size,
1196 src_cn, blue_idx, icvRGB2HSV_8u_C3R_p );
1200 for( ; size.height--; dst += dststep )
1202 for( i = 0; i <= size.width - 12; i += 12 )
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;
1209 for( ; i < size.width; i += 3 )
1210 dst[i] = icvHue255To180[dst[i]];
1216 srcstep -= size.width*src_cn;
1219 for( ; size.height--; src += srcstep, dst += dststep )
1221 for( i = 0; i < size.width; i += 3, src += src_cn )
1223 int b = (src)[blue_idx], g = (src)[1], r = (src)[2^blue_idx];
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 );
1234 vr = v == r ? -1 : 0;
1235 vg = v == g ? -1 : 0;
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);
1244 dst[i+1] = (uchar)s;
1245 dst[i+2] = (uchar)v;
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 )
1259 srcstep /= sizeof(src[0]);
1260 dststep /= sizeof(dst[0]);
1261 srcstep -= size.width*src_cn;
1264 for( ; size.height--; src += srcstep, dst += dststep )
1266 for( i = 0; i < size.width; i += 3, src += src_cn )
1268 float b = src[blue_idx], g = src[1], r = src[2^blue_idx];
1276 if( vmin > g ) vmin = g;
1277 if( vmin > b ) vmin = b;
1280 s = diff/(float)(fabs(v) + FLT_EPSILON);
1281 diff = (float)(60./(diff + FLT_EPSILON));
1285 h = (b - r)*diff + 120.f;
1287 h = (r - g)*diff + 240.f;
1289 if( h < 0 ) h += 360.f;
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 )
1306 srcstep /= sizeof(src[0]);
1307 dststep /= sizeof(dst[0]);
1308 dststep -= size.width*dst_cn;
1311 for( ; size.height--; src += srcstep, dst += dststep )
1313 for( i = 0; i < size.width; i += 3, dst += dst_cn )
1315 float h = src[i], s = src[i+1], v = src[i+2];
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}};
1326 h *= 0.016666666666666666f; // h /= 60;
1328 do h += 6; while( h < 0 );
1330 do h -= 6; while( h >= 6 );
1331 sector = cvFloor(h);
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));
1339 b = tab[sector_data[sector][0]];
1340 g = tab[sector_data[sector][1]];
1341 r = tab[sector_data[sector][2]];
1346 dst[blue_idx^2] = r;
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 )
1360 static const float pre_coeffs[] = { 2.f, 0.f, 0.0039215686274509803f, 0.f, 1.f, 0.f };
1362 if( icvHSV2RGB_8u_C3R_p )
1364 int block_size = MIN(1 << 14, size.width);
1367 CvStatus status = CV_OK;
1369 buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
1370 dststep -= size.width*dst_cn;
1372 for( ; size.height--; src += srcstep, dst += dststep )
1374 for( i = 0; i < size.width; i += block_size )
1376 const uchar* src1 = src + i*3;
1377 di = MIN(block_size, size.width - i);
1378 for( k = 0; k < di*3; k += 3 )
1380 uchar h = icvHue180To255[src1[k]];
1381 uchar s = src1[k+1];
1382 uchar v = src1[k+2];
1388 status = icvHSV2RGB_8u_C3R_p( buffer, di*3,
1389 buffer, di*3, cvSize(di,1) );
1393 for( k = 0; k < di*3; k += 3, dst += dst_cn )
1395 uchar r = buffer[k];
1396 uchar g = buffer[k+1];
1397 uchar b = buffer[k+2];
1400 dst[blue_idx^2] = r;
1410 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx,
1411 (CvColorCvtFunc2)icvHSV2BGRx_32f_C3CnR, pre_coeffs, 0 );
1415 /****************************************************************************************\
1417 \****************************************************************************************/
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 )
1425 if( icvRGB2HLS_32f_C3R_p )
1427 CvStatus status = icvBGRx2ABC_IPP_32f_CnC3R( src, srcstep, dst, dststep, size,
1428 src_cn, blue_idx, icvRGB2HLS_32f_C3R_p );
1432 dststep /= sizeof(dst[0]);
1434 for( ; size.height--; dst += dststep )
1436 for( i = 0; i <= size.width - 12; i += 12 )
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;
1443 for( ; i < size.width; i += 3 )
1444 dst[i] = dst[i]*360.f;
1450 srcstep /= sizeof(src[0]);
1451 dststep /= sizeof(dst[0]);
1452 srcstep -= size.width*src_cn;
1455 for( ; size.height--; src += srcstep, dst += dststep )
1457 for( i = 0; i < size.width; i += 3, src += src_cn )
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;
1464 if( vmax < g ) vmax = g;
1465 if( vmax < b ) vmax = b;
1466 if( vmin > g ) vmin = g;
1467 if( vmin > b ) vmin = b;
1470 l = (vmax + vmin)*0.5f;
1472 if( diff > FLT_EPSILON )
1474 s = l < 0.5f ? diff/(vmax + vmin) : diff/(2 - vmax - vmin);
1479 else if( vmax == g )
1480 h = (b - r)*diff + 120.f;
1482 h = (r - g)*diff + 240.f;
1484 if( h < 0.f ) h += 360.f;
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 )
1502 srcstep /= sizeof(src[0]);
1503 dststep /= sizeof(dst[0]);
1505 if( icvHLS2RGB_32f_C3R_p )
1507 int block_size = MIN(1 << 10, size.width);
1510 CvStatus status = CV_OK;
1512 buffer = (float*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
1513 dststep -= size.width*dst_cn;
1515 for( ; size.height--; src += srcstep, dst += dststep )
1517 for( i = 0; i < size.width; i += block_size )
1519 const float* src1 = src + i*3;
1520 di = MIN(block_size, size.width - i);
1521 for( k = 0; k < di*3; k += 3 )
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;
1528 status = icvHLS2RGB_32f_C3R_p( buffer, di*3*sizeof(dst[0]),
1529 buffer, di*3*sizeof(dst[0]), cvSize(di,1) );
1533 for( k = 0; k < di*3; k += 3, dst += dst_cn )
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;
1546 dststep -= size.width*dst_cn;
1549 for( ; size.height--; src += srcstep, dst += dststep )
1551 for( i = 0; i < size.width; i += 3, dst += dst_cn )
1553 float h = src[i], l = src[i+1], s = src[i+2];
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}};
1565 float p2 = l <= 0.5f ? l*(1 + s) : l + s - l*s;
1566 float p1 = 2*l - p2;
1568 h *= 0.016666666666666666f; // h /= 60;
1570 do h += 6; while( h < 0 );
1572 do h -= 6; while( h >= 6 );
1574 assert( 0 <= h && h < 6 );
1575 sector = cvFloor(h);
1580 tab[2] = p1 + (p2 - p1)*(1-h);
1581 tab[3] = p1 + (p2 - p1)*h;
1583 b = tab[sector_data[sector][0]];
1584 g = tab[sector_data[sector][1]];
1585 r = tab[sector_data[sector][2]];
1590 dst[blue_idx^2] = r;
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 )
1603 static const float post_coeffs[] = { 0.5f, 0.f, 255.f, 0.f, 255.f, 0.f };
1605 if( icvRGB2HLS_8u_C3R_p )
1607 CvStatus status = icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size,
1608 src_cn, blue_idx, icvRGB2HLS_8u_C3R_p );
1612 for( ; size.height--; dst += dststep )
1615 for( i = 0; i <= size.width - 12; i += 12 )
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;
1622 for( ; i < size.width; i += 3 )
1623 dst[i] = icvHue255To180[dst[i]];
1629 return icvBGRx2ABC_8u_CnC3R( src, srcstep, dst, dststep, size, src_cn, blue_idx,
1630 (CvColorCvtFunc2)icvBGRx2HLS_32f_CnC3R, 1, post_coeffs );
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 )
1638 static const float pre_coeffs[] = { 2.f, 0.f, 0.0039215686274509803f, 0.f,
1639 0.0039215686274509803f, 0.f };
1641 if( icvHLS2RGB_8u_C3R_p )
1643 int block_size = MIN(1 << 14, size.width);
1646 CvStatus status = CV_OK;
1648 buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
1649 dststep -= size.width*dst_cn;
1651 for( ; size.height--; src += srcstep, dst += dststep )
1653 for( i = 0; i < size.width; i += block_size )
1655 const uchar* src1 = src + i*3;
1656 di = MIN(block_size, size.width - i);
1657 for( k = 0; k < di*3; k += 3 )
1659 uchar h = icvHue180To255[src1[k]];
1660 uchar l = src1[k+1];
1661 uchar s = src1[k+2];
1667 status = icvHLS2RGB_8u_C3R_p( buffer, di*3,
1668 buffer, di*3, cvSize(di,1) );
1672 for( k = 0; k < di*3; k += 3, dst += dst_cn )
1674 uchar r = buffer[k];
1675 uchar g = buffer[k+1];
1676 uchar b = buffer[k+2];
1679 dst[blue_idx^2] = r;
1689 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx,
1690 (CvColorCvtFunc2)icvHLS2BGRx_32f_C3CnR, pre_coeffs, 1 );
1694 /****************************************************************************************\
1696 \****************************************************************************************/
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 */
1702 #define labYr_32f 0.212671f /* = xyzYr_32f */
1703 #define labYg_32f 0.715160f /* = xyzYg_32f */
1704 #define labYb_32f 0.072169f /* = xyzYb_32f */
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 */
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 */
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 */
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 */
1722 #define labT_32f 0.008856f
1724 #define labT fix(labT_32f*255,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)
1732 #define labYr fix(labYr_32f,lab_shift)
1733 #define labYg fix(labYg_32f,lab_shift)
1734 #define labYb fix(labYb_32f,lab_shift)
1736 #define labZr fix(labZr_32f,lab_shift)
1737 #define labZg fix(labZg_32f,lab_shift)
1738 #define labZb fix(labZb_32f,lab_shift)
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
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)
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
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 )
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 );*/
1799 srcstep -= size.width*src_cn;
1802 for( ; size.height--; src += srcstep, dst += dststep )
1804 for( i = 0; i < size.width; i += 3, src += src_cn )
1806 int b = src[blue_idx], g = src[1], r = src[2^blue_idx];
1810 x = b*labXb + g*labXg + r*labXr;
1811 y = b*labYb + g*labYg + r*labYr;
1812 z = b*labZb + g*labZg + r*labZr;
1815 x = CV_DESCALE( x, lab_shift );
1818 assert( (unsigned)x < 512 ), x = icvLabCubeRootTab[x];
1820 x = CV_DESCALE(x*labSmallScale + labSmallShift,lab_shift);
1823 z = CV_DESCALE( z, lab_shift );
1826 assert( (unsigned)z < 512 ), z = icvLabCubeRootTab[z];
1828 z = CV_DESCALE(z*labSmallScale + labSmallShift,lab_shift);
1831 y = CV_DESCALE( y, lab_shift );
1835 assert( (unsigned)y < 512 ), y = icvLabCubeRootTab[y];
1836 L = CV_DESCALE(y*labLScale - labLShift, 2*lab_shift );
1840 L = CV_DESCALE(y*labLScale2,lab_shift);
1841 y = CV_DESCALE(y*labSmallScale + labSmallShift,lab_shift);
1844 a = CV_DESCALE( 500*(x - y), lab_shift ) + 128;
1845 b = CV_DESCALE( 200*(y - z), lab_shift ) + 128;
1847 dst[i] = CV_CAST_8U(L);
1848 dst[i+1] = CV_CAST_8U(a);
1849 dst[i+2] = CV_CAST_8U(b);
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 )
1862 srcstep /= sizeof(src[0]);
1863 dststep /= sizeof(dst[0]);
1864 srcstep -= size.width*src_cn;
1867 for( ; size.height--; src += srcstep, dst += dststep )
1869 for( i = 0; i < size.width; i += 3, src += src_cn )
1871 float b = src[blue_idx], g = src[1], r = src[2^blue_idx];
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;
1882 x = x*labSmallScale_32f + labSmallShift_32f;
1887 z = z*labSmallScale_32f + labSmallShift_32f;
1892 L = y*labLScale_32f - labLShift_32f;
1896 L = y*labLScale2_32f;
1897 y = y*labSmallScale_32f + labSmallShift_32f;
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 )
1918 srcstep /= sizeof(src[0]);
1919 dststep /= sizeof(dst[0]);
1920 dststep -= size.width*dst_cn;
1923 for( ; size.height--; src += srcstep, dst += dststep )
1925 for( i = 0; i < size.width; i += 3, dst += dst_cn )
1927 float L = src[i], a = src[i+1], b = src[i+2];
1931 L = (L + labLShift_32f)*(1.f/labLScale_32f);
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;
1944 dst[blue_idx^2] = r;
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 )
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 };
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 );
1967 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx,
1968 (CvColorCvtFunc2)icvLab2BGRx_32f_C3CnR, pre_coeffs, 1 );
1972 /****************************************************************************************\
1974 \****************************************************************************************/
1976 #define luvUn_32f 0.19793943f
1977 #define luvVn_32f 0.46831096f
1978 #define luvYmin_32f 0.05882353f /* 15/255 */
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 )
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 );*/
1990 srcstep /= sizeof(src[0]);
1991 dststep /= sizeof(dst[0]);
1992 srcstep -= size.width*src_cn;
1995 for( ; size.height--; src += srcstep, dst += dststep )
1997 for( i = 0; i < size.width; i += 3, src += src_cn )
1999 float b = src[blue_idx], g = src[1], r = src[2^blue_idx];
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;
2007 if( !x && !y && !z )
2012 L = labLScale_32f * cvCbrt(y) - labLShift_32f;
2014 L = labLScale2_32f * y;
2016 t = 1.f / (x + 15 * y + 3 * z);
2020 u = 13*L*(u - luvUn_32f);
2021 v = 13*L*(v - luvVn_32f);
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 )
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 );*/
2044 srcstep /= sizeof(src[0]);
2045 dststep /= sizeof(dst[0]);
2046 dststep -= size.width*dst_cn;
2049 for( ; size.height--; src += srcstep, dst += dststep )
2051 for( i = 0; i < size.width; i += 3, dst += dst_cn )
2053 float L = src[i], u = src[i+1], v = src[i+2];
2054 float x, y, z, t, u1, v1, b, g, r;
2058 t = (L + labLShift_32f) * (1.f/labLScale_32f);
2063 y = L * (1.f/labLScale2_32f);
2064 L = MAX( L, 0.001f );
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);
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;
2079 dst[blue_idx^2] = r;
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 )
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 };
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 );
2104 return icvBGRx2ABC_8u_CnC3R( src, srcstep, dst, dststep, size, src_cn, blue_idx,
2105 (CvColorCvtFunc2)icvBGRx2Luv_32f_CnC3R, 1, post_coeffs );
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 )
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 };
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 );
2123 return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx,
2124 (CvColorCvtFunc2)icvLuv2BGRx_32f_C3CnR, pre_coeffs, 1 );
2127 /****************************************************************************************\
2128 * Bayer Pattern -> RGB conversion *
2129 \****************************************************************************************/
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 )
2136 int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1;
2137 int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR;
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;
2145 for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
2148 const uchar* bayer = bayer0;
2150 const uchar* bayer_end = bayer + size.width;
2152 dst[-4] = dst[-3] = dst[-2] = dst[size.width*3-1] =
2153 dst[size.width*3] = dst[size.width*3+1] = 0;
2155 if( size.width <= 0 )
2158 if( start_with_green )
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;
2171 for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 )
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;
2179 dst[1] = bayer[bayer_step+1];
2181 t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
2182 t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
2184 dst[3] = bayer[bayer_step+2];
2190 for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 )
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;
2198 dst[-1] = bayer[bayer_step+1];
2200 t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
2201 t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
2203 dst[3] = bayer[bayer_step+2];
2208 if( bayer < bayer_end )
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;
2216 dst[blue] = bayer[bayer_step+1];
2222 start_with_green = !start_with_green;
2229 /****************************************************************************************\
2230 * The main function *
2231 \****************************************************************************************/
2234 cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code )
2236 CV_FUNCNAME( "cvCvtColor" );
2240 CvMat srcstub, *src = (CvMat*)srcarr;
2241 CvMat dststub, *dst = (CvMat*)dstarr;
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 };
2251 CV_CALL( src = cvGetMat( srcarr, &srcstub ));
2252 CV_CALL( dst = cvGetMat( dstarr, &dststub ));
2254 if( !CV_ARE_SIZES_EQ( src, dst ))
2255 CV_ERROR( CV_StsUnmatchedSizes, "" );
2257 if( !CV_ARE_DEPTHS_EQ( src, dst ))
2258 CV_ERROR( CV_StsUnmatchedFormats, "" );
2260 depth = CV_MAT_DEPTH(src->type);
2261 if( depth != CV_8U && depth != CV_16U && depth != CV_32F )
2262 CV_ERROR( CV_StsUnsupportedFormat, "" );
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;
2270 if( CV_IS_MAT_CONT(src->type & dst->type) &&
2271 code != CV_BayerBG2BGR && code != CV_BayerGB2BGR &&
2272 code != CV_BayerRG2BGR && code != CV_BayerGR2BGR )
2274 size.width *= size.height;
2276 src_step = dst_step = CV_STUB_STEP;
2283 if( src_cn != 3 || dst_cn != 4 )
2284 CV_ERROR( CV_BadNumChannels,
2285 "Incorrect number of channels for this conversion code" );
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
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" );
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;
2304 param[1] = code == CV_BGRA2BGR ? 0 : 2; // blue_idx
2308 if( src_cn != 4 || dst_cn != 4 )
2309 CV_ERROR( CV_BadNumChannels,
2310 "Incorrect number of channels for this conversion code" );
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;
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" );
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)" );
2334 func3 = (CvColorCvtFunc3)icvBGRx2BGR5x5_8u_CnC2R;
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
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" );
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)" );
2359 func3 = (CvColorCvtFunc3)icvBGR5x52BGRx_8u_C2CnR;
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
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" );
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;
2380 param[1] = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
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" );
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)" );
2394 func2 = (CvColorCvtFunc2)icvBGR5x52Gray_8u_C2C1R;
2396 param[0] = code == CV_BGR5652GRAY ? 6 : 5; // green_bits
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" );
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;
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" );
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)" );
2423 func2 = (CvColorCvtFunc2)icvGray2BGR5x5_8u_C1C2R;
2424 param[0] = code == CV_GRAY2BGR565 ? 6 : 5; // green_bits
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" );
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;
2462 param[1] = code == CV_BGR2XYZ || code == CV_BGR2YCrCb || code == CV_BGR2HSV ||
2463 code == CV_BGR2Lab || code == CV_BGR2Luv || code == CV_BGR2HLS ? 0 : 2;
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" );
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;
2501 param[1] = code == CV_XYZ2BGR || code == CV_YCrCb2BGR || code == CV_HSV2BGR ||
2502 code == CV_Lab2BGR || code == CV_Luv2BGR || code == CV_HLS2BGR ? 0 : 2;
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" );
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" );
2517 func1 = (CvColorCvtFunc1)icvBayer2BGR_8u_C1C3R;
2518 param[0] = code; // conversion code
2521 CV_ERROR( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
2526 IPPI_CALL( func0( src->data.ptr, src_step, dst->data.ptr, dst_step, size ));
2530 IPPI_CALL( func1( src->data.ptr, src_step,
2531 dst->data.ptr, dst_step, size, param[0] ));
2535 IPPI_CALL( func2( src->data.ptr, src_step,
2536 dst->data.ptr, dst_step, size, param[0], param[1] ));
2540 IPPI_CALL( func3( src->data.ptr, src_step,
2541 dst->data.ptr, dst_step, size, param[0], param[1], param[2] ));
2544 CV_ERROR( CV_StsUnsupportedFormat, "The image format is not supported" );