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