11cb0ef41Sopenharmony_ci/* Copyright 2013 Google Inc. All Rights Reserved.
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci   Distributed under MIT license.
41cb0ef41Sopenharmony_ci   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
51cb0ef41Sopenharmony_ci*/
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci/* Bit reading helpers */
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "./bit_reader.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "../common/platform.h"
121cb0ef41Sopenharmony_ci#include <brotli/types.h>
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci#if defined(__cplusplus) || defined(c_plusplus)
151cb0ef41Sopenharmony_ciextern "C" {
161cb0ef41Sopenharmony_ci#endif
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciconst uint32_t kBrotliBitMask[33] = {   0x00000000,
191cb0ef41Sopenharmony_ci    0x00000001, 0x00000003, 0x00000007, 0x0000000F,
201cb0ef41Sopenharmony_ci    0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
211cb0ef41Sopenharmony_ci    0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
221cb0ef41Sopenharmony_ci    0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
231cb0ef41Sopenharmony_ci    0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
241cb0ef41Sopenharmony_ci    0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
251cb0ef41Sopenharmony_ci    0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
261cb0ef41Sopenharmony_ci    0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
271cb0ef41Sopenharmony_ci};
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_civoid BrotliInitBitReader(BrotliBitReader* const br) {
301cb0ef41Sopenharmony_ci  br->val_ = 0;
311cb0ef41Sopenharmony_ci  br->bit_pos_ = sizeof(br->val_) << 3;
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciBROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
351cb0ef41Sopenharmony_ci  size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1;
361cb0ef41Sopenharmony_ci  /* Fixing alignment after unaligned BrotliFillWindow would result accumulator
371cb0ef41Sopenharmony_ci     overflow. If unalignment is caused by BrotliSafeReadBits, then there is
381cb0ef41Sopenharmony_ci     enough space in accumulator to fix alignment. */
391cb0ef41Sopenharmony_ci  if (!BROTLI_ALIGNED_READ) {
401cb0ef41Sopenharmony_ci    aligned_read_mask = 0;
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci  if (BrotliGetAvailableBits(br) == 0) {
431cb0ef41Sopenharmony_ci    if (!BrotliPullByte(br)) {
441cb0ef41Sopenharmony_ci      return BROTLI_FALSE;
451cb0ef41Sopenharmony_ci    }
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  while ((((size_t)br->next_in) & aligned_read_mask) != 0) {
491cb0ef41Sopenharmony_ci    if (!BrotliPullByte(br)) {
501cb0ef41Sopenharmony_ci      /* If we consumed all the input, we don't care about the alignment. */
511cb0ef41Sopenharmony_ci      return BROTLI_TRUE;
521cb0ef41Sopenharmony_ci    }
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci  return BROTLI_TRUE;
551cb0ef41Sopenharmony_ci}
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ciBROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
581cb0ef41Sopenharmony_ci    uint32_t n_bits, uint32_t* val) {
591cb0ef41Sopenharmony_ci  uint32_t low_val;
601cb0ef41Sopenharmony_ci  uint32_t high_val;
611cb0ef41Sopenharmony_ci  BrotliBitReaderState memento;
621cb0ef41Sopenharmony_ci  BROTLI_DCHECK(n_bits <= 32);
631cb0ef41Sopenharmony_ci  BROTLI_DCHECK(n_bits > 24);
641cb0ef41Sopenharmony_ci  BrotliBitReaderSaveState(br, &memento);
651cb0ef41Sopenharmony_ci  if (!BrotliSafeReadBits(br, 16, &low_val) ||
661cb0ef41Sopenharmony_ci      !BrotliSafeReadBits(br, n_bits - 16, &high_val)) {
671cb0ef41Sopenharmony_ci    BrotliBitReaderRestoreState(br, &memento);
681cb0ef41Sopenharmony_ci    return BROTLI_FALSE;
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci  *val = low_val | (high_val << 16);
711cb0ef41Sopenharmony_ci  return BROTLI_TRUE;
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci#if defined(__cplusplus) || defined(c_plusplus)
751cb0ef41Sopenharmony_ci}  /* extern "C" */
761cb0ef41Sopenharmony_ci#endif
77