gstreamer/ext/tarkin/rle.h
Thomas Vander Stichele 7a778ee4b7 gst-indent
Original commit message from CVS:
gst-indent
2004-03-14 22:34:33 +00:00

143 lines
3.5 KiB
C

#ifndef __RLE_H
#define __RLE_H
#include <string.h>
#include <assert.h>
#include "mem.h"
#include "bitcoder.h"
#include "golomb.h"
#if defined(RLECODER)
#define OUTPUT_BIT(rlecoder,bit) rlecoder_write_bit(rlecoder,bit)
#define INPUT_BIT(rlecoder) rlecoder_read_bit(rlecoder)
#define OUTPUT_BIT_DIRECT(coder,bit) bitcoder_write_bit(&(coder)->bitcoder,bit)
#define INPUT_BIT_DIRECT(rlecoder) bitcoder_read_bit(&(rlecoder)->bitcoder)
#define ENTROPY_CODER RLECoderState
#define ENTROPY_ENCODER_INIT(coder,limit) rlecoder_encoder_init(coder,limit)
#define ENTROPY_ENCODER_DONE(coder) rlecoder_encoder_done(coder)
#define ENTROPY_ENCODER_FLUSH(coder) rlecoder_encoder_flush(coder)
#define ENTROPY_DECODER_INIT(coder,bitstream,limit) \
rlecoder_decoder_init(coder,bitstream,limit)
#define ENTROPY_DECODER_DONE(coder) /* nothing to do ... */
#define ENTROPY_CODER_BITSTREAM(coder) ((coder)->bitcoder.bitstream)
#define ENTROPY_CODER_EOS(coder) ((coder)->bitcoder.eos)
#define ENTROPY_CODER_SYMBOL(coder) ((coder)->symbol)
#define ENTROPY_CODER_RUNLENGTH(coder) ((coder)->count)
#define ENTROPY_CODER_SKIP(coder,skip) do { (coder)->count -= skip; } while (0)
#endif
typedef struct
{
int symbol;
uint32_t count; /* have seen count symbol's */
BitCoderState bitcoder;
GolombAdaptiveCoderState golomb_state[2]; /* 2 states for 2 symbols... */
int have_seen_1;
} RLECoderState;
/*
* bit should be 0 or 1 !!!
*/
static inline void
rlecoder_write_bit (RLECoderState * s, int bit)
{
assert (bit == 0 || bit == 1);
if (s->symbol == -1) {
s->symbol = bit & 1;
s->count = 1;
s->have_seen_1 = bit;
bitcoder_write_bit (&s->bitcoder, bit);
}
if (s->symbol != bit) {
golombcoder_encode_number (&s->golomb_state[s->symbol],
&s->bitcoder, s->count);
s->symbol = ~s->symbol & 1;
s->have_seen_1 = 1;
s->count = 1;
} else
s->count++;
}
static inline int
rlecoder_read_bit (RLECoderState * s)
{
if (s->count == 0) {
s->symbol = ~s->symbol & 1;
s->count = golombcoder_decode_number (&s->golomb_state[s->symbol],
&s->bitcoder);
if (s->bitcoder.eos) {
s->symbol = 0;
s->count = ~0;
}
}
s->count--;
return (s->symbol);
}
int coder_id = 0;
FILE *file = NULL;
static inline void
rlecoder_encoder_init (RLECoderState * s, uint32_t limit)
{
bitcoder_encoder_init (&s->bitcoder, limit);
s->symbol = -1;
s->have_seen_1 = 0;
s->golomb_state[0].count = 0;
s->golomb_state[1].count = 0;
s->golomb_state[0].bits = 5 << 3;
s->golomb_state[1].bits = 5 << 3;
}
/**
* once you called this, you better should not encode any more symbols ...
*/
static inline uint32_t
rlecoder_encoder_flush (RLECoderState * s)
{
if (s->symbol == -1 || !s->have_seen_1)
return 0;
golombcoder_encode_number (&s->golomb_state[s->symbol],
&s->bitcoder, s->count);
return bitcoder_flush (&s->bitcoder);
}
static inline void
rlecoder_decoder_init (RLECoderState * s, uint8_t * bitstream, uint32_t limit)
{
bitcoder_decoder_init (&s->bitcoder, bitstream, limit);
s->golomb_state[0].count = 0;
s->golomb_state[1].count = 0;
s->golomb_state[0].bits = 5 << 3;
s->golomb_state[1].bits = 5 << 3;
s->symbol = bitcoder_read_bit (&s->bitcoder);
s->count = golombcoder_decode_number (&s->golomb_state[s->symbol],
&s->bitcoder) - 1;
if (s->bitcoder.eos) {
s->symbol = 0;
s->count = ~0;
}
}
static inline void
rlecoder_encoder_done (RLECoderState * s)
{
bitcoder_encoder_done (&s->bitcoder);
}
#endif