Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2017, 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 | |
Debargha Mukherjee | e23d5c3 | 2017-04-13 15:33:58 -0700 | [diff] [blame] | 12 | #include "aom_dsp/binary_codes_reader.h" |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 13 | |
| 14 | #include "av1/common/common.h" |
| 15 | |
| 16 | // Inverse recenters a non-negative literal v around a reference r |
| 17 | static uint16_t inv_recenter_nonneg(uint16_t r, uint16_t v) { |
| 18 | if (v > (r << 1)) |
| 19 | return v; |
| 20 | else if ((v & 1) == 0) |
| 21 | return (v >> 1) + r; |
| 22 | else |
| 23 | return r - ((v + 1) >> 1); |
| 24 | } |
| 25 | |
| 26 | // Inverse recenters a non-negative literal v in [0, n-1] around a |
| 27 | // reference r also in [0, n-1] |
| 28 | static uint16_t inv_recenter_finite_nonneg(uint16_t n, uint16_t r, uint16_t v) { |
| 29 | if ((r << 1) <= n) { |
| 30 | return inv_recenter_nonneg(r, v); |
| 31 | } else { |
| 32 | return n - 1 - inv_recenter_nonneg(n - 1 - r, v); |
| 33 | } |
| 34 | } |
| 35 | |
Debargha Mukherjee | e23d5c3 | 2017-04-13 15:33:58 -0700 | [diff] [blame] | 36 | uint16_t aom_read_primitive_quniform_(aom_reader *r, |
| 37 | uint16_t n ACCT_STR_PARAM) { |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 38 | if (n <= 1) return 0; |
| 39 | const int l = get_msb(n - 1) + 1; |
| 40 | const int m = (1 << l) - n; |
Debargha Mukherjee | e23d5c3 | 2017-04-13 15:33:58 -0700 | [diff] [blame] | 41 | const int v = aom_read_literal(r, l - 1, ACCT_STR_NAME); |
| 42 | return v < m ? v : (v << 1) - m + aom_read_bit(r, ACCT_STR_NAME); |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 43 | } |
| 44 | |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 45 | static uint16_t aom_rb_read_primitive_quniform(struct aom_read_bit_buffer *rb, |
| 46 | uint16_t n) { |
| 47 | if (n <= 1) return 0; |
| 48 | const int l = get_msb(n - 1) + 1; |
| 49 | const int m = (1 << l) - n; |
| 50 | const int v = aom_rb_read_literal(rb, l - 1); |
| 51 | return v < m ? v : (v << 1) - m + aom_rb_read_bit(rb); |
| 52 | } |
| 53 | |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 54 | // Decode finite subexponential code that for a symbol v in [0, n-1] with |
| 55 | // parameter k |
Debargha Mukherjee | e23d5c3 | 2017-04-13 15:33:58 -0700 | [diff] [blame] | 56 | uint16_t aom_read_primitive_subexpfin_(aom_reader *r, uint16_t n, |
| 57 | uint16_t k ACCT_STR_PARAM) { |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 58 | int i = 0; |
| 59 | int mk = 0; |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 60 | |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 61 | while (1) { |
| 62 | int b = (i ? k + i - 1 : k); |
| 63 | int a = (1 << b); |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 64 | |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 65 | if (n <= mk + 3 * a) { |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 66 | return aom_read_primitive_quniform(r, n - mk, ACCT_STR_NAME) + mk; |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 67 | } |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 68 | |
| 69 | if (!aom_read_bit(r, ACCT_STR_NAME)) { |
| 70 | return aom_read_literal(r, b, ACCT_STR_NAME) + mk; |
| 71 | } |
| 72 | |
| 73 | i = i + 1; |
| 74 | mk += a; |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 75 | } |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 76 | |
| 77 | assert(0); |
| 78 | return 0; |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 79 | } |
| 80 | |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 81 | static uint16_t aom_rb_read_primitive_subexpfin(struct aom_read_bit_buffer *rb, |
| 82 | uint16_t n, uint16_t k) { |
| 83 | int i = 0; |
| 84 | int mk = 0; |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 85 | |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 86 | while (1) { |
| 87 | int b = (i ? k + i - 1 : k); |
| 88 | int a = (1 << b); |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 89 | |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 90 | if (n <= mk + 3 * a) { |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 91 | return aom_rb_read_primitive_quniform(rb, n - mk) + mk; |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 92 | } |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 93 | |
| 94 | if (!aom_rb_read_bit(rb)) { |
| 95 | return aom_rb_read_literal(rb, b) + mk; |
| 96 | } |
| 97 | |
| 98 | i = i + 1; |
| 99 | mk += a; |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 100 | } |
Sebastien Alaiwan | 209649c | 2017-12-07 16:06:24 +0100 | [diff] [blame] | 101 | |
| 102 | assert(0); |
| 103 | return 0; |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 104 | } |
| 105 | |
Debargha Mukherjee | e23d5c3 | 2017-04-13 15:33:58 -0700 | [diff] [blame] | 106 | uint16_t aom_read_primitive_refsubexpfin_(aom_reader *r, uint16_t n, uint16_t k, |
| 107 | uint16_t ref ACCT_STR_PARAM) { |
| 108 | return inv_recenter_finite_nonneg( |
| 109 | n, ref, aom_read_primitive_subexpfin(r, n, k, ACCT_STR_NAME)); |
Debargha Mukherjee | 47748b5 | 2017-03-24 12:20:49 -0700 | [diff] [blame] | 110 | } |
Sarah Parker | f178329 | 2017-04-05 11:55:27 -0700 | [diff] [blame] | 111 | |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 112 | static uint16_t aom_rb_read_primitive_refsubexpfin( |
| 113 | struct aom_read_bit_buffer *rb, uint16_t n, uint16_t k, uint16_t ref) { |
| 114 | return inv_recenter_finite_nonneg(n, ref, |
| 115 | aom_rb_read_primitive_subexpfin(rb, n, k)); |
| 116 | } |
| 117 | |
Sarah Parker | 3e579a6 | 2017-08-23 16:53:20 -0700 | [diff] [blame] | 118 | int16_t aom_rb_read_signed_primitive_refsubexpfin( |
| 119 | struct aom_read_bit_buffer *rb, uint16_t n, uint16_t k, int16_t ref) { |
| 120 | ref += n - 1; |
| 121 | const uint16_t scaled_n = (n << 1) - 1; |
| 122 | return aom_rb_read_primitive_refsubexpfin(rb, scaled_n, k, ref) - n + 1; |
| 123 | } |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 124 | |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 125 | uint32_t aom_rb_read_uvlc(struct aom_read_bit_buffer *rb) { |
| 126 | int leading_zeros = 0; |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 127 | while (!aom_rb_read_bit(rb)) ++leading_zeros; |
Hui Su | 828bffe | 2018-03-11 20:58:20 -0700 | [diff] [blame] | 128 | // Maximum 32 bits. |
| 129 | if (leading_zeros >= 32) return UINT32_MAX; |
| 130 | const uint32_t base = (1u << leading_zeros) - 1; |
| 131 | const uint32_t value = aom_rb_read_literal(rb, leading_zeros); |
| 132 | return base + value; |
Andrey Norkin | 28e9ce2 | 2018-01-08 10:11:21 -0800 | [diff] [blame] | 133 | } |