bitwriter_buffer.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. #include <assert.h>
  12. #include <limits.h>
  13. #include <stdlib.h>
  14. #include "config/aom_config.h"
  15. #include "aom_dsp/bitwriter_buffer.h"
  16. #include "aom_dsp/recenter.h"
  17. #include "aom_ports/bitops.h"
  18. int aom_wb_is_byte_aligned(const struct aom_write_bit_buffer *wb) {
  19. return (wb->bit_offset % CHAR_BIT == 0);
  20. }
  21. uint32_t aom_wb_bytes_written(const struct aom_write_bit_buffer *wb) {
  22. return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0);
  23. }
  24. void aom_wb_write_bit(struct aom_write_bit_buffer *wb, int bit) {
  25. const int off = (int)wb->bit_offset;
  26. const int p = off / CHAR_BIT;
  27. const int q = CHAR_BIT - 1 - off % CHAR_BIT;
  28. if (q == CHAR_BIT - 1) {
  29. // Zero next char and write bit
  30. wb->bit_buffer[p] = bit << q;
  31. } else {
  32. wb->bit_buffer[p] &= ~(1 << q);
  33. wb->bit_buffer[p] |= bit << q;
  34. }
  35. wb->bit_offset = off + 1;
  36. }
  37. void aom_wb_overwrite_bit(struct aom_write_bit_buffer *wb, int bit) {
  38. // Do not zero bytes but overwrite exisiting values
  39. const int off = (int)wb->bit_offset;
  40. const int p = off / CHAR_BIT;
  41. const int q = CHAR_BIT - 1 - off % CHAR_BIT;
  42. wb->bit_buffer[p] &= ~(1 << q);
  43. wb->bit_buffer[p] |= bit << q;
  44. wb->bit_offset = off + 1;
  45. }
  46. void aom_wb_write_literal(struct aom_write_bit_buffer *wb, int data, int bits) {
  47. assert(bits <= 31);
  48. int bit;
  49. for (bit = bits - 1; bit >= 0; bit--) aom_wb_write_bit(wb, (data >> bit) & 1);
  50. }
  51. void aom_wb_write_unsigned_literal(struct aom_write_bit_buffer *wb,
  52. uint32_t data, int bits) {
  53. assert(bits <= 32);
  54. int bit;
  55. for (bit = bits - 1; bit >= 0; bit--) aom_wb_write_bit(wb, (data >> bit) & 1);
  56. }
  57. void aom_wb_overwrite_literal(struct aom_write_bit_buffer *wb, int data,
  58. int bits) {
  59. int bit;
  60. for (bit = bits - 1; bit >= 0; bit--)
  61. aom_wb_overwrite_bit(wb, (data >> bit) & 1);
  62. }
  63. void aom_wb_write_inv_signed_literal(struct aom_write_bit_buffer *wb, int data,
  64. int bits) {
  65. aom_wb_write_literal(wb, data, bits + 1);
  66. }
  67. void aom_wb_write_uvlc(struct aom_write_bit_buffer *wb, uint32_t v) {
  68. int64_t shift_val = ++v;
  69. int leading_zeroes = 1;
  70. assert(shift_val > 0);
  71. while (shift_val >>= 1) leading_zeroes += 2;
  72. aom_wb_write_literal(wb, 0, leading_zeroes >> 1);
  73. aom_wb_write_unsigned_literal(wb, v, (leading_zeroes + 1) >> 1);
  74. }
  75. static void wb_write_primitive_quniform(struct aom_write_bit_buffer *wb,
  76. uint16_t n, uint16_t v) {
  77. if (n <= 1) return;
  78. const int l = get_msb(n) + 1;
  79. const int m = (1 << l) - n;
  80. if (v < m) {
  81. aom_wb_write_literal(wb, v, l - 1);
  82. } else {
  83. aom_wb_write_literal(wb, m + ((v - m) >> 1), l - 1);
  84. aom_wb_write_bit(wb, (v - m) & 1);
  85. }
  86. }
  87. static void wb_write_primitive_subexpfin(struct aom_write_bit_buffer *wb,
  88. uint16_t n, uint16_t k, uint16_t v) {
  89. int i = 0;
  90. int mk = 0;
  91. while (1) {
  92. int b = (i ? k + i - 1 : k);
  93. int a = (1 << b);
  94. if (n <= mk + 3 * a) {
  95. wb_write_primitive_quniform(wb, n - mk, v - mk);
  96. break;
  97. } else {
  98. int t = (v >= mk + a);
  99. aom_wb_write_bit(wb, t);
  100. if (t) {
  101. i = i + 1;
  102. mk += a;
  103. } else {
  104. aom_wb_write_literal(wb, v - mk, b);
  105. break;
  106. }
  107. }
  108. }
  109. }
  110. static void wb_write_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
  111. uint16_t n, uint16_t k,
  112. uint16_t ref, uint16_t v) {
  113. wb_write_primitive_subexpfin(wb, n, k, recenter_finite_nonneg(n, ref, v));
  114. }
  115. void aom_wb_write_signed_primitive_refsubexpfin(struct aom_write_bit_buffer *wb,
  116. uint16_t n, uint16_t k,
  117. int16_t ref, int16_t v) {
  118. ref += n - 1;
  119. v += n - 1;
  120. const uint16_t scaled_n = (n << 1) - 1;
  121. wb_write_primitive_refsubexpfin(wb, scaled_n, k, ref, v);
  122. }