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