~ubuntu-branches/ubuntu/wily/mkvtoolnix/wily

« back to all changes in this revision

Viewing changes to src/common/bit_cursor.h

  • Committer: Package Import Robot
  • Author(s): Christian Marillat
  • Date: 2015-04-26 10:36:27 UTC
  • mfrom: (1.1.29) (4.2.45 sid)
  • Revision ID: package-import@ubuntu.com-20150426103627-k53p8hrai2ynikaa
Tags: 7.8.0-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
   mkvmerge -- utility for splicing together matroska files
3
3
   from component media subtypes
4
4
 
5
 
   Distributed under the GPL
 
5
   Distributed under the GPL v2
6
6
   see the file COPYING for details
7
7
   or visit http://www.gnu.org/copyleft/gpl.html
8
8
 
24
24
  const unsigned char *m_end_of_data;
25
25
  const unsigned char *m_byte_position;
26
26
  const unsigned char *m_start_of_data;
27
 
  unsigned int m_bits_valid;
 
27
  std::size_t m_bits_valid;
28
28
  bool m_out_of_data;
29
29
 
30
30
public:
31
 
  bit_reader_c(const unsigned char *data, unsigned int len) {
 
31
  bit_reader_c(unsigned char const *data, std::size_t len) {
32
32
    init(data, len);
33
33
  }
34
34
 
35
 
  void init(const unsigned char *data, unsigned int len) {
 
35
  void init(const unsigned char *data, std::size_t len) {
36
36
    m_end_of_data   = data + len;
37
37
    m_byte_position = data;
38
38
    m_start_of_data = data;
44
44
    return m_out_of_data;
45
45
  }
46
46
 
47
 
  uint64_t get_bits(unsigned int n) {
 
47
  uint64_t get_bits(std::size_t n) {
48
48
    uint64_t r = 0;
49
49
 
50
50
    while (n > 0) {
53
53
        throw mtx::mm_io::end_of_file_x();
54
54
      }
55
55
 
56
 
      unsigned int b = 8; // number of bits to extract from the current byte
 
56
      std::size_t b = 8; // number of bits to extract from the current byte
57
57
      if (b > n)
58
58
        b = n;
59
59
      if (b > m_bits_valid)
60
60
        b = m_bits_valid;
61
61
 
62
 
      unsigned int rshift = m_bits_valid - b;
 
62
      std::size_t rshift = m_bits_valid - b;
63
63
 
64
64
      r <<= b;
65
65
      r  |= ((*m_byte_position) >> rshift) & (0xff >> (8 - b));
96
96
    return get_bits(1) + 1;
97
97
  }
98
98
 
99
 
  uint64_t peek_bits(unsigned int n) {
 
99
  inline int get_unsigned_golomb() {
 
100
    int n = 0, bit;
 
101
 
 
102
    while ((bit = get_bit()) == 0)
 
103
      ++n;
 
104
 
 
105
    bit = get_bits(n);
 
106
 
 
107
    return (1 << n) - 1 + bit;
 
108
  }
 
109
 
 
110
  inline int get_signed_golomb() {
 
111
    int v = get_unsigned_golomb();
 
112
    return v & 1 ? (v + 1) / 2 : -(v / 2);
 
113
  }
 
114
 
 
115
  uint64_t peek_bits(std::size_t n) {
100
116
    uint64_t r                             = 0;
101
117
    const unsigned char *tmp_byte_position = m_byte_position;
102
 
    unsigned int tmp_bits_valid            = m_bits_valid;
 
118
    std::size_t tmp_bits_valid                  = m_bits_valid;
103
119
 
104
120
    while (0 < n) {
105
121
      if (tmp_byte_position >= m_end_of_data)
106
122
        throw mtx::mm_io::end_of_file_x();
107
123
 
108
 
      unsigned int b = 8; // number of bits to extract from the current byte
 
124
      std::size_t b = 8; // number of bits to extract from the current byte
109
125
      if (b > n)
110
126
        b = n;
111
127
      if (b > tmp_bits_valid)
112
128
        b = tmp_bits_valid;
113
129
 
114
 
      unsigned int rshift = tmp_bits_valid - b;
 
130
      std::size_t rshift = tmp_bits_valid - b;
115
131
 
116
132
      r <<= b;
117
133
      r  |= ((*tmp_byte_position) >> rshift) & (0xff >> (8 - b));
128
144
    return r;
129
145
  }
130
146
 
131
 
  void get_bytes(unsigned char *buf, size_t n) {
132
 
    size_t idx;
133
 
    for (idx = 0; idx < n; ++idx)
 
147
  void get_bytes(unsigned char *buf, std::size_t n) {
 
148
    if (8 == m_bits_valid) {
 
149
      get_bytes_byte_aligned(buf, n);
 
150
      return;
 
151
    }
 
152
 
 
153
    for (auto idx = 0u; idx < n; ++idx)
134
154
      buf[idx] = get_bits(8);
135
155
  }
136
156
 
139
159
      skip_bits(m_bits_valid);
140
160
  }
141
161
 
142
 
  void set_bit_position(unsigned int pos) {
143
 
    if (pos >= (static_cast<unsigned int>(m_end_of_data - m_start_of_data) * 8)) {
 
162
  void set_bit_position(std::size_t pos) {
 
163
    if (pos >= (static_cast<std::size_t>(m_end_of_data - m_start_of_data) * 8)) {
144
164
      m_byte_position = m_end_of_data;
145
165
      m_out_of_data   = true;
146
166
 
159
179
    return (m_end_of_data - m_byte_position) * 8 - 8 + m_bits_valid;
160
180
  }
161
181
 
162
 
  void skip_bits(unsigned int num) {
 
182
  void skip_bits(std::size_t num) {
163
183
    set_bit_position(get_bit_position() + num);
164
184
  }
165
185
 
166
186
  void skip_bit() {
167
187
    set_bit_position(get_bit_position() + 1);
168
188
  }
 
189
protected:
 
190
  void get_bytes_byte_aligned(unsigned char *buf, std::size_t n) {
 
191
    auto bytes_to_copy = std::min<std::size_t>(n, m_end_of_data - m_byte_position);
 
192
    std::memcpy(buf, m_byte_position, bytes_to_copy);
 
193
 
 
194
    m_byte_position += bytes_to_copy;
 
195
 
 
196
    if (bytes_to_copy < n) {
 
197
      m_out_of_data = true;
 
198
      throw mtx::mm_io::end_of_file_x();
 
199
    }
 
200
  }
169
201
};
170
 
typedef std::shared_ptr<bit_reader_c> bit_reader_cptr;
 
202
using bit_reader_cptr = std::shared_ptr<bit_reader_c>;
171
203
 
172
204
class bit_writer_c {
173
205
private:
174
206
  unsigned char *m_end_of_data;
175
207
  unsigned char *m_byte_position;
176
208
  unsigned char *m_start_of_data;
177
 
  unsigned int m_mask;
 
209
  std::size_t m_mask;
178
210
 
179
211
  bool m_out_of_data;
180
212
 
181
213
public:
182
 
  bit_writer_c(unsigned char *data, unsigned int len)
 
214
  bit_writer_c(unsigned char *data, std::size_t len)
183
215
    : m_end_of_data(data + len)
184
216
    , m_byte_position(data)
185
217
    , m_start_of_data(data)
188
220
  {
189
221
  }
190
222
 
191
 
  uint64_t copy_bits(unsigned int n, bit_reader_c &src) {
 
223
  uint64_t copy_bits(std::size_t n, bit_reader_c &src) {
192
224
    uint64_t value = src.get_bits(n);
193
225
    put_bits(n, value);
194
226
 
195
227
    return value;
196
228
  }
197
229
 
198
 
  void put_bits(unsigned int n, uint64_t value) {
 
230
  inline int copy_unsigned_golomb(bit_reader_c &r) {
 
231
    int n = 0, bit;
 
232
 
 
233
    while ((bit = r.get_bit()) == 0) {
 
234
      put_bit(0);
 
235
      ++n;
 
236
    }
 
237
 
 
238
    put_bit(1);
 
239
 
 
240
    bit = copy_bits(n, r);
 
241
 
 
242
    return (1 << n) - 1 + bit;
 
243
  }
 
244
 
 
245
  inline int copy_signed_golomb(bit_reader_c &r) {
 
246
    int v = copy_unsigned_golomb(r);
 
247
    return v & 1 ? (v + 1) / 2 : -(v / 2);
 
248
  }
 
249
 
 
250
  void put_bits(std::size_t n, uint64_t value) {
199
251
    while (0 < n) {
200
252
      put_bit(value & (1 << (n - 1)));
201
253
      --n;
226
278
      put_bit(0);
227
279
  }
228
280
 
229
 
  void set_bit_position(unsigned int pos) {
230
 
    if (pos >= (static_cast<unsigned int>(m_end_of_data - m_start_of_data) * 8)) {
 
281
  void set_bit_position(std::size_t pos) {
 
282
    if (pos >= (static_cast<std::size_t>(m_end_of_data - m_start_of_data) * 8)) {
231
283
      m_byte_position = m_end_of_data;
232
284
      m_out_of_data   = true;
233
285
 
239
291
  }
240
292
 
241
293
  int get_bit_position() {
242
 
    unsigned int i;
243
 
    unsigned int pos = (m_byte_position - m_start_of_data) * 8;
244
 
    for (i = 0; 8 > i; ++i)
 
294
    std::size_t pos = (m_byte_position - m_start_of_data) * 8;
 
295
    for (auto i = 0u; 8 > i; ++i)
245
296
      if ((0x80u >> i) == m_mask) {
246
297
        pos += i;
247
298
        break;
249
300
    return pos;
250
301
  }
251
302
};
252
 
typedef std::shared_ptr<bit_writer_c> bit_writer_cptr;
 
303
using bit_writer_cptr = std::shared_ptr<bit_writer_c>;
253
304
 
254
305
#endif // MTX_COMMON_BIT_CURSOR_H