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