#ifndef __GOLOMB_H #define __GOLOMB_H #include "bitcoder.h" static inline unsigned int required_bits (unsigned int x) { int bits = 31; while ((x & (1 << bits)) == 0 && bits) bits--; return bits; } static inline void write_number_binary (BitCoderState *b, unsigned int x, int bits, int u) { /*printf ("wrote %i with %i bits (%i+%i)\n", x, u+bits, u, bits); */ while (bits) { bits--; bitcoder_write_bit (b, (x >> bits) & 1); } } static inline unsigned int read_number_binary (BitCoderState *b, int bits) { unsigned int x = 0; while (bits) { bits--; x |= bitcoder_read_bit (b) << bits; } return x; } static inline void golomb_write_number (BitCoderState *b, unsigned int x, int bits) { unsigned int q, r; int i = 0; assert (x > 0); while ((q = (x - 1) >> bits) > 0) { bitcoder_write_bit (b, 1); /* fast temporary adaption, write */ bits++; /* unary representation of q */ i++; }; bitcoder_write_bit (b, 0); r = x - 1 - (q << bits); write_number_binary (b, r, bits, i+1); } static inline unsigned int golomb_read_number (BitCoderState *b, int bits) { unsigned int q = 0, r, x; while (bitcoder_read_bit (b) != 0) { bits++; } r = read_number_binary (b, bits); x = (q << bits) + r + 1; return x; } typedef struct { uint8_t count; uint8_t bits; /* a 5.3 fixed point integer */ } GolombAdaptiveCoderState; #define GOLOMB_ADAPTIVE_CODER_STATE_INITIALIZER { 8<<3, 0 } static const int golomb_w_tab [] = { 256, 128, 64 }; static inline void golombcoder_encode_number (GolombAdaptiveCoderState *g, BitCoderState *b, unsigned int x) { golomb_write_number (b, x, g->bits >> 3); g->bits = ((256 - golomb_w_tab[g->count]) * (int) g->bits + golomb_w_tab[g->count] * (required_bits(x)<<3)) / 256; g->count++; if (g->count > 2) g->count = 2; } static inline unsigned int golombcoder_decode_number (GolombAdaptiveCoderState *g, BitCoderState *b) { unsigned int x; x = golomb_read_number (b, g->bits >> 3); g->bits = ((256 - golomb_w_tab[g->count]) * g->bits + golomb_w_tab[g->count] * (required_bits(x)<<3)) / 256; g->count++; if (g->count > 2) g->count = 2; return x; } #endif