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
icvBGR5x52BGRx_8u_C2CnR(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int dst_cn,int blue_idx,int green_bits)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
icvBGRx2BGR5x5_8u_CnC2R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx,int green_bits)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
icvBGRx2ABC_IPP_8u_CnC3R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx,CvColorCvtFunc0 ipp_func)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
icvBGR5x52Gray_8u_C2C1R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int green_bits)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
icvGray2BGR5x5_8u_C1C2R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int green_bits)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
icvBGRx2Gray_8u_CnC1R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvBGRx2Gray_16u_CnC1R(const ushort * src,int srcstep,ushort * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvBGRx2Gray_32f_CnC1R(const float * src,int srcstep,float * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvABC2BGRx_8u_C3CnR(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int dst_cn,int blue_idx,CvColorCvtFunc2 cvtfunc_32f,const float * pre_coeffs,int postscale)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
icvBGRx2ABC_8u_CnC3R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx,CvColorCvtFunc2 cvtfunc_32f,int prescale,const float * post_coeffs)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
icvBGRx2HSV_8u_CnC3R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvBGRx2HSV_32f_CnC3R(const float * src,int srcstep,float * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvHSV2BGRx_32f_C3CnR(const float * src,int srcstep,float * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvHSV2BGRx_8u_C3CnR(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvBGRx2HLS_32f_CnC3R(const float * src,int srcstep,float * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvHLS2BGRx_32f_C3CnR(const float * src,int srcstep,float * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvBGRx2HLS_8u_CnC3R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvHLS2BGRx_8u_C3CnR(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvBGRx2Lab_8u_CnC3R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvBGRx2Lab_32f_CnC3R(const float * src,int srcstep,float * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvLab2BGRx_32f_C3CnR(const float * src,int srcstep,float * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvLab2BGRx_8u_C3CnR(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvBGRx2Luv_32f_CnC3R(const float * src,int srcstep,float * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvLuv2BGRx_32f_C3CnR(const float * src,int srcstep,float * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvBGRx2Luv_8u_CnC3R(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int src_cn,int blue_idx)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
icvLuv2BGRx_8u_C3CnR(const uchar * src,int srcstep,uchar * dst,int dststep,CvSize size,int dst_cn,int blue_idx)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
icvBayer2BGR_8u_C1C3R(const uchar * bayer0,int bayer_step,uchar * dst0,int dst_step,CvSize size,int code)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
cvCvtColor(const CvArr * srcarr,CvArr * dstarr,int code)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