mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 07:46:38 +00:00
133 lines
2.4 KiB
C
133 lines
2.4 KiB
C
|
#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
|
||
|
|