tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bitwriter_buffer.c (4416B)


      1 /*
      2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
      3 *
      4 * This source code is subject to the terms of the BSD 2 Clause License and
      5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6 * was not distributed with this source code in the LICENSE file, you can
      7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8 * Media Patent License 1.0 was not distributed with this source code in the
      9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10 */
     11 
     12 #include <assert.h>
     13 #include <limits.h>
     14 #include <stdlib.h>
     15 
     16 #include "config/aom_config.h"
     17 
     18 #include "aom_dsp/bitwriter_buffer.h"
     19 #include "aom_dsp/recenter.h"
     20 #include "aom_ports/bitops.h"
     21 
     22 int aom_wb_is_byte_aligned(const struct aom_write_bit_buffer *wb) {
     23  return (wb->bit_offset % CHAR_BIT == 0);
     24 }
     25 
     26 uint32_t aom_wb_bytes_written(const struct aom_write_bit_buffer *wb) {
     27  return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0);
     28 }
     29 
     30 void aom_wb_write_bit(struct aom_write_bit_buffer *wb, int bit) {
     31  const int off = (int)wb->bit_offset;
     32  const int p = off / CHAR_BIT;
     33  const int q = CHAR_BIT - 1 - off % CHAR_BIT;
     34  if (q == CHAR_BIT - 1) {
     35    // Zero next char and write bit
     36    wb->bit_buffer[p] = bit << q;
     37  } else {
     38    wb->bit_buffer[p] &= ~(1 << q);
     39    wb->bit_buffer[p] |= bit << q;
     40  }
     41  wb->bit_offset = off + 1;
     42 }
     43 
     44 static void overwrite_bit(struct aom_write_bit_buffer *wb, int bit) {
     45  // Do not zero bytes but overwrite exisiting values
     46  const int off = (int)wb->bit_offset;
     47  const int p = off / CHAR_BIT;
     48  const int q = CHAR_BIT - 1 - off % CHAR_BIT;
     49  wb->bit_buffer[p] &= ~(1 << q);
     50  wb->bit_buffer[p] |= bit << q;
     51  wb->bit_offset = off + 1;
     52 }
     53 
     54 void aom_wb_write_literal(struct aom_write_bit_buffer *wb, int data, int bits) {
     55  assert(bits <= 31);
     56  int bit;
     57  for (bit = bits - 1; bit >= 0; bit--) aom_wb_write_bit(wb, (data >> bit) & 1);
     58 }
     59 
     60 void aom_wb_write_unsigned_literal(struct aom_write_bit_buffer *wb,
     61                                   uint32_t data, int bits) {
     62  assert(bits <= 32);
     63  int bit;
     64  for (bit = bits - 1; bit >= 0; bit--) aom_wb_write_bit(wb, (data >> bit) & 1);
     65 }
     66 
     67 void aom_wb_overwrite_literal(struct aom_write_bit_buffer *wb, int data,
     68                              int bits) {
     69  int bit;
     70  for (bit = bits - 1; bit >= 0; bit--) overwrite_bit(wb, (data >> bit) & 1);
     71 }
     72 
     73 void aom_wb_write_inv_signed_literal(struct aom_write_bit_buffer *wb, int data,
     74                                     int bits) {
     75  aom_wb_write_literal(wb, data, bits + 1);
     76 }
     77 
     78 void aom_wb_write_uvlc(struct aom_write_bit_buffer *wb, uint32_t v) {
     79  assert(v != UINT32_MAX);
     80  ++v;
     81  const int leading_zeroes = get_msb(v);
     82  aom_wb_write_literal(wb, 0, leading_zeroes);
     83  aom_wb_write_unsigned_literal(wb, v, leading_zeroes + 1);
     84 }
     85 
     86 static void wb_write_primitive_quniform(struct aom_write_bit_buffer *wb,
     87                                        uint16_t n, uint16_t v) {
     88  if (n <= 1) return;
     89  const int l = get_msb(n) + 1;
     90  const int m = (1 << l) - n;
     91  if (v < m) {
     92    aom_wb_write_literal(wb, v, l - 1);
     93  } else {
     94    aom_wb_write_literal(wb, m + ((v - m) >> 1), l - 1);
     95    aom_wb_write_bit(wb, (v - m) & 1);
     96  }
     97 }
     98 
     99 static void wb_write_primitive_subexpfin(struct aom_write_bit_buffer *wb,
    100                                         uint16_t n, uint16_t k, uint16_t v) {
    101  int i = 0;
    102  int mk = 0;
    103  while (1) {
    104    int b = (i ? k + i - 1 : k);
    105    int a = (1 << b);
    106    if (n <= mk + 3 * a) {
    107      wb_write_primitive_quniform(wb, n - mk, v - mk);
    108      break;
    109    } else {
    110      int t = (v >= mk + a);
    111      aom_wb_write_bit(wb, t);
    112      if (t) {
    113        i = i + 1;
    114        mk += a;
    115      } else {
    116        aom_wb_write_literal(wb, v - mk, b);
    117        break;
    118      }
    119    }
    120  }
    121 }
    122 
    123 static void wb_write_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
    124                                            uint16_t n, uint16_t k,
    125                                            uint16_t ref, uint16_t v) {
    126  wb_write_primitive_subexpfin(wb, n, k, recenter_finite_nonneg(n, ref, v));
    127 }
    128 
    129 void aom_wb_write_signed_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
    130                                                uint16_t n, uint16_t k,
    131                                                int16_t ref, int16_t v) {
    132  ref += n - 1;
    133  v += n - 1;
    134  const uint16_t scaled_n = (n << 1) - 1;
    135  wb_write_primitive_refsubexpfin(wb, scaled_n, k, ref, v);
    136 }