1a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Copyright 2011 Google Inc. All Rights Reserved.
2a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
30406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Use of this source code is governed by a BSD-style license
40406ce1417f76f2034833414dcecc9f56253640cVikas Arora// that can be found in the COPYING file in the root of the source
50406ce1417f76f2034833414dcecc9f56253640cVikas Arora// tree. An additional intellectual property rights grant can be found
60406ce1417f76f2034833414dcecc9f56253640cVikas Arora// in the file PATENTS. All contributing project authors may
70406ce1417f76f2034833414dcecc9f56253640cVikas Arora// be found in the AUTHORS file in the root of the source tree.
8a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// -----------------------------------------------------------------------------
9a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
10a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Bit writing and boolean coder
11a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//
12a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Author: Skal (pascal.massimino@gmail.com)
13a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//         Vikas Arora (vikaas.arora@gmail.com)
14a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
15a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include <assert.h>
16a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include <string.h>   // for memcpy()
17a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include <stdlib.h>
18a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "./bit_writer.h"
19a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
20a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#if defined(__cplusplus) || defined(c_plusplus)
21a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraextern "C" {
22a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
23a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
24a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
25a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// VP8BitWriter
26a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
27a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
28a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  uint8_t* new_buf;
29a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  size_t new_size;
30a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size;
31a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const size_t needed_size = (size_t)needed_size_64b;
32a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (needed_size_64b != needed_size) {
33a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
34a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
35a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
36a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (needed_size <= bw->max_pos_) return 1;
37a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  // If the following line wraps over 32bit, the test just after will catch it.
38a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  new_size = 2 * bw->max_pos_;
39a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (new_size < needed_size) new_size = needed_size;
40a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (new_size < 1024) new_size = 1024;
41a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  new_buf = (uint8_t*)malloc(new_size);
42a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (new_buf == NULL) {
43a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
44a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
45a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
46a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memcpy(new_buf, bw->buf_, bw->pos_);
47a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  free(bw->buf_);
48a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->buf_ = new_buf;
49a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->max_pos_ = new_size;
50a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return 1;
51a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
52a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
53a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic void kFlush(VP8BitWriter* const bw) {
54a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int s = 8 + bw->nb_bits_;
55a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int32_t bits = bw->value_ >> s;
56a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  assert(bw->nb_bits_ >= 0);
57a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->value_ -= bits << s;
58a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->nb_bits_ -= 8;
59a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if ((bits & 0xff) != 0xff) {
60a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    size_t pos = bw->pos_;
61a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (!BitWriterResize(bw, bw->run_ + 1)) {
62a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      return;
63a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
64a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bits & 0x100) {  // overflow -> propagate carry over pending 0xff's
65a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      if (pos > 0) bw->buf_[pos - 1]++;
66a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
67a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bw->run_ > 0) {
68a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      const int value = (bits & 0x100) ? 0x00 : 0xff;
69a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
70a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
71a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->buf_[pos++] = bits;
72a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->pos_ = pos;
73a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
74a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->run_++;   // delay writing of bytes 0xff, pending eventual carry.
75a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
76a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
77a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
78a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
79a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// renormalization
80a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
81a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic const uint8_t kNorm[128] = {  // renorm_sizes[i] = 8 - log2(i)
82a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
83a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
84a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
85a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
86a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
87a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
88a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
89a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
90a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  0
91a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora};
92a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
93a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// range = ((range + 1) << kVP8Log2Range[range]) - 1
94a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic const uint8_t kNewRange[128] = {
95a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239,
96a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239,
97a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179,
98a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239,
99a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149,
100a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,
101a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209,
102a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,
103a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  241, 243, 245, 247, 249, 251, 253, 127
104a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora};
105a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
106a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8PutBit(VP8BitWriter* const bw, int bit, int prob) {
107a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int split = (bw->range_ * prob) >> 8;
108a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bit) {
109a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ += split + 1;
110a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ -= split + 1;
111a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
112a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = split;
113a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
114a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->range_ < 127) {   // emit 'shift' bits out and renormalize
115a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    const int shift = kNorm[bw->range_];
116a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = kNewRange[bw->range_];
117a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ <<= shift;
118a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->nb_bits_ += shift;
119a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bw->nb_bits_ > 0) kFlush(bw);
120a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
121a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return bit;
122a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
123a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
124a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
125a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int split = bw->range_ >> 1;
126a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bit) {
127a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ += split + 1;
128a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ -= split + 1;
129a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
130a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = split;
131a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
132a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->range_ < 127) {
133a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = kNewRange[bw->range_];
134a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ <<= 1;
135a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->nb_bits_ += 1;
136a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bw->nb_bits_ > 0) kFlush(bw);
137a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
138a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return bit;
139a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
140a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
141a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) {
142a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  int mask;
143a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  for (mask = 1 << (nb_bits - 1); mask; mask >>= 1)
144a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    VP8PutBitUniform(bw, value & mask);
145a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
146a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
147a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) {
148a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (!VP8PutBitUniform(bw, value != 0))
149a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return;
150a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (value < 0) {
151a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1);
152a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
153a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    VP8PutValue(bw, value << 1, nb_bits + 1);
154a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
155a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
156a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
157a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
158a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
159a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
160a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->range_   = 255 - 1;
161a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->value_   = 0;
162a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->run_     = 0;
163a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->nb_bits_ = -8;
164a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->pos_     = 0;
165a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->max_pos_ = 0;
166a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->error_   = 0;
167a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->buf_     = NULL;
168a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1;
169a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
170a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
171a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorauint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
172a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  VP8PutValue(bw, 0, 9 - bw->nb_bits_);
173a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->nb_bits_ = 0;   // pad with zeroes
174a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  kFlush(bw);
175a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return bw->buf_;
176a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
177a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
178a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8BitWriterAppend(VP8BitWriter* const bw,
179a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                       const uint8_t* data, size_t size) {
180a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  assert(data);
181a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->nb_bits_ != -8) return 0;   // kFlush() must have been called
182a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (!BitWriterResize(bw, size)) return 0;
183a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memcpy(bw->buf_ + bw->pos_, data, size);
184a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->pos_ += size;
185a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return 1;
186a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
187a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
188a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8BitWriterWipeOut(VP8BitWriter* const bw) {
189a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw) {
190a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    free(bw->buf_);
191a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    memset(bw, 0, sizeof(*bw));
192a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
193a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
194a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
195a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
196a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// VP8LBitWriter
197a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
198a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Returns 1 on success.
199a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
200a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  uint8_t* allocated_buf;
201a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  size_t allocated_size;
202a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const size_t current_size = VP8LBitWriterNumBytes(bw);
203a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const uint64_t size_required_64b = (uint64_t)current_size + extra_size;
204a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const size_t size_required = (size_t)size_required_64b;
205a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (size_required != size_required_64b) {
206a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
207a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
208a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
209a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->max_bytes_ > 0 && size_required <= bw->max_bytes_) return 1;
210a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  allocated_size = (3 * bw->max_bytes_) >> 1;
211a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (allocated_size < size_required) allocated_size = size_required;
212a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  // make allocated size multiple of 1k
213a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  allocated_size = (((allocated_size >> 10) + 1) << 10);
214a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  allocated_buf = (uint8_t*)malloc(allocated_size);
215a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (allocated_buf == NULL) {
216a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
217a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
218a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
219a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memcpy(allocated_buf, bw->buf_, current_size);
220a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  free(bw->buf_);
221a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->buf_ = allocated_buf;
222a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->max_bytes_ = allocated_size;
223a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memset(allocated_buf + current_size, 0, allocated_size - current_size);
224a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return 1;
225a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
226a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
227a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
228a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memset(bw, 0, sizeof(*bw));
229a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return VP8LBitWriterResize(bw, expected_size);
230a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
231a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
232a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
233a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw != NULL) {
234a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    free(bw->buf_);
235a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    memset(bw, 0, sizeof(*bw));
236a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
237a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
238a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
239a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) {
240a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (n_bits < 1) return;
241a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#if !defined(__BIG_ENDIAN__)
242a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  // Technically, this branch of the code can write up to 25 bits at a time,
243a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  // but in prefix encoding, the maximum number of bits written is 18 at a time.
244a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  {
245a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    uint8_t* const p = &bw->buf_[bw->bit_pos_ >> 3];
246a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    uint32_t v = *(const uint32_t*)p;
247a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    v |= bits << (bw->bit_pos_ & 7);
248a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    *(uint32_t*)p = v;
249a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->bit_pos_ += n_bits;
250a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
251a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#else  // BIG_ENDIAN
252a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  {
253a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    uint8_t* p = &bw->buf_[bw->bit_pos_ >> 3];
254a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    const int bits_reserved_in_first_byte = bw->bit_pos_ & 7;
255a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    const int bits_left_to_write = n_bits - 8 + bits_reserved_in_first_byte;
256a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    // implicit & 0xff is assumed for uint8_t arithmetics
257a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    *p++ |= bits << bits_reserved_in_first_byte;
258a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bits >>= 8 - bits_reserved_in_first_byte;
259a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bits_left_to_write >= 1) {
260a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      *p++ = bits;
261a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      bits >>= 8;
262a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      if (bits_left_to_write >= 9) {
263a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora        *p++ = bits;
264a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora        bits >>= 8;
265a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      }
266a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
267a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    assert(n_bits <= 25);
268a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    *p = bits;
269a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->bit_pos_ += n_bits;
270a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
271a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
272a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if ((bw->bit_pos_ >> 3) > (bw->max_bytes_ - 8)) {
273a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    const uint64_t extra_size = 32768ULL + bw->max_bytes_;
274a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (extra_size != (size_t)extra_size ||
275a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora        !VP8LBitWriterResize(bw, (size_t)extra_size)) {
276a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      bw->bit_pos_ = 0;
277a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      bw->error_ = 1;
278a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
279a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
280a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
281a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
282a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
283a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
284a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#if defined(__cplusplus) || defined(c_plusplus)
285a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}    // extern "C"
286a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif
287