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>
18af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
19a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#include "./bit_writer.h"
20af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#include "./endian_inl.h"
21af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#include "./utils.h"
22a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
23a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
24a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// VP8BitWriter
25a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
26a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
27a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  uint8_t* new_buf;
28a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  size_t new_size;
29a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size;
30a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const size_t needed_size = (size_t)needed_size_64b;
31a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (needed_size_64b != needed_size) {
32a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
33a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
34a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
35a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (needed_size <= bw->max_pos_) return 1;
36a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  // If the following line wraps over 32bit, the test just after will catch it.
37a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  new_size = 2 * bw->max_pos_;
38a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (new_size < needed_size) new_size = needed_size;
39a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (new_size < 1024) new_size = 1024;
40af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  new_buf = (uint8_t*)WebPSafeMalloc(1ULL, new_size);
41a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (new_buf == NULL) {
42a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
43a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
44a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
458b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  if (bw->pos_ > 0) {
468b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    assert(bw->buf_ != NULL);
478b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora    memcpy(new_buf, bw->buf_, bw->pos_);
488b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  }
49af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  WebPSafeFree(bw->buf_);
50a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->buf_ = new_buf;
51a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->max_pos_ = new_size;
52a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return 1;
53a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
54a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
55a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic void kFlush(VP8BitWriter* const bw) {
56a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int s = 8 + bw->nb_bits_;
57a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int32_t bits = bw->value_ >> s;
58a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  assert(bw->nb_bits_ >= 0);
59a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->value_ -= bits << s;
60a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->nb_bits_ -= 8;
61a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if ((bits & 0xff) != 0xff) {
62a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    size_t pos = bw->pos_;
63a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (!BitWriterResize(bw, bw->run_ + 1)) {
64a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      return;
65a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
66a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bits & 0x100) {  // overflow -> propagate carry over pending 0xff's
67a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      if (pos > 0) bw->buf_[pos - 1]++;
68a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
69a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bw->run_ > 0) {
70a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      const int value = (bits & 0x100) ? 0x00 : 0xff;
71a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
72a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
73a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->buf_[pos++] = bits;
74a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->pos_ = pos;
75a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
76a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->run_++;   // delay writing of bytes 0xff, pending eventual carry.
77a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
78a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
79a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
80a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
81a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// renormalization
82a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
83a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic const uint8_t kNorm[128] = {  // renorm_sizes[i] = 8 - log2(i)
84a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
85a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
86a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
87a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
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  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
91a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
92a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  0
93a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora};
94a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
95a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// range = ((range + 1) << kVP8Log2Range[range]) - 1
96a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic const uint8_t kNewRange[128] = {
97a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239,
98a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239,
99a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179,
100a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239,
101a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149,
102a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,
103a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209,
104a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,
105a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  241, 243, 245, 247, 249, 251, 253, 127
106a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora};
107a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
108a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8PutBit(VP8BitWriter* const bw, int bit, int prob) {
109a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int split = (bw->range_ * prob) >> 8;
110a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bit) {
111a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ += split + 1;
112a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ -= split + 1;
113a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
114a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = split;
115a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
116a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->range_ < 127) {   // emit 'shift' bits out and renormalize
117a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    const int shift = kNorm[bw->range_];
118a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = kNewRange[bw->range_];
119a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ <<= shift;
120a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->nb_bits_ += shift;
121a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bw->nb_bits_ > 0) kFlush(bw);
122a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
123a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return bit;
124a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
125a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
126a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
127a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int split = bw->range_ >> 1;
128a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bit) {
129a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ += split + 1;
130a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ -= split + 1;
131a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
132a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = split;
133a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
134a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->range_ < 127) {
135a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->range_ = kNewRange[bw->range_];
136a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->value_ <<= 1;
137a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->nb_bits_ += 1;
138a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    if (bw->nb_bits_ > 0) kFlush(bw);
139a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
140a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return bit;
141a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
142a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
143a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) {
144a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  int mask;
145a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  for (mask = 1 << (nb_bits - 1); mask; mask >>= 1)
146a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    VP8PutBitUniform(bw, value & mask);
147a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
148a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
149a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) {
150a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (!VP8PutBitUniform(bw, value != 0))
151a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return;
152a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (value < 0) {
153a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1);
154a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  } else {
155a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    VP8PutValue(bw, value << 1, nb_bits + 1);
156a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
157a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
158a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
159a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
160a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
161a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
162a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->range_   = 255 - 1;
163a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->value_   = 0;
164a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->run_     = 0;
165a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->nb_bits_ = -8;
166a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->pos_     = 0;
167a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->max_pos_ = 0;
168a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->error_   = 0;
169a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->buf_     = NULL;
170a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1;
171a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
172a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
173a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorauint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
174a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  VP8PutValue(bw, 0, 9 - bw->nb_bits_);
175a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->nb_bits_ = 0;   // pad with zeroes
176a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  kFlush(bw);
177a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return bw->buf_;
178a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
179a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
180a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8BitWriterAppend(VP8BitWriter* const bw,
181a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                       const uint8_t* data, size_t size) {
182af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  assert(data != NULL);
183a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw->nb_bits_ != -8) return 0;   // kFlush() must have been called
184a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (!BitWriterResize(bw, size)) return 0;
185a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memcpy(bw->buf_ + bw->pos_, data, size);
186a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->pos_ += size;
187a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return 1;
188a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
189a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
190a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8BitWriterWipeOut(VP8BitWriter* const bw) {
191af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  if (bw != NULL) {
192af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    WebPSafeFree(bw->buf_);
193a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    memset(bw, 0, sizeof(*bw));
194a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
195a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
196a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
197a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
198a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// VP8LBitWriter
199a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
200af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora// This is the minimum amount of size the memory buffer is guaranteed to grow
201af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora// when extra space is needed.
202af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#define MIN_EXTRA_SIZE  (32768ULL)
203af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
204af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#define VP8L_WRITER_BYTES ((int)sizeof(vp8l_wtype_t))
205af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#define VP8L_WRITER_BITS (VP8L_WRITER_BYTES * 8)
206af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora#define VP8L_WRITER_MAX_BITS (8 * (int)sizeof(vp8l_atype_t))
207af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
208a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Returns 1 on success.
209a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
210a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  uint8_t* allocated_buf;
211a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  size_t allocated_size;
212af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  const size_t max_bytes = bw->end_ - bw->buf_;
213af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  const size_t current_size = bw->cur_ - bw->buf_;
214a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const uint64_t size_required_64b = (uint64_t)current_size + extra_size;
215a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const size_t size_required = (size_t)size_required_64b;
216a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (size_required != size_required_64b) {
217a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
218a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
219a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
220af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  if (max_bytes > 0 && size_required <= max_bytes) return 1;
221af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  allocated_size = (3 * max_bytes) >> 1;
222a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (allocated_size < size_required) allocated_size = size_required;
223a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  // make allocated size multiple of 1k
224a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  allocated_size = (((allocated_size >> 10) + 1) << 10);
225af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  allocated_buf = (uint8_t*)WebPSafeMalloc(1ULL, allocated_size);
226a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (allocated_buf == NULL) {
227a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    bw->error_ = 1;
228a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    return 0;
229a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
230af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  if (current_size > 0) {
231af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    memcpy(allocated_buf, bw->buf_, current_size);
232af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  }
233af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  WebPSafeFree(bw->buf_);
234a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  bw->buf_ = allocated_buf;
235af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  bw->cur_ = bw->buf_ + current_size;
236af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  bw->end_ = bw->buf_ + allocated_size;
237a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return 1;
238a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
239a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
240a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroraint VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
241a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  memset(bw, 0, sizeof(*bw));
242a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  return VP8LBitWriterResize(bw, expected_size);
243a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
244a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
245a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
246a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  if (bw != NULL) {
247af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    WebPSafeFree(bw->buf_);
248a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    memset(bw, 0, sizeof(*bw));
249a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
250a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
251a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
252a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Aroravoid VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) {
253af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  assert(n_bits <= 32);
254af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  // That's the max we can handle:
255af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS);
256af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  if (n_bits > 0) {
257af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    // Local field copy.
258af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    vp8l_atype_t lbits = bw->bits_;
259af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    int used = bw->used_;
260af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    // Special case of overflow handling for 32bit accumulator (2-steps flush).
261af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    if (VP8L_WRITER_BITS == 16) {
262af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      if (used + n_bits >= VP8L_WRITER_MAX_BITS) {
263af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        // Fill up all the VP8L_WRITER_MAX_BITS so it can be flushed out below.
264af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        const int shift = VP8L_WRITER_MAX_BITS - used;
265af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        lbits |= (vp8l_atype_t)bits << used;
266af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        used = VP8L_WRITER_MAX_BITS;
267af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        n_bits -= shift;
268af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        bits >>= shift;
269af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        assert(n_bits <= VP8L_WRITER_MAX_BITS);
270a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora      }
271a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
272af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    // If needed, make some room by flushing some bits out.
273af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    while (used >= VP8L_WRITER_BITS) {
274af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
275af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
276af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        if (extra_size != (size_t)extra_size ||
277af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora            !VP8LBitWriterResize(bw, (size_t)extra_size)) {
278af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora          bw->cur_ = bw->buf_;
279af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora          bw->error_ = 1;
280af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora          return;
281af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora        }
282af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      }
283af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits);
284af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      bw->cur_ += VP8L_WRITER_BYTES;
285af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      lbits >>= VP8L_WRITER_BITS;
286af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      used -= VP8L_WRITER_BITS;
287af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    }
288af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    // Eventually, insert new bits.
289af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    bw->bits_ = lbits | ((vp8l_atype_t)bits << used);
290af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    bw->used_ = used + n_bits;
291a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
292af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora}
293af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora
294af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arorauint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) {
295af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  // flush leftover bits
296af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  if (VP8LBitWriterResize(bw, (bw->used_ + 7) >> 3)) {
297af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    while (bw->used_ > 0) {
298af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      *bw->cur_++ = (uint8_t)bw->bits_;
299af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      bw->bits_ >>= 8;
300af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora      bw->used_ -= 8;
301a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora    }
302af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora    bw->used_ = 0;
303a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  }
304af51b94a435132e9014c324e25fb686b3d07a8c8Vikas Arora  return bw->buf_;
305a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
306a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
307a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
308