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 ) \ 104CvStatus 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 121ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 1 ) 122ICV_DEF_LUT_FUNC_8U_CN( 16u, ushort, 1 ) 123ICV_DEF_LUT_FUNC_8U_CN( 32s, int, 1 ) 124ICV_DEF_LUT_FUNC_8U_CN( 64f, double, 1 ) 125 126ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 2 ) 127ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 3 ) 128ICV_DEF_LUT_FUNC_8U_CN( 8u, uchar, 4 ) 129 130 131#define ICV_DEF_LUT_FUNC_8U( flavor, dsttype ) \ 132static CvStatus CV_STDCALL \ 133icvLUT_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 186ICV_DEF_LUT_FUNC_8U( 8u, uchar ) 187ICV_DEF_LUT_FUNC_8U( 16u, ushort ) 188ICV_DEF_LUT_FUNC_8U( 32s, int ) 189ICV_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 203CV_DEF_INIT_FUNC_TAB_2D( LUT_Transform8u, C1R ) 204CV_DEF_INIT_FUNC_TAB_2D( LUT_Transform8u, CnR ) 205 206typedef CvStatus (CV_STDCALL * CvLUT_TransformCnFunc)( 207 const void* src, int srcstep, void* dst, 208 int dststep, CvSize size, const void* lut, int cn ); 209 210CV_IMPL void 211cvLUT( 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