blob: 8fe1ff7631d8581418c0a51e2d1059c16374a6e0 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Alex Converse7fe2ae82016-09-28 11:33:20 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Alex Converse7fe2ae82016-09-28 11:33:20 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <string.h>
13
Alex Converse1ac1ae72016-09-17 15:11:16 -070014#include "aom_dsp/buf_ans.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "aom_mem/aom_mem.h"
Alex Converse1ac1ae72016-09-17 15:11:16 -070016#include "aom/internal/aom_codec_internal.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Alex Converse1ac1ae72016-09-17 15:11:16 -070018void aom_buf_ans_alloc(struct BufAnsCoder *c,
Alex Converse2cdf0d82016-12-13 13:53:09 -080019 struct aom_internal_error_info *error, int size) {
Alex Converse1ac1ae72016-09-17 15:11:16 -070020 c->error = error;
Alex Converse2cdf0d82016-12-13 13:53:09 -080021 c->size = size;
Alex Converseeb780e72016-12-13 12:46:41 -080022 assert(c->size > 1);
Alex Converse1ac1ae72016-09-17 15:11:16 -070023 AOM_CHECK_MEM_ERROR(error, c->buf, aom_malloc(c->size * sizeof(*c->buf)));
Yaowu Xuc27fc142016-08-22 16:08:15 -070024 // Initialize to overfull to trigger the assert in write.
25 c->offset = c->size + 1;
26}
27
Alex Converse1ac1ae72016-09-17 15:11:16 -070028void aom_buf_ans_free(struct BufAnsCoder *c) {
Yaowu Xuf883b422016-08-30 14:01:10 -070029 aom_free(c->buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -070030 c->buf = NULL;
31 c->size = 0;
32}
33
Alex Converse2cdf0d82016-12-13 13:53:09 -080034#if !ANS_MAX_SYMBOLS
Alex Converse1ac1ae72016-09-17 15:11:16 -070035void aom_buf_ans_grow(struct BufAnsCoder *c) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070036 struct buffered_ans_symbol *new_buf = NULL;
37 int new_size = c->size * 2;
Alex Converse1ac1ae72016-09-17 15:11:16 -070038 AOM_CHECK_MEM_ERROR(c->error, new_buf,
39 aom_malloc(new_size * sizeof(*new_buf)));
Yaowu Xuc27fc142016-08-22 16:08:15 -070040 memcpy(new_buf, c->buf, c->size * sizeof(*c->buf));
Yaowu Xuf883b422016-08-30 14:01:10 -070041 aom_free(c->buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -070042 c->buf = new_buf;
43 c->size = new_size;
44}
Alex Converse2cdf0d82016-12-13 13:53:09 -080045#endif
Alex Converse1ecdf2b2016-11-30 15:51:12 -080046
47void aom_buf_ans_flush(struct BufAnsCoder *const c) {
48 int offset;
Alex Converseb0be6412016-11-30 15:51:50 -080049#if ANS_MAX_SYMBOLS
50 if (c->offset == 0) return;
51#endif
52 assert(c->offset > 0);
Alex Converse39204062017-02-02 15:59:29 -080053 offset = c->offset - 1;
54 // Code the first symbol such that it brings the state to the smallest normal
55 // state from an initial state that would have been a subnormal/refill state.
56 if (c->buf[offset].method == ANS_METHOD_RANS) {
57 c->ans.state += c->buf[offset].val_start;
58 } else {
59 c->ans.state += c->buf[offset].val_start ? c->buf[offset].prob : 0;
60 }
61 for (offset = offset - 1; offset >= 0; --offset) {
Alex Converse1ecdf2b2016-11-30 15:51:12 -080062 if (c->buf[offset].method == ANS_METHOD_RANS) {
Alex Converse8c687d22017-02-07 15:55:24 -080063 rans_write(&c->ans, c->buf[offset].val_start, c->buf[offset].prob);
Alex Converse1ecdf2b2016-11-30 15:51:12 -080064 } else {
Alex Conversec54692b2017-01-25 16:41:05 -080065 rabs_write(&c->ans, (uint8_t)c->buf[offset].val_start,
Alex Converse1ecdf2b2016-11-30 15:51:12 -080066 (AnsP8)c->buf[offset].prob);
67 }
68 }
69 c->offset = 0;
70 c->output_bytes += ans_write_end(&c->ans);
71}