00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 #define KATE_INTERNAL
00011 #include "kate_internal.h"
00012 
00013 #ifdef HAVE_STDLIB_H
00014 #include <stdlib.h>
00015 #endif
00016 #include "kate/kate.h"
00017 #include "kate_bitwise.h"
00018 #include "kate_fp.h"
00019 
00020 #define MERGE_STREAMS
00021 #define MERGE_STREAMS_COUNT_THRESHOLD 0
00022 
00023 
00024 #define FLOAT_SCALE ((kate_float)(((kate_fp)1)<<(KATE_FP_FRAC)))
00025 #define kate_fp_bits (sizeof(kate_fp)*8)
00026 #define kate_fp_cut_bits ((kate_fp_bits)/2-1)
00027 #define kate_fp_cut_bits_bits (kate_fp_bits==16?3:kate_fp_bits==32?4:kate_fp_bits==64?5:8)
00028 #define kate_fp_sign_bit (kate_fp_bits==16?0x8000:kate_fp_bits==32?0x80000000:kate_fp_bits==64?((kate_int64_t)-1):0)
00029 
00030 static inline kate_fp f2kfp(kate_float f)
00031 {
00032   kate_fp test=(kate_fp)(f*(FLOAT_SCALE*2));
00033   if (test&1)
00034     return (kate_fp)(f*FLOAT_SCALE+(kate_float)0.5);
00035   else
00036     return (kate_fp)(f*FLOAT_SCALE);
00037 }
00038 
00039 static inline kate_float kfp2f(kate_fp v)
00040 {
00041   return v/FLOAT_SCALE;
00042 }
00043 
00044 static int kate_fp_scan(size_t count,const kate_fp *values,size_t streams,int *head,int *tail)
00045 {
00046   kate_fp v=0,tst;
00047   size_t n;
00048 
00049   if (!values || !head || !tail) return KATE_E_INVALID_PARAMETER;
00050 
00051   while (count--) {
00052     kate_fp value=*values;
00053     values+=streams;
00054     if (value<0) value=-value;
00055     v|=value;
00056   }
00057 
00058   tst=v;
00059   for (n=0;n<kate_fp_cut_bits;++n) {
00060     if (tst&kate_fp_sign_bit) break;
00061     tst<<=1;
00062   }
00063   *head=n;
00064 
00065   tst=v;
00066   for (n=0;n<kate_fp_cut_bits;++n) {
00067     if (tst&1) break;
00068     tst>>=1;
00069   }
00070   *tail=n;
00071 
00072   return 0;
00073 }
00074 
00075 #if 0
00076 static int kate_fp_scan_constant(size_t count,const kate_fp *values,size_t streams,kate_fp constant)
00077 {
00078   while (count--) {
00079     kate_fp value=*values;
00080     values+=streams;
00081     if (value!=constant) return 1;
00082   }
00083   return 0;
00084 }
00085 #endif
00086 
00087 
00088 int kate_fp_encode(size_t count,const kate_fp *values,size_t streams,kate_pack_buffer *kpb)
00089 {
00090   int head,tail;
00091   int bits;
00092 
00093   if (!kpb || count==0 || !values) return KATE_E_INVALID_PARAMETER;
00094 
00095   kate_fp_scan(count,values,streams,&head,&tail);
00096   kate_pack_write(kpb,head,kate_fp_cut_bits_bits); 
00097   kate_pack_write(kpb,tail,kate_fp_cut_bits_bits); 
00098   bits=kate_fp_bits-tail-head;
00099   while (count--) {
00100     kate_fp v=*values++;
00101     if (head>0) {
00102       if (v<0) {
00103         kate_pack_write(kpb,1,1);
00104         v=-v;
00105       }
00106       else {
00107         kate_pack_write(kpb,0,1);
00108       }
00109     }
00110     v>>=tail;
00111 #ifdef WRITE_64_IN_TWO_32
00112     if (bits>32) {
00113       kate_pack_write(kpb,v,32);
00114       v>>=32;
00115       kate_pack_write(kpb,v,bits-32); 
00116     }
00117     else
00118 #endif
00119     {
00120       kate_pack_write(kpb,v,bits); 
00121     }
00122   }
00123 
00124   return 0;
00125 }
00126 
00127 int kate_fp_encode_kate_float(size_t count,const kate_float *values,size_t streams,kate_pack_buffer *kpb)
00128 {
00129   kate_fp *fp_values;
00130   size_t s,n;
00131   int ret;
00132 
00133   if (count*streams==0) return 0;
00134 
00135   if (streams>1 && count>MERGE_STREAMS_COUNT_THRESHOLD) {
00136 #ifdef MERGE_STREAMS
00137     count*=streams;
00138     streams=1;
00139     kate_pack_write(kpb,1,1);
00140 #else
00141     kate_pack_write(kpb,0,1);
00142 #endif
00143   }
00144 
00145   fp_values=(kate_fp*)kate_checked_malloc(count,sizeof(kate_fp));
00146   if (!fp_values) return KATE_E_OUT_OF_MEMORY;
00147 
00148   for (s=0;s<streams;++s) {
00149     for (n=0;n<count;++n) {
00150       kate_float v=values[n*streams+s];
00151       fp_values[n]=f2kfp(v);
00152     }
00153 
00154     ret=kate_fp_encode(count,fp_values,1,kpb);
00155     if (ret<0) {
00156       kate_free(fp_values);
00157       return ret;
00158     }
00159   }
00160 
00161   kate_free(fp_values);
00162 
00163   return 0;
00164 }
00165 
00166 int kate_fp_decode(size_t count,kate_fp *values,size_t streams,kate_pack_buffer *kpb)
00167 {
00168   int head,tail,bits;
00169   kate_fp v;
00170 
00171   if (!kpb || count==0 || !values) return KATE_E_INVALID_PARAMETER;
00172 
00173   head=kate_pack_read(kpb,kate_fp_cut_bits_bits);
00174   tail=kate_pack_read(kpb,kate_fp_cut_bits_bits);
00175   bits=kate_fp_bits-head-tail;
00176   while (count--) {
00177     int sign=0;
00178     if (head>0) {
00179       sign=kate_pack_read1(kpb);
00180     }
00181 #ifdef WRITE_64_IN_TWO_32
00182     if (bits>32) {
00183       kate_fp low=kate_pack_read(kpb,32);
00184       v=kate_pack_read(kpb,bits-32);
00185       v<<=32;
00186       v|=low;
00187     }
00188     else
00189 #endif
00190     {
00191       v=kate_pack_read(kpb,bits);
00192     }
00193     v<<=tail;
00194     if (sign) v=-v;
00195     *values=v;
00196     values+=streams;
00197   }
00198 
00199   return 0;
00200 }
00201 
00202 int kate_fp_decode_kate_float(size_t count,kate_float *values,size_t streams,kate_pack_buffer *kpb)
00203 {
00204   kate_fp *fp_values;
00205   size_t s,n;
00206   int ret;
00207 
00208   if (count*streams==0) return 0;
00209 
00210   if (streams>1 && count>MERGE_STREAMS_COUNT_THRESHOLD) {
00211     if (kate_pack_read1(kpb)) {
00212       count*=streams;
00213       streams=1;
00214     }
00215   }
00216 
00217   fp_values=(kate_fp*)kate_checked_malloc(count,sizeof(kate_fp));
00218   if (!fp_values) return KATE_E_OUT_OF_MEMORY;
00219 
00220   for (s=0;s<streams;++s) {
00221     ret=kate_fp_decode(count,fp_values,1,kpb);
00222     if (ret<0) {
00223       kate_free(fp_values);
00224       return ret;
00225     }
00226 
00227     for (n=0;n<count;++n) {
00228       values[n*streams+s]=kfp2f(fp_values[n]);
00229     }
00230   }
00231 
00232   kate_free(fp_values);
00233 
00234   return 0;
00235 }
00236