126fa459cSmrg/* Copyright 2013 Google Inc. All Rights Reserved.
226fa459cSmrg
326fa459cSmrg   Distributed under MIT license.
426fa459cSmrg   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
526fa459cSmrg*/
626fa459cSmrg
726fa459cSmrg/* Bit reading helpers */
826fa459cSmrg
926fa459cSmrg#include "./bit_reader.h"
1026fa459cSmrg
1126fa459cSmrg#include "../common/platform.h"
1226fa459cSmrg#include <brotli/types.h>
1326fa459cSmrg
1426fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
1526fa459cSmrgextern "C" {
1626fa459cSmrg#endif
1726fa459cSmrg
1826fa459cSmrgconst uint32_t kBrotliBitMask[33] = {   0x00000000,
1926fa459cSmrg    0x00000001, 0x00000003, 0x00000007, 0x0000000F,
2026fa459cSmrg    0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
2126fa459cSmrg    0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
2226fa459cSmrg    0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
2326fa459cSmrg    0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
2426fa459cSmrg    0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
2526fa459cSmrg    0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
2626fa459cSmrg    0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
2726fa459cSmrg};
2826fa459cSmrg
2926fa459cSmrgvoid BrotliInitBitReader(BrotliBitReader* const br) {
3026fa459cSmrg  br->val_ = 0;
3126fa459cSmrg  br->bit_pos_ = sizeof(br->val_) << 3;
3226fa459cSmrg}
3326fa459cSmrg
3426fa459cSmrgBROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
3526fa459cSmrg  size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1;
3626fa459cSmrg  /* Fixing alignment after unaligned BrotliFillWindow would result accumulator
3726fa459cSmrg     overflow. If unalignment is caused by BrotliSafeReadBits, then there is
3826fa459cSmrg     enough space in accumulator to fix alignment. */
3926fa459cSmrg  if (!BROTLI_ALIGNED_READ) {
4026fa459cSmrg    aligned_read_mask = 0;
4126fa459cSmrg  }
4226fa459cSmrg  if (BrotliGetAvailableBits(br) == 0) {
4326fa459cSmrg    if (!BrotliPullByte(br)) {
4426fa459cSmrg      return BROTLI_FALSE;
4526fa459cSmrg    }
4626fa459cSmrg  }
4726fa459cSmrg
4826fa459cSmrg  while ((((size_t)br->next_in) & aligned_read_mask) != 0) {
4926fa459cSmrg    if (!BrotliPullByte(br)) {
5026fa459cSmrg      /* If we consumed all the input, we don't care about the alignment. */
5126fa459cSmrg      return BROTLI_TRUE;
5226fa459cSmrg    }
5326fa459cSmrg  }
5426fa459cSmrg  return BROTLI_TRUE;
5526fa459cSmrg}
5626fa459cSmrg
5726fa459cSmrgBROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
5826fa459cSmrg    uint32_t n_bits, uint32_t* val) {
5926fa459cSmrg  uint32_t low_val;
6026fa459cSmrg  uint32_t high_val;
6126fa459cSmrg  BrotliBitReaderState memento;
6226fa459cSmrg  BROTLI_DCHECK(n_bits <= 32);
6326fa459cSmrg  BROTLI_DCHECK(n_bits > 24);
6426fa459cSmrg  BrotliBitReaderSaveState(br, &memento);
6526fa459cSmrg  if (!BrotliSafeReadBits(br, 16, &low_val) ||
6626fa459cSmrg      !BrotliSafeReadBits(br, n_bits - 16, &high_val)) {
6726fa459cSmrg    BrotliBitReaderRestoreState(br, &memento);
6826fa459cSmrg    return BROTLI_FALSE;
6926fa459cSmrg  }
7026fa459cSmrg  *val = low_val | (high_val << 16);
7126fa459cSmrg  return BROTLI_TRUE;
7226fa459cSmrg}
7326fa459cSmrg
7426fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
7526fa459cSmrg}  /* extern "C" */
7626fa459cSmrg#endif
77