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