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