misc
[carveJwlIkooP6JGAAIwe30JlM.git] / network_compression.h
1 #ifndef NETWORK_COMPRESSION_H
2 #define NETWORK_COMPRESSION_H
3
4 #include "vg/vg_stdint.h"
5 #include "vg/vg_m.h"
6
7 typedef struct bitpack_ctx bitpack_ctx;
8 struct bitpack_ctx {
9 enum bitpack_mode {
10 k_bitpack_compress,
11 k_bitpack_decompress
12 }
13 mode;
14
15 u8 *buffer;
16 u32 bytes, buffer_len;
17 };
18
19 static void bitpack_bytes( bitpack_ctx *ctx, u32 bytes, void *data ){
20 u8 *ext = data;
21 for( u32 i=0; i<bytes; i++ ){
22 u32 index = ctx->bytes+i;
23 if( ctx->mode == k_bitpack_compress ){
24 if( index < ctx->buffer_len )
25 ctx->buffer[index] = ext[i];
26 }
27 else{
28 if( index < ctx->buffer_len )
29 ext[i] = ctx->buffer[index];
30 else
31 ext[i] = 0x00;
32 }
33 }
34 ctx->bytes += bytes;
35 }
36
37 static void bitpack_qf32( bitpack_ctx *ctx, u32 bits,
38 f32 min, f32 max, f32 *v ){
39 u32 mask = (0x1 << bits) - 1;
40
41 if( ctx->mode == k_bitpack_compress ){
42 u32 a = vg_quantf( *v, bits, min, max );
43 bitpack_bytes( ctx, bits/8, &a );
44 }
45 else {
46 u32 a = 0;
47 bitpack_bytes( ctx, bits/8, &a );
48 *v = vg_dequantf( a, bits, min, max );
49 }
50 }
51
52 static void bitpack_qv2f( bitpack_ctx *ctx, u32 bits,
53 f32 min, f32 max, v2f v ){
54 for( u32 i=0; i<2; i ++ )
55 bitpack_qf32( ctx, bits, min, max, v+i );
56 }
57
58 static void bitpack_qv3f( bitpack_ctx *ctx, u32 bits,
59 f32 min, f32 max, v3f v ){
60 for( u32 i=0; i<3; i ++ )
61 bitpack_qf32( ctx, bits, min, max, v+i );
62 }
63
64 static void bitpack_qv4f( bitpack_ctx *ctx, u32 bits,
65 f32 min, f32 max, v4f v ){
66 for( u32 i=0; i<4; i ++ )
67 bitpack_qf32( ctx, bits, min, max, v+i );
68 }
69
70 static void bitpack_qquat( bitpack_ctx *ctx, v4f quat ){
71 const f32 k_domain = 0.70710678118f;
72
73 if( ctx->mode == k_bitpack_compress ){
74 v4f qabs;
75 for( u32 i=0; i<4; i++ )
76 qabs[i] = fabsf(quat[i]);
77
78 u32 lxy = qabs[1]>qabs[0],
79 lzw = (qabs[3]>qabs[2])+2,
80 l = qabs[lzw]>qabs[lxy]? lzw: lxy;
81
82 f32 sign = vg_signf(quat[l]);
83
84 u32 smallest[3];
85 for( u32 i=0, j=0; i<4; i ++ )
86 if( i != l )
87 smallest[j ++] = vg_quantf( quat[i]*sign, 10, -k_domain, k_domain );
88
89 u32 comp = (smallest[0]<<2) | (smallest[1]<<12) | (smallest[2]<<22) | l;
90 bitpack_bytes( ctx, 4, &comp );
91 }
92 else {
93 u32 comp;
94 bitpack_bytes( ctx, 4, &comp );
95
96 u32 smallest[3] = {(comp>>2 )&0x3ff,
97 (comp>>12)&0x3ff,
98 (comp>>22)&0x3ff},
99 l = comp & 0x3;
100
101 f32 m = 1.0f;
102
103 for( u32 i=0, j=0; i<4; i ++ ){
104 if( i != l ){
105 quat[i] = vg_dequantf( smallest[j ++], 10, -k_domain, k_domain );
106 m -= quat[i]*quat[i];
107 }
108 }
109
110 quat[l] = sqrtf(m);
111 q_normalize( quat );
112 }
113 }
114
115 #endif /* NETWORK_COMPRESSION_H */