00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CONVERTER_H
00019 #define CONVERTER_H
00020
00021 #include <limits>
00022
00023 #include <tjutils/tjcomplex.h>
00024 #include <tjutils/tjtypes.h>
00025 #include <tjutils/tjlog.h>
00026 #include <assert.h>
00027
00033
00034 class OdinData {
00035 public:
00036 static const char* get_compName();
00037 };
00038
00040
00046 enum autoscaleOption {noscale, autoscale};
00047
00049
00053 class Converter {
00054
00055 public:
00056
00057
00058
00060
00061
00062
00063 static int get_elements(const STD_complex&) {
00064 return 2;
00065 }
00066
00070 template<typename T>
00071 static int get_elements(const T&) {
00072 return 1;
00073 }
00074
00075
00077
00078
00085 template<typename Src, typename Dst>
00086 static void convert_array(const Src* src, Dst* dst, int srcsize, int dstsize, autoscaleOption scaleopt=autoscale) {
00087 Log<OdinData> odinlog("Converter","convert_array");
00088 init();
00089 const int srcstep=get_elements(*dst);
00090 const int dststep=get_elements(*src);
00091 bool doScale = (scaleopt!=noscale && std::numeric_limits<Dst>::is_integer);
00092
00093 if(dststep*srcsize != srcstep*dstsize) {
00094 ODINLOG(odinlog,warningLog) << "size mismatch: dststep(" << dststep << ") * srcsize(" << srcsize << ") != srcstep(" << srcstep << ") * dstsize(" << dstsize << ")" << STD_endl;
00095 }
00096
00097 double scale=1.0;
00098 double offset=0.0;
00099 if(doScale) {
00100 const double domain_minus=creal(std::numeric_limits<Dst>::min());
00101 const double domain_plus =creal(std::numeric_limits<Dst>::max());
00102 double minval=domain_plus;
00103 double maxval=domain_minus;
00104 if(srcsize>0) minval=maxval=creal(src[0]);
00105 for(int i=1; i<srcsize; i++) {
00106 if(src[i]<minval) minval=creal(src[i]);
00107 if(src[i]>maxval) maxval=creal(src[i]);
00108 }
00109
00110 ODINLOG(odinlog,normalDebug) << "src Range:" << minval << "=>" << maxval << STD_endl;
00111 ODINLOG(odinlog,normalDebug) << "dst Domain:" << domain_minus << "=>" << domain_plus << STD_endl;
00112
00113 assert(domain_minus<=0 && domain_plus>=0);
00114 assert(domain_minus<domain_plus);
00115
00116
00117
00118
00119
00120 if(minval>0 || !domain_minus)offset=-minval;
00121 else if(maxval<0 || !domain_plus)offset=-maxval;
00122
00123
00124 const double range_plus =maxval+offset;
00125 const double range_minus=minval+offset;
00126
00127
00128
00129 const double scale_plus =
00130 range_plus ? domain_plus/range_plus :
00131 std::numeric_limits<double>::max();
00132 const double scale_minus=
00133 range_minus ? domain_minus/ range_minus:
00134 std::numeric_limits<double>::max();
00135 ODINLOG(odinlog,normalDebug) << "scale_minus/scale_plus=" << scale_minus << "/" << scale_plus << STD_endl;
00136
00137 scale = std::min(scale_plus,scale_minus);
00138 doScale=(scale!=1. || offset);
00139 offset*=scale;
00140 }
00141 if(doScale)ODINLOG(odinlog,normalDebug) << "converting with scale/offset=" << scale << "/" << offset << STD_endl;
00142 else ODINLOG(odinlog,normalDebug) << "converting without scaling" << STD_endl;
00143
00144 if(srcstep==dststep)
00145 {
00146 if(doScale)
00147 convert_array_impl(src,dst, srcsize < dstsize?srcsize:dstsize,scale,offset);
00148 else
00149 convert_array_impl(src,dst, srcsize < dstsize?srcsize:dstsize);
00150 }
00151 else
00152 {
00153 int srcindex=0, dstindex=0;
00154 while(srcindex<srcsize && dstindex<dstsize) {
00155 convert(src+srcindex, dst+dstindex,scale,offset);
00156 srcindex+=srcstep;
00157 dstindex+=dststep;
00158 }
00159 }
00160 }
00161
00162 static void init();
00163
00164 private:
00165
00167
00168
00172 template<typename Src, typename Dst> static void convert_array_impl(const Src* src, Dst* dst, unsigned int count,double scale=1,double offset=0) {
00173 Log<OdinData> odinlog("Converter","convert_array_impl(using generic impl)");
00174 ODINLOG(odinlog,normalDebug) << "generic convert " << TypeTraits::type2label(*src) << "=>" << TypeTraits::type2label(*dst) << STD_endl;
00175 ODINLOG(odinlog,normalDebug) << "scale/offset=" << scale << "/" << offset << STD_endl;
00176 while(count--)
00177 convert(src++, dst++,scale,offset);
00178 }
00179
00180 template<typename Src> static void convert_array_impl(const Src* src, Src* dst, unsigned int count) {
00181 Log<OdinData> odinlog("Converter","convert_array_impl(using memcopy)");
00182 ODINLOG(odinlog,normalDebug) << "generic convert " << TypeTraits::type2label(*src) << "=>" << TypeTraits::type2label(*dst) << STD_endl;
00183 memcpy(dst,src,sizeof(Src)*count);
00184 }
00185
00186 #ifdef USE_OIL
00187 #define DECL_CONVERT(SRC_TYPE,DST_TYPE,SRC_KEY,DST_KEY) static void convert_array_impl(const SRC_TYPE *src,DST_TYPE *dst,const unsigned int count);
00188 #define DECL_SCALED_CONVERT(SRC_TYPE,DST_TYPE,SRC_KEY,DST_KEY) static void convert_array_impl(const SRC_TYPE *src,DST_TYPE *dst,const unsigned int count,const double scale,const double offset);
00189 #define DECL_CONVERT_CPY(TYPE) static void convert_array_impl(const TYPE *src,TYPE *dst,const unsigned int count);
00190
00191
00192 DECL_CONVERT(float,int32_t,f32,s32)
00193 DECL_CONVERT(double,int32_t,f64,s32)
00194 DECL_CONVERT_CPY(int32_t)
00195 DECL_CONVERT(uint32_t,int32_t,u32,s32)
00196 DECL_CONVERT(int16_t,int32_t,s16,s32)
00197 DECL_CONVERT(uint16_t,int32_t,u16,s32)
00198 DECL_CONVERT(int8_t,int32_t,s8,s32)
00199 DECL_CONVERT(uint8_t,int32_t,u8,s32)
00200
00201
00202 DECL_CONVERT(float,uint32_t,f32,u32)
00203 DECL_CONVERT(double,uint32_t,f64,u32)
00204 DECL_CONVERT(int32_t,uint32_t,s32,u32)
00205 DECL_CONVERT_CPY(uint32_t)
00206
00207 DECL_CONVERT(uint16_t,uint32_t,u16,u32)
00208
00209 DECL_CONVERT(uint8_t,uint32_t,u8,u32)
00210
00211
00212 DECL_CONVERT(float,int16_t,f32,s16)
00213 DECL_CONVERT(double,int16_t,f64,s16)
00214 DECL_CONVERT(int32_t,int16_t,s32,s16)
00215 DECL_CONVERT(uint32_t,int16_t,u32,s16)
00216 DECL_CONVERT_CPY(int16_t)
00217 DECL_CONVERT(uint16_t,int16_t,u16,s16)
00218 DECL_CONVERT(int8_t,int16_t,s8,s16)
00219 DECL_CONVERT(uint8_t,int16_t,u8,s16)
00220
00221
00222 DECL_CONVERT(float,uint16_t,f32,u16)
00223 DECL_CONVERT(double,uint16_t,f64,u16)
00224 DECL_CONVERT(int32_t,uint16_t,s32,u16)
00225 DECL_CONVERT(uint32_t,uint16_t,u32,u16)
00226 DECL_CONVERT(int16_t,uint16_t,s16,u16)
00227 DECL_CONVERT_CPY(uint16_t)
00228
00229 DECL_CONVERT(uint8_t,uint16_t,u8,u16)
00230
00231
00232 DECL_CONVERT(float,int8_t,f32,s8)
00233 DECL_CONVERT(double,int8_t,f64,s8)
00234 DECL_CONVERT(int32_t,int8_t,s32,s8)
00235 DECL_CONVERT(uint32_t,int8_t,u32,s8)
00236 DECL_CONVERT(int16_t,int8_t,s16,s8)
00237 DECL_CONVERT(uint16_t,int8_t,u16,s8)
00238 DECL_CONVERT_CPY(int8_t)
00239 DECL_CONVERT(uint8_t,int8_t,u8,s8)
00240
00241
00242 DECL_CONVERT(float,uint8_t,f32,u8)
00243 DECL_CONVERT(double,uint8_t,f64,u8)
00244 DECL_CONVERT(int32_t,uint8_t,s32,u8)
00245 DECL_CONVERT(uint32_t,uint8_t,u32,u8)
00246 DECL_CONVERT(int16_t,uint8_t,s16,u8)
00247 DECL_CONVERT(uint16_t,uint8_t,u16,u8)
00248 DECL_CONVERT(int8_t,uint8_t,s8,u8)
00249 DECL_CONVERT_CPY(uint8_t)
00250
00251
00252 DECL_CONVERT_CPY(float)
00253 DECL_CONVERT(double,float,f64,f32)
00254 DECL_CONVERT(int32_t,float,s32,f32)
00255 DECL_CONVERT(uint32_t,float,u32,f32)
00256 DECL_CONVERT(int16_t,float,s16,f32)
00257 DECL_CONVERT(uint16_t,float,u16,f32)
00258 DECL_CONVERT(int8_t,float,s8,f32)
00259 DECL_CONVERT(uint8_t,float,u8,f32)
00260
00261
00262 DECL_CONVERT(float,double,f32,f64)
00263 DECL_CONVERT_CPY(double)
00264 DECL_CONVERT(int32_t,double,s32,f64)
00265 DECL_CONVERT(uint32_t,double,u32,f64)
00266 DECL_CONVERT(int16_t,double,s16,f64)
00267 DECL_CONVERT(uint16_t,double,u16,f64)
00268 DECL_CONVERT(int8_t,double,s8,f64)
00269 DECL_CONVERT(uint8_t,double,u8,f64)
00270
00271
00272 DECL_SCALED_CONVERT(float,int32_t,f32,s32)
00273 DECL_SCALED_CONVERT(double,int32_t,f64,s32)
00274
00275
00276 DECL_SCALED_CONVERT(float,uint32_t,f32,u32)
00277 DECL_SCALED_CONVERT(double,uint32_t,f64,u32)
00278
00279
00280 DECL_SCALED_CONVERT(float,int16_t,f32,s16)
00281 DECL_SCALED_CONVERT(double,int16_t,f64,s16)
00282
00283
00284 DECL_SCALED_CONVERT(float,uint16_t,f32,u16)
00285 DECL_SCALED_CONVERT(double,uint16_t,f64,u16)
00286
00287
00288 DECL_SCALED_CONVERT(float,int8_t,f32,s8)
00289 DECL_SCALED_CONVERT(double,int8_t,f64,s8)
00290
00291
00292 DECL_SCALED_CONVERT(float,uint8_t,f32,u8)
00293 DECL_SCALED_CONVERT(double,uint8_t,f64,u8)
00294
00295
00296 DECL_SCALED_CONVERT(int32_t,float,s32,f32)
00297 DECL_SCALED_CONVERT(uint32_t,float,u32,f32)
00298 DECL_SCALED_CONVERT(int16_t,float,s16,f32)
00299 DECL_SCALED_CONVERT(uint16_t,float,u16,f32)
00300 DECL_SCALED_CONVERT(int8_t,float,s8,f32)
00301 DECL_SCALED_CONVERT(uint8_t,float,u8,f32)
00302
00303
00304 DECL_SCALED_CONVERT(int32_t,double,s32,f64)
00305 DECL_SCALED_CONVERT(uint32_t,double,u32,f64)
00306 DECL_SCALED_CONVERT(int16_t,double,s16,f64)
00307 DECL_SCALED_CONVERT(uint16_t,double,u16,f64)
00308 DECL_SCALED_CONVERT(int8_t,double,s8,f64)
00309 DECL_SCALED_CONVERT(uint8_t,double,u8,f64)
00310
00311 #undef DECL_CONVERT
00312 #undef DECL_SCALED_CONVERT
00313 #endif //USE_OIL
00314
00315
00316
00317 template<typename T> static T round(double x) {
00318 return (T)(x < 0 ? x - 0.5 : x + 0.5);
00319 }
00320
00321
00322
00323
00324
00325 static void convert(const s8bit* src, STD_complex* dst,float scale,float offset) {
00326 (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale);
00327 }
00328 static void convert(const u8bit* src, STD_complex* dst,float scale,float offset) {
00329 (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale);
00330 }
00331 static void convert(const u16bit* src, STD_complex* dst,float scale,float offset) {
00332 (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale);
00333 }
00334 static void convert(const s16bit* src, STD_complex* dst,float scale,float offset) {
00335 (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale);
00336 }
00337 static void convert(const u32bit* src, STD_complex* dst,float scale,float offset) {
00338 (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale);
00339 }
00340 static void convert(const s32bit* src, STD_complex* dst,float scale,float offset) {
00341 (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale);
00342 }
00343 static void convert(const float *src, STD_complex* dst,float scale,float offset) {
00344 dst[0]=STD_complex(src[0]*scale+offset,src[1]*scale);
00345 }
00346 static void convert(const double *src, STD_complex* dst,float scale,float offset) {
00347 dst[0]=STD_complex(src[0]*scale+offset,src[1]*scale);
00348 }
00349
00350
00351 static void convert(const STD_complex* src, s8bit* dst,float scale,float offset) {
00352 dst[0]=round<s8bit>(src->real()*scale+offset);
00353 dst[1]=round<s8bit>(src->imag()*scale);
00354 }
00355 static void convert(const STD_complex* src, u8bit* dst,float scale,float offset) {
00356 dst[0]=round<u8bit>(src->real()*scale+offset);
00357 dst[1]=round<u8bit>(src->imag()*scale);
00358 }
00359 static void convert(const STD_complex* src, s16bit* dst,float scale,float offset) {
00360 dst[0]=round<s16bit>(src->real()*scale+offset);
00361 dst[1]=round<s16bit>(src->imag()*scale);
00362 }
00363 static void convert(const STD_complex* src, u16bit* dst,float scale,float offset) {
00364 dst[0]=round<u16bit>(src->real()*scale+offset);
00365 dst[1]=round<u16bit>(src->imag()*scale);
00366 }
00367 static void convert(const STD_complex* src, s32bit* dst,float scale,float offset) {
00368 dst[0]=round<s32bit>(src->real()*scale+offset);
00369 dst[1]=round<s32bit>(src->imag()*scale);
00370 }
00371 static void convert(const STD_complex* src, u32bit* dst,float scale,float offset) {
00372 dst[0]=round<u32bit>(src->real()*scale+offset);
00373 dst[1]=round<u32bit>(src->imag()*scale);
00374 }
00375 static void convert(const STD_complex* src, float* dst,float scale,float offset) {
00376 dst[0]=src->real()*scale+offset;
00377 dst[1]=src->imag()*scale;
00378 }
00379 static void convert(const STD_complex* src, double* dst,float scale,float offset) {
00380 dst[0]=src->real()*scale+offset;
00381 dst[1]=src->imag()*scale;
00382 }
00383
00384
00385
00386 static void convert(const float* src, s8bit* dst,float scale,float offset) {
00387 dst[0]=round<s8bit>(src[0]*scale+offset);
00388 }
00389 static void convert(const float* src, u8bit* dst,float scale,float offset) {
00390 dst[0]=round<u8bit>(src[0]*scale+offset);
00391 }
00392 static void convert(const float* src, s16bit* dst,float scale,float offset) {
00393 dst[0]=round<s16bit>(src[0]*scale+offset);
00394 }
00395 static void convert(const float* src, u16bit* dst,float scale,float offset) {
00396 dst[0]=round<u16bit>(src[0]*scale+offset);
00397 }
00398 static void convert(const float* src, s32bit* dst,float scale,float offset) {
00399 dst[0]=round<s32bit>(src[0]*scale+offset);
00400 }
00401 static void convert(const float* src, u32bit* dst,float scale,float offset) {
00402 dst[0]=round<u32bit>(src[0]*scale+offset);
00403 }
00404
00405
00406
00407 static void convert(const double* src, s8bit* dst,float scale,float offset) {
00408 dst[0]=round<s8bit>(src[0]*scale+offset);
00409 }
00410 static void convert(const double* src, u8bit* dst,float scale,float offset) {
00411 dst[0]=round<u8bit>(src[0]*scale+offset);
00412 }
00413 static void convert(const double* src, s16bit* dst,float scale,float offset) {
00414 dst[0]=round<s16bit>(src[0]*scale+offset);
00415 }
00416 static void convert(const double* src, u16bit* dst,float scale,float offset) {
00417 dst[0]=round<u16bit>(src[0]*scale+offset);
00418 }
00419 static void convert(const double* src, s32bit* dst,float scale,float offset) {
00420 dst[0]=round<s32bit>(src[0]*scale+offset);
00421 }
00422 static void convert(const double* src, u32bit* dst,float scale,float offset) {
00423 dst[0]=round<u32bit>(src[0]*scale+offset);
00424 }
00425
00426
00427
00428
00429 template<typename Src, typename Dst>
00430 static void convert(const Src* src, Dst* dst,float scale,float offset) {
00431 dst[0]=(Dst)(src[0]*scale+offset);
00432 }
00433
00435
00436 Converter() {}
00437
00438
00439 };
00440
00444 #endif