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 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 #include "_cxcore.h"
     43 
     44 /****************************************************************************************\
     45 *                                    LUT Transform                                       *
     46 \****************************************************************************************/
     47 
     48 #define ICV_LUT_CASE_C1( type )             \
     49     for( i = 0; i <= size.width-4; i += 4 ) \
     50     {                                       \
     51         type t0 = lut[src[i]];              \
     52         type t1 = lut[src[i+1]];            \
     53         dst[i] = t0;                        \
     54         dst[i+1] = t1;                      \
     55                                             \
     56         t0 = lut[src[i+2]];                 \
     57         t1 = lut[src[i+3]];                 \
     58         dst[i+2] = t0;                      \
     59         dst[i+3] = t1;                      \
     60     }                                       \
     61                                             \
     62     for( ; i < size.width; i++ )            \
     63     {                                       \
     64         type t0 = lut[src[i]];              \
     65         dst[i] = t0;                        \
     66     }
     67 
     68 
     69 #define ICV_LUT_CASE_C2( type )             \
     70     for( i = 0; i < size.width; i += 2 )    \
     71     {                                       \
     72         type t0 = lut[src[i]*2];            \
     73         type t1 = lut[src[i+1]*2 + 1];      \
     74         dst[i] = t0;                        \
     75         dst[i+1] = t1;                      \
     76     }
     77 
     78 #define ICV_LUT_CASE_C3( type )             \
     79     for( i = 0; i < size.width; i += 3 )    \
     80     {                                       \
     81         type t0 = lut[src[i]*3];            \
     82         type t1 = lut[src[i+1]*3 + 1];      \
     83         type t2 = lut[src[i+2]*3 + 2];      \
     84         dst[i] = t0;                        \
     85         dst[i+1] = t1;                      \
     86         dst[i+2] = t2;                      \
     87     }
     88 
     89 #define ICV_LUT_CASE_C4( type )             \
     90     for( i = 0; i < size.width; i += 4 )    \
     91     {                                       \
     92         type t0 = lut[src[i]*4];            \
     93         type t1 = lut[src[i+1]*4 + 1];      \
     94         dst[i] = t0;                        \
     95         dst[i+1] = t1;                      \
     96         t0 = lut[src[i+2]*4 + 2];           \
     97         t1 = lut[src[i+3]*4 + 3];           \
     98         dst[i+2] = t0;                      \
     99         dst[i+3] = t1;                      \
    100     }
    101 
    102 
    103 #define  ICV_DEF_LUT_FUNC_8U_CN( flavor, dsttype, cn )      \
    104 CvStatus CV_STDCALL icvLUT_Transform8u_##flavor##_C##cn##R( \
    105     const uchar* src, int srcstep,                          \
    106     dsttype* dst, int dststep, CvSize size,                 \
    107     const dsttype* lut )                                    \
    108 {                                                           \
    109     size.width *= cn;                                       \
    110     dststep /= sizeof(dst[0]);                              \
    111     for( ; size.height--; src += srcstep, dst += dststep )  \
    112     {                                                       \
    113         int i;                                              \
    114         ICV_LUT_CASE_C##cn( dsttype )                       \
    115     }                                                       \
    116                                                             \
    117     return CV_OK;                                           \
    118 }
    119 
    120 
    121 ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 1 )
    122 ICV_DEF_LUT_FUNC_8U_CN( 16u, ushort, 1 )
    123 ICV_DEF_LUT_FUNC_8U_CN( 32s, int, 1 )
    124 ICV_DEF_LUT_FUNC_8U_CN( 64f, double, 1 )
    125 
    126 ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 2 )
    127 ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 3 )
    128 ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 4 )
    129 
    130 
    131 #define  ICV_DEF_LUT_FUNC_8U( flavor, dsttype )             \
    132 static CvStatus CV_STDCALL                                  \
    133 icvLUT_Transform8u_##flavor##_CnR(                          \
    134     const uchar* src, int srcstep,                          \
    135     dsttype* dst, int dststep, CvSize size,                 \
    136     const dsttype* _lut, int cn )                           \
    137 {                                                           \
    138     int max_block_size = (1 << 10)*cn;                      \
    139     dsttype lutp[1024];                                     \
    140     int i, k;                                               \
    141                                                             \
    142     size.width *= cn;                                       \
    143     dststep /= sizeof(dst[0]);                              \
    144                                                             \
    145     if( size.width*size.height < 256 )                      \
    146     {                                                       \
    147         for( ; size.height--; src+=srcstep, dst+=dststep )  \
    148             for( k = 0; k < cn; k++ )                       \
    149                 for( i = 0; i < size.width; i += cn )       \
    150                     dst[i+k] = _lut[src[i+k]*cn+k];         \
    151         return CV_OK;                                       \
    152     }                                                       \
    153                                                             \
    154     /* repack the lut to planar layout */                   \
    155     for( k = 0; k < cn; k++ )                               \
    156         for( i = 0; i < 256; i++ )                          \
    157             lutp[i+k*256] = _lut[i*cn+k];                   \
    158                                                             \
    159     for( ; size.height--; src += srcstep, dst += dststep )  \
    160     {                                                       \
    161         for( i = 0; i < size.width; )                       \
    162         {                                                   \
    163             int j, limit = MIN(size.width,i+max_block_size);\
    164             for( k=0; k<cn; k++, src++, dst++ )             \
    165             {                                               \
    166                 const dsttype* lut = lutp + k*256;          \
    167                 for( j = i; j <= limit - cn*2; j += cn*2 )  \
    168                 {                                           \
    169                     dsttype t0 = lut[src[j]];               \
    170                     dsttype t1 = lut[src[j+cn]];            \
    171                     dst[j] = t0; dst[j+cn] = t1;            \
    172                 }                                           \
    173                                                             \
    174                 for( ; j < limit; j += cn )                 \
    175                     dst[j] = lut[src[j]];                   \
    176             }                                               \
    177             src -= cn;                                      \
    178             dst -= cn;                                      \
    179             i += limit;                                     \
    180         }                                                   \
    181     }                                                       \
    182                                                             \
    183     return CV_OK;                                           \
    184 }
    185 
    186 ICV_DEF_LUT_FUNC_8U( 8u, uchar )
    187 ICV_DEF_LUT_FUNC_8U( 16u, ushort )
    188 ICV_DEF_LUT_FUNC_8U( 32s, int )
    189 ICV_DEF_LUT_FUNC_8U( 64f, double )
    190 
    191 #undef   icvLUT_Transform8u_8s_C1R
    192 #undef   icvLUT_Transform8u_16s_C1R
    193 #undef   icvLUT_Transform8u_32f_C1R
    194 
    195 #define  icvLUT_Transform8u_8s_C1R    icvLUT_Transform8u_8u_C1R
    196 #define  icvLUT_Transform8u_16s_C1R   icvLUT_Transform8u_16u_C1R
    197 #define  icvLUT_Transform8u_32f_C1R   icvLUT_Transform8u_32s_C1R
    198 
    199 #define  icvLUT_Transform8u_8s_CnR    icvLUT_Transform8u_8u_CnR
    200 #define  icvLUT_Transform8u_16s_CnR   icvLUT_Transform8u_16u_CnR
    201 #define  icvLUT_Transform8u_32f_CnR   icvLUT_Transform8u_32s_CnR
    202 
    203 CV_DEF_INIT_FUNC_TAB_2D( LUT_Transform8u, C1R )
    204 CV_DEF_INIT_FUNC_TAB_2D( LUT_Transform8u, CnR )
    205 
    206 typedef CvStatus (CV_STDCALL * CvLUT_TransformCnFunc)(
    207     const void* src, int srcstep, void* dst,
    208     int dststep, CvSize size, const void* lut, int cn );
    209 
    210 CV_IMPL  void
    211 cvLUT( const void* srcarr, void* dstarr, const void* lutarr )
    212 {
    213     static CvFuncTable lut_c1_tab, lut_cn_tab;
    214     static CvLUT_TransformFunc lut_8u_tab[4];
    215     static int inittab = 0;
    216 
    217     CV_FUNCNAME( "cvLUT" );
    218 
    219     __BEGIN__;
    220 
    221     int  coi1 = 0, coi2 = 0;
    222     int  depth, cn, lut_cn;
    223     CvMat  srcstub, *src = (CvMat*)srcarr;
    224     CvMat  dststub, *dst = (CvMat*)dstarr;
    225     CvMat  lutstub, *lut = (CvMat*)lutarr;
    226     uchar* lut_data;
    227     uchar* shuffled_lut = 0;
    228     CvSize size;
    229 
    230     if( !inittab )
    231     {
    232         icvInitLUT_Transform8uC1RTable( &lut_c1_tab );
    233         icvInitLUT_Transform8uCnRTable( &lut_cn_tab );
    234         lut_8u_tab[0] = (CvLUT_TransformFunc)icvLUT_Transform8u_8u_C1R;
    235         lut_8u_tab[1] = (CvLUT_TransformFunc)icvLUT_Transform8u_8u_C2R;
    236         lut_8u_tab[2] = (CvLUT_TransformFunc)icvLUT_Transform8u_8u_C3R;
    237         lut_8u_tab[3] = (CvLUT_TransformFunc)icvLUT_Transform8u_8u_C4R;
    238         inittab = 1;
    239     }
    240 
    241     if( !CV_IS_MAT(src) )
    242         CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
    243 
    244     if( !CV_IS_MAT(dst) )
    245         CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
    246 
    247     if( !CV_IS_MAT(lut) )
    248         CV_CALL( lut = cvGetMat( lut, &lutstub ));
    249 
    250     if( coi1 != 0 || coi2 != 0 )
    251         CV_ERROR( CV_BadCOI, "" );
    252 
    253     if( !CV_ARE_SIZES_EQ( src, dst ))
    254         CV_ERROR( CV_StsUnmatchedSizes, "" );
    255 
    256     if( !CV_ARE_CNS_EQ( src, dst ))
    257         CV_ERROR( CV_StsUnmatchedFormats, "" );
    258 
    259     if( CV_MAT_DEPTH( src->type ) > CV_8S )
    260         CV_ERROR( CV_StsUnsupportedFormat, "" );
    261 
    262     depth = CV_MAT_DEPTH( dst->type );
    263     cn = CV_MAT_CN( dst->type );
    264     lut_cn = CV_MAT_CN( lut->type );
    265 
    266     if( !CV_IS_MAT_CONT(lut->type) || (lut_cn != 1 && lut_cn != cn) ||
    267         !CV_ARE_DEPTHS_EQ( dst, lut ) || lut->width*lut->height != 256 )
    268         CV_ERROR( CV_StsBadArg, "The LUT must be continuous array \n"
    269                                 "with 256 elements of the same type as destination" );
    270 
    271     size = cvGetMatSize( src );
    272     if( lut_cn == 1 )
    273     {
    274         size.width *= cn;
    275         cn = 1;
    276     }
    277 
    278     if( CV_IS_MAT_CONT( src->type & dst->type ))
    279     {
    280         size.width *= size.height;
    281         size.height = 1;
    282     }
    283 
    284     lut_data = lut->data.ptr;
    285 
    286     if( CV_MAT_DEPTH( src->type ) == CV_8S )
    287     {
    288         int half_size = CV_ELEM_SIZE1(depth)*cn*128;
    289         shuffled_lut = (uchar*)cvStackAlloc(half_size*2);
    290 
    291         // shuffle lut
    292         memcpy( shuffled_lut, lut_data + half_size, half_size );
    293         memcpy( shuffled_lut + half_size, lut_data, half_size );
    294 
    295         lut_data = shuffled_lut;
    296     }
    297 
    298     if( lut_cn == 1 || (lut_cn <= 4 && depth == CV_8U) )
    299     {
    300         CvLUT_TransformFunc func = depth == CV_8U ? lut_8u_tab[cn-1] :
    301             (CvLUT_TransformFunc)(lut_c1_tab.fn_2d[depth]);
    302 
    303         if( !func )
    304             CV_ERROR( CV_StsUnsupportedFormat, "" );
    305 
    306         IPPI_CALL( func( src->data.ptr, src->step, dst->data.ptr,
    307                          dst->step, size, lut_data ));
    308     }
    309     else
    310     {
    311         CvLUT_TransformCnFunc func =
    312             (CvLUT_TransformCnFunc)(lut_cn_tab.fn_2d[depth]);
    313 
    314         if( !func )
    315             CV_ERROR( CV_StsUnsupportedFormat, "" );
    316 
    317         IPPI_CALL( func( src->data.ptr, src->step, dst->data.ptr,
    318                          dst->step, size, lut_data, cn ));
    319     }
    320 
    321     __END__;
    322 }
    323 
    324 /* End of file. */
    325