network compression test
[carveJwlIkooP6JGAAIwe30JlM.git] / network_compression.h
diff --git a/network_compression.h b/network_compression.h
new file mode 100644 (file)
index 0000000..6ef08f9
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef NETWORK_COMPRESSION_H
+#define NETWORK_COMPRESSION_H
+
+#include "vg/vg_stdint.h"
+#include "vg/vg_m.h"
+
+typedef struct bitpack_ctx bitpack_ctx;
+struct bitpack_ctx {
+   enum bitpack_mode {
+      k_bitpack_compress,
+      k_bitpack_decompress
+   }
+   mode;
+
+   u8 *buffer;
+   u32 bytes, buffer_len;
+};
+
+static void bitpack_bytes( bitpack_ctx *ctx, u32 bytes, void *data ){
+   u8 *ext = data;
+   for( u32 i=0; i<bytes; i++ ){
+      u32 index = ctx->bytes+i;
+      if( ctx->mode == k_bitpack_compress ){
+         if( index < ctx->buffer_len )
+            ctx->buffer[index] = ext[i];
+      }
+      else{
+         if( index < ctx->buffer_len )
+            ext[i] = ctx->buffer[index];
+         else
+            ext[i] = 0x00;
+      }
+   }
+   ctx->bytes += bytes;
+}
+
+static void bitpack_qf32( bitpack_ctx *ctx, u32 bits, 
+                          f32 min, f32 max, f32 *v ){
+   u32 mask = (0x1 << bits) - 1;
+
+   if( ctx->mode == k_bitpack_compress ){
+      u32 a = vg_quantf( *v, bits, min, max );
+      bitpack_bytes( ctx, bits/8, &a );
+   }
+   else {
+      u32 a = 0;
+      bitpack_bytes( ctx, bits/8, &a );
+      *v = vg_dequantf( a, bits, min, max );
+   }
+}
+
+static void bitpack_qv2f( bitpack_ctx *ctx, u32 bits,
+                          f32 min, f32 max, v2f v ){
+   for( u32 i=0; i<2; i ++ )
+      bitpack_qf32( ctx, bits, min, max, v+i );
+}
+
+static void bitpack_qv3f( bitpack_ctx *ctx, u32 bits,
+                          f32 min, f32 max, v3f v ){
+   for( u32 i=0; i<3; i ++ )
+      bitpack_qf32( ctx, bits, min, max, v+i );
+}
+
+static void bitpack_qv4f( bitpack_ctx *ctx, u32 bits,
+                          f32 min, f32 max, v4f v ){
+   for( u32 i=0; i<4; i ++ )
+      bitpack_qf32( ctx, bits, min, max, v+i );
+}
+
+static void bitpack_qquat( bitpack_ctx *ctx, v4f quat ){
+   const f32 k_domain = 0.70710678118f;
+
+   if( ctx->mode == k_bitpack_compress ){
+      v4f qabs;
+      for( u32 i=0; i<4; i++ )
+         qabs[i] = fabsf(quat[i]);
+
+      u32 lxy =  qabs[1]>qabs[0],
+          lzw = (qabs[3]>qabs[2])+2,
+          l   = qabs[lzw]>qabs[lxy]? lzw: lxy;
+
+      f32 sign = vg_signf(quat[l]);
+
+      u32 smallest[3];
+      for( u32 i=0, j=0; i<4; i ++ )
+         if( i != l )
+            smallest[j ++] = vg_quantf( quat[i]*sign, 10, -k_domain, k_domain );
+      
+      u32 comp = (smallest[0]<<2) | (smallest[1]<<12) | (smallest[2]<<22) | l;
+      bitpack_bytes( ctx, 4, &comp );
+   }
+   else {
+      u32 comp;
+      bitpack_bytes( ctx, 4, &comp );
+
+      u32 smallest[3] = {(comp>>2 )&0x3ff,
+                         (comp>>12)&0x3ff,
+                         (comp>>22)&0x3ff},
+          l = comp & 0x3;
+
+      f32 m = 1.0f;
+
+      for( u32 i=0, j=0; i<4; i ++ ){
+         if( i != l ){
+            quat[i] = vg_dequantf( smallest[j ++], 10, -k_domain, k_domain );
+            m -= quat[i]*quat[i];
+         }
+      }
+
+      quat[l] = sqrtf(m);
+      q_normalize( quat );
+   }
+}
+
+#endif /* NETWORK_COMPRESSION_H */