15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2011 Google Inc. All Rights Reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// that can be found in the COPYING file in the root of the source
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// tree. An additional intellectual property rights grant can be found
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in the file PATENTS. All contributing project authors may
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// be found in the AUTHORS file in the root of the source tree.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bit writing and boolean coder
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Skal (pascal.massimino@gmail.com)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         Vikas Arora (vikaas.arora@gmail.com)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>   // for memcpy()
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "./bit_writer.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "./endian_inl.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "./utils.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VP8BitWriter
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8_t* new_buf;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t new_size;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t needed_size = (size_t)needed_size_64b;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needed_size_64b != needed_size) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->error_ = 1;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needed_size <= bw->max_pos_) return 1;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the following line wraps over 32bit, the test just after will catch it.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_size = 2 * bw->max_pos_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_size < needed_size) new_size = needed_size;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_size < 1024) new_size = 1024;
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  new_buf = (uint8_t*)WebPSafeMalloc(1ULL, new_size);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_buf == NULL) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->error_ = 1;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bw->pos_ > 0) {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    assert(bw->buf_ != NULL);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    memcpy(new_buf, bw->buf_, bw->pos_);
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebPSafeFree(bw->buf_);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->buf_ = new_buf;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->max_pos_ = new_size;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void kFlush(VP8BitWriter* const bw) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int s = 8 + bw->nb_bits_;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int32_t bits = bw->value_ >> s;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(bw->nb_bits_ >= 0);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->value_ -= bits << s;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->nb_bits_ -= 8;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((bits & 0xff) != 0xff) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t pos = bw->pos_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!BitWriterResize(bw, bw->run_ + 1)) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bits & 0x100) {  // overflow -> propagate carry over pending 0xff's
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pos > 0) bw->buf_[pos - 1]++;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bw->run_ > 0) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const int value = (bits & 0x100) ? 0x00 : 0xff;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->buf_[pos++] = bits;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->pos_ = pos;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->run_++;   // delay writing of bytes 0xff, pending eventual carry.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// renormalization
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const uint8_t kNorm[128] = {  // renorm_sizes[i] = 8 - log2(i)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// range = ((range + 1) << kVP8Log2Range[range]) - 1
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const uint8_t kNewRange[128] = {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  127, 127, 191, 127, 159, 191, 223, 127, 143, 159, 175, 191, 207, 223, 239,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  247, 127, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  183, 187, 191, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  243, 247, 251, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  241, 243, 245, 247, 249, 251, 253, 127
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VP8PutBit(VP8BitWriter* const bw, int bit, int prob) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int split = (bw->range_ * prob) >> 8;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bit) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->value_ += split + 1;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->range_ -= split + 1;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->range_ = split;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bw->range_ < 127) {   // emit 'shift' bits out and renormalize
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int shift = kNorm[bw->range_];
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->range_ = kNewRange[bw->range_];
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->value_ <<= shift;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->nb_bits_ += shift;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bw->nb_bits_ > 0) kFlush(bw);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bit;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VP8PutBitUniform(VP8BitWriter* const bw, int bit) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int split = bw->range_ >> 1;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bit) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->value_ += split + 1;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->range_ -= split + 1;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->range_ = split;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bw->range_ < 127) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->range_ = kNewRange[bw->range_];
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->value_ <<= 1;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->nb_bits_ += 1;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bw->nb_bits_ > 0) kFlush(bw);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bit;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mask;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (mask = 1 << (nb_bits - 1); mask; mask >>= 1)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VP8PutBitUniform(bw, value & mask);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!VP8PutBitUniform(bw, value != 0))
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value < 0) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VP8PutValue(bw, value << 1, nb_bits + 1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->range_   = 255 - 1;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->value_   = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->run_     = 0;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->nb_bits_ = -8;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->pos_     = 0;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->max_pos_ = 0;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->error_   = 0;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->buf_     = NULL;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VP8PutValue(bw, 0, 9 - bw->nb_bits_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->nb_bits_ = 0;   // pad with zeroes
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  kFlush(bw);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bw->buf_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VP8BitWriterAppend(VP8BitWriter* const bw,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const uint8_t* data, size_t size) {
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  assert(data != NULL);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bw->nb_bits_ != -8) return 0;   // kFlush() must have been called
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!BitWriterResize(bw, size)) return 0;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(bw->buf_ + bw->pos_, data, size);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->pos_ += size;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (bw != NULL) {
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebPSafeFree(bw->buf_);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(bw, 0, sizeof(*bw));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VP8LBitWriter
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This is the minimum amount of size the memory buffer is guaranteed to grow
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// when extra space is needed.
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define MIN_EXTRA_SIZE  (32768ULL)
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define VP8L_WRITER_BYTES ((int)sizeof(vp8l_wtype_t))
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define VP8L_WRITER_BITS (VP8L_WRITER_BYTES * 8)
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define VP8L_WRITER_MAX_BITS (8 * (int)sizeof(vp8l_atype_t))
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns 1 on success.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8_t* allocated_buf;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t allocated_size;
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const size_t max_bytes = bw->end_ - bw->buf_;
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const size_t current_size = bw->cur_ - bw->buf_;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint64_t size_required_64b = (uint64_t)current_size + extra_size;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t size_required = (size_t)size_required_64b;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size_required != size_required_64b) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->error_ = 1;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (max_bytes > 0 && size_required <= max_bytes) return 1;
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  allocated_size = (3 * max_bytes) >> 1;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allocated_size < size_required) allocated_size = size_required;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // make allocated size multiple of 1k
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allocated_size = (((allocated_size >> 10) + 1) << 10);
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  allocated_buf = (uint8_t*)WebPSafeMalloc(1ULL, allocated_size);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (allocated_buf == NULL) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bw->error_ = 1;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (current_size > 0) {
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    memcpy(allocated_buf, bw->buf_, current_size);
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebPSafeFree(bw->buf_);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bw->buf_ = allocated_buf;
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bw->cur_ = bw->buf_ + current_size;
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bw->end_ = bw->buf_ + allocated_size;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(bw, 0, sizeof(*bw));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return VP8LBitWriterResize(bw, expected_size);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bw != NULL) {
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WebPSafeFree(bw->buf_);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(bw, 0, sizeof(*bw));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) {
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  assert(n_bits <= 32);
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // That's the max we can handle:
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS);
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (n_bits > 0) {
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Local field copy.
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    vp8l_atype_t lbits = bw->bits_;
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int used = bw->used_;
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Special case of overflow handling for 32bit accumulator (2-steps flush).
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (VP8L_WRITER_BITS == 16) {
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (used + n_bits >= VP8L_WRITER_MAX_BITS) {
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        // Fill up all the VP8L_WRITER_MAX_BITS so it can be flushed out below.
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        const int shift = VP8L_WRITER_MAX_BITS - used;
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        lbits |= (vp8l_atype_t)bits << used;
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        used = VP8L_WRITER_MAX_BITS;
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        n_bits -= shift;
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        bits >>= shift;
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        assert(n_bits <= VP8L_WRITER_MAX_BITS);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If needed, make some room by flushing some bits out.
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    while (used >= VP8L_WRITER_BITS) {
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) {
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE;
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if (extra_size != (size_t)extra_size ||
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            !VP8LBitWriterResize(bw, (size_t)extra_size)) {
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          bw->cur_ = bw->buf_;
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          bw->error_ = 1;
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          return;
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        }
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits);
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bw->cur_ += VP8L_WRITER_BYTES;
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      lbits >>= VP8L_WRITER_BITS;
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      used -= VP8L_WRITER_BITS;
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Eventually, insert new bits.
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bw->bits_ = lbits | ((vp8l_atype_t)bits << used);
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bw->used_ = used + n_bits;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) {
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // flush leftover bits
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (VP8LBitWriterResize(bw, (bw->used_ + 7) >> 3)) {
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    while (bw->used_ > 0) {
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *bw->cur_++ = (uint8_t)bw->bits_;
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bw->bits_ >>= 8;
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bw->used_ -= 8;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bw->used_ = 0;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return bw->buf_;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
308