Path: blob/master/thirdparty/libwebp/src/utils/bit_reader_utils.h
9912 views
// Copyright 2010 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Boolean decoder10//11// Author: Skal ([email protected])12// Vikas Arora ([email protected])1314#ifndef WEBP_UTILS_BIT_READER_UTILS_H_15#define WEBP_UTILS_BIT_READER_UTILS_H_1617#include <assert.h>18#ifdef _MSC_VER19#include <stdlib.h> // _byteswap_ulong20#endif21#include "src/dsp/cpu.h"22#include "src/webp/types.h"2324// Warning! This macro triggers quite some MACRO wizardry around func signature!25#if !defined(BITTRACE)26#define BITTRACE 0 // 0 = off, 1 = print bits, 2 = print bytes27#endif2829#if (BITTRACE > 0)30struct VP8BitReader;31extern void BitTrace(const struct VP8BitReader* const br, const char label[]);32#define BT_TRACK(br) BitTrace(br, label)33#define VP8Get(BR, L) VP8GetValue(BR, 1, L)34#else35#define BT_TRACK(br)36// We'll REMOVE the 'const char label[]' from all signatures and calls (!!):37#define VP8GetValue(BR, N, L) VP8GetValue(BR, N)38#define VP8Get(BR, L) VP8GetValue(BR, 1, L)39#define VP8GetSignedValue(BR, N, L) VP8GetSignedValue(BR, N)40#define VP8GetBit(BR, P, L) VP8GetBit(BR, P)41#define VP8GetBitAlt(BR, P, L) VP8GetBitAlt(BR, P)42#define VP8GetSigned(BR, V, L) VP8GetSigned(BR, V)43#endif4445#ifdef __cplusplus46extern "C" {47#endif4849// The Boolean decoder needs to maintain infinite precision on the value_ field.50// However, since range_ is only 8bit, we only need an active window of 8 bits51// for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls52// below 128, range_ is updated, and fresh bits read from the bitstream are53// brought in as LSB. To avoid reading the fresh bits one by one (slow), we54// cache BITS of them ahead. The total of (BITS + 8) bits must fit into a55// natural register (with type bit_t). To fetch BITS bits from bitstream we56// use a type lbit_t.57//58// BITS can be any multiple of 8 from 8 to 56 (inclusive).59// Pick values that fit natural register size.6061#if defined(__i386__) || defined(_M_IX86) // x86 32bit62#define BITS 2463#elif defined(__x86_64__) || defined(_M_X64) // x86 64bit64#define BITS 5665#elif defined(__arm__) || defined(_M_ARM) // ARM66#define BITS 2467#elif WEBP_AARCH64 // ARM 64bit68#define BITS 5669#elif defined(__mips__) // MIPS70#define BITS 2471#elif defined(__wasm__) // WASM72#define BITS 5673#else // reasonable default74#define BITS 2475#endif7677//------------------------------------------------------------------------------78// Derived types and constants:79// bit_t = natural register type for storing 'value_' (which is BITS+8 bits)80// range_t = register for 'range_' (which is 8bits only)8182#if (BITS > 24)83typedef uint64_t bit_t;84#else85typedef uint32_t bit_t;86#endif8788typedef uint32_t range_t;8990//------------------------------------------------------------------------------91// Bitreader9293typedef struct VP8BitReader VP8BitReader;94struct VP8BitReader {95// boolean decoder (keep the field ordering as is!)96bit_t value_; // current value97range_t range_; // current range minus 1. In [127, 254] interval.98int bits_; // number of valid bits left99// read buffer100const uint8_t* buf_; // next byte to be read101const uint8_t* buf_end_; // end of read buffer102const uint8_t* buf_max_; // max packed-read position on buffer103int eof_; // true if input is exhausted104};105106// Initialize the bit reader and the boolean decoder.107void VP8InitBitReader(VP8BitReader* const br,108const uint8_t* const start, size_t size);109// Sets the working read buffer.110void VP8BitReaderSetBuffer(VP8BitReader* const br,111const uint8_t* const start, size_t size);112113// Update internal pointers to displace the byte buffer by the114// relative offset 'offset'.115void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);116117// return the next value made of 'num_bits' bits118uint32_t VP8GetValue(VP8BitReader* const br, int num_bits, const char label[]);119120// return the next value with sign-extension.121int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits,122const char label[]);123124// bit_reader_inl.h will implement the following methods:125// static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob, ...)126// static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v, ...)127// and should be included by the .c files that actually need them.128// This is to avoid recompiling the whole library whenever this file is touched,129// and also allowing platform-specific ad-hoc hacks.130131// -----------------------------------------------------------------------------132// Bitreader for lossless format133134// maximum number of bits (inclusive) the bit-reader can handle:135#define VP8L_MAX_NUM_BIT_READ 24136137#define VP8L_LBITS 64 // Number of bits prefetched (= bit-size of vp8l_val_t).138#define VP8L_WBITS 32 // Minimum number of bytes ready after VP8LFillBitWindow.139140typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit.141142typedef struct {143vp8l_val_t val_; // pre-fetched bits144const uint8_t* buf_; // input byte buffer145size_t len_; // buffer length146size_t pos_; // byte position in buf_147int bit_pos_; // current bit-reading position in val_148int eos_; // true if a bit was read past the end of buffer149} VP8LBitReader;150151void VP8LInitBitReader(VP8LBitReader* const br,152const uint8_t* const start,153size_t length);154155// Sets a new data buffer.156void VP8LBitReaderSetBuffer(VP8LBitReader* const br,157const uint8_t* const buffer, size_t length);158159// Reads the specified number of bits from read buffer.160// Flags an error in case end_of_stream or n_bits is more than the allowed limit161// of VP8L_MAX_NUM_BIT_READ (inclusive).162// Flags eos_ if this read attempt is going to cross the read buffer.163uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);164165// Return the prefetched bits, so they can be looked up.166static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {167return (uint32_t)(br->val_ >> (br->bit_pos_ & (VP8L_LBITS - 1)));168}169170// Returns true if there was an attempt at reading bit past the end of171// the buffer. Doesn't set br->eos_ flag.172static WEBP_INLINE int VP8LIsEndOfStream(const VP8LBitReader* const br) {173assert(br->pos_ <= br->len_);174return br->eos_ || ((br->pos_ == br->len_) && (br->bit_pos_ > VP8L_LBITS));175}176177// For jumping over a number of bits in the bit stream when accessed with178// VP8LPrefetchBits and VP8LFillBitWindow.179// This function does *not* set br->eos_, since it's speed-critical.180// Use with extreme care!181static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {182br->bit_pos_ = val;183}184185// Advances the read buffer by 4 bytes to make room for reading next 32 bits.186// Speed critical, but infrequent part of the code can be non-inlined.187extern void VP8LDoFillBitWindow(VP8LBitReader* const br);188static WEBP_INLINE void VP8LFillBitWindow(VP8LBitReader* const br) {189if (br->bit_pos_ >= VP8L_WBITS) VP8LDoFillBitWindow(br);190}191192#ifdef __cplusplus193} // extern "C"194#endif195196#endif // WEBP_UTILS_BIT_READER_UTILS_H_197198199