- Main Page
- Related Pages
- Data Structures
- Files
- Examples

- File List

# /home/v/Kate/WORK_TREES/kate-sorceress-backup/v/src/kate/src/kate_fp.c

    00001 /* Copyright (C) 2008, 2009 Vincent Penquerc'h.
    00002    This file is part of the Kate codec library.
    00003    Written by Vincent Penquerc'h.
    00004
    00005    Use, distribution and reproduction of this library is governed
    00006    by a BSD style source license included with this source in the
    00007    file 'COPYING'. Please read these terms before distributing. */
    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 /* #define WRITE_64_IN_TWO_32 */
    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 /* need 8 bits, then a bit for sign and kate_fp_bits-(t+h) per value */
    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); /* can be between 0 and kate_fp_cut_bits */
    00097   kate_pack_write(kpb,tail,kate_fp_cut_bits_bits); /* can be between 0 and kate_fp_cut_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); /* will autoclip the head */
    00116     }
    00117     else
    00118 #endif
    00119     {
    00120       kate_pack_write(kpb,v,bits); /* will autoclip the head */
    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