Subversion Repository Public Repository

Nextrek

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2010 Google Inc.
//
// This code is licensed under the same terms as WebM:
//  Software License Agreement:  http://www.webmproject.org/license/software/
//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
// -----------------------------------------------------------------------------
//
// Boolean decoder
//
// Author: Skal (pascal.massimino@gmail.com)

#ifndef WEBP_UTILS_BIT_READER_H_
#define WEBP_UTILS_BIT_READER_H_

#include <assert.h>
#include "../webp/decode_vp8.h"

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

//------------------------------------------------------------------------------
// Bitreader and code-tree reader

typedef struct VP8BitReader VP8BitReader;
struct VP8BitReader {
	const uint8_t* buf_; // next byte to be read
	const uint8_t* buf_end_; // end of read buffer
	int eof_; // true if input is exhausted

	// boolean decoder
	uint32_t range_; // current range minus 1. In [127, 254] interval.
	uint32_t value_; // current value
	int missing_; // number of missing bits in value_ (8bit)
};

// Initialize the bit reader and the boolean decoder.
void VP8InitBitReader(VP8BitReader* const br, const uint8_t* const start,
		const uint8_t* const end);

// Read a bit with proba 'prob'. Speed-critical function!
extern uint16_t kVP8RangeLUT[128];

static inline uint8_t VP8GetByte(VP8BitReader* const br) {
	if (br->buf_ != br->buf_end_) {
		return *br->buf_++;
	}
	br->eof_ = 1;
	return 0xff;
}

static inline uint8_t VP8BitUpdate(VP8BitReader* const br, const uint32_t split) {
	uint32_t value_split = (split + 1) << 8;
	// Make sure we have a least 8 bits in 'value_'
	while (br->missing_ > 0) {
		br->value_ |= VP8GetByte(br) << br->missing_;
		br->missing_ -= 8;
	}

	if (br->value_ < value_split) {
		br->range_ = split;
		return 0;
	} else {
		br->value_ -= value_split;
		br->range_ -= split + 1;
		return 1;
	}
}

static inline uint8_t NOT_VP8BitUpdate(VP8BitReader* const br, const uint32_t split) {
	uint32_t value_split = (split + 1) << 8;
	// Make sure we have a least 8 bits in 'value_'
	while (br->missing_ > 0) {
		br->value_ |= VP8GetByte(br) << br->missing_;
		br->missing_ -= 8;
	}

	if (br->value_ < value_split) {
		br->range_ = split;
		return 1;
	} else {
		br->value_ -= value_split;
		br->range_ -= split + 1;
		return 0;
	}
}

static inline void VP8Shift(VP8BitReader* const br) {
	// range_ is in [0..127] interval here.
	const uint16_t pack = kVP8RangeLUT[br->range_];
	const uint8_t shift = pack & 0x7;
	br->range_ = pack >> 3;
	br->value_ <<= shift;
	br->missing_ += shift;
}

static inline uint32_t VP8GetBit(VP8BitReader* const br, int prob) {
	const uint32_t split = ((uint16_t)br->range_ * (uint16_t)prob) >> 8;
	const uint32_t bit = VP8BitUpdate(br, split);
/*	if (br->range_ < 0x7f) {
		VP8Shift(br);
	}
	return bit;*/
	if (br->range_ >> 7) {
		return bit;
	} else {
		VP8Shift(br);
		return bit;
	}
}

static inline uint32_t NOT_VP8GetBit(VP8BitReader* const br, int prob) {
	const uint32_t split = ((uint16_t)br->range_ * (uint16_t)prob) >> 8;
	const uint32_t bit = NOT_VP8BitUpdate(br, split);
	if (br->range_ >> 7) {
		return bit;
	} else {
		VP8Shift(br);
		return bit;
	}
}

static inline int VP8GetSigned(VP8BitReader* const br, int v) {
	const uint32_t split = br->range_ >> 1;
	const uint32_t bit = VP8BitUpdate(br, split);
	VP8Shift(br);
	return bit ? -v : v;
}

//------------------------------------------------------------------------------
// Higher-level calls

static inline uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
  uint32_t v = 0;
  while (bits-- > 0) {
    v |= VP8GetBit(br, 0x80) << bits;
  }
  return v;
}

// return the next value made of 'num_bits' bits
static inline uint32_t VP8Get(VP8BitReader* const br) {
	return VP8GetValue(br, 1);
}

static inline int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
  const int value = VP8GetValue(br, bits);
  return VP8Get(br) ? -value : value;
}



//------------------------------------------------------------------------------

#if defined(__cplusplus) || defined(c_plusplus)
} // extern "C"
#endif

#endif  /* WEBP_UTILS_BIT_READER_H_ */

Commits for Nextrek/Android/LibrerieNextrek/jni/src/utils/bit_reader.h

Diff revisions: vs.
Revision Author Commited Message
4 FMMortaroli picture FMMortaroli Fri 19 Apr, 2013 16:54:38 +0000