/src/libvpx/vp8/common/treecoder.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license |
5 | | * that can be found in the LICENSE file in the root of the source |
6 | | * tree. An additional intellectual property rights grant can be found |
7 | | * in the file PATENTS. All contributing project authors may |
8 | | * be found in the AUTHORS file in the root of the source tree. |
9 | | */ |
10 | | |
11 | | #include <assert.h> |
12 | | #include <stdio.h> |
13 | | |
14 | | #include "vp8/common/treecoder.h" |
15 | | #include "vpx/vpx_integer.h" |
16 | | |
17 | | static void tree2tok(struct vp8_token_struct *const p, vp8_tree t, int i, int v, |
18 | 0 | int L) { |
19 | 0 | v += v; |
20 | 0 | ++L; |
21 | |
|
22 | 0 | do { |
23 | 0 | const vp8_tree_index j = t[i++]; |
24 | |
|
25 | 0 | if (j <= 0) { |
26 | 0 | p[-j].value = v; |
27 | 0 | p[-j].Len = L; |
28 | 0 | } else { |
29 | 0 | tree2tok(p, t, j, v, L); |
30 | 0 | } |
31 | 0 | } while (++v & 1); |
32 | 0 | } |
33 | | |
34 | 0 | void vp8_tokens_from_tree(struct vp8_token_struct *p, vp8_tree t) { |
35 | 0 | tree2tok(p, t, 0, 0, 0); |
36 | 0 | } |
37 | | |
38 | | void vp8_tokens_from_tree_offset(struct vp8_token_struct *p, vp8_tree t, |
39 | 0 | int offset) { |
40 | 0 | tree2tok(p - offset, t, 0, 0, 0); |
41 | 0 | } |
42 | | |
43 | | static void branch_counts(int n, /* n = size of alphabet */ |
44 | | vp8_token tok[/* n */], vp8_tree tree, |
45 | | unsigned int branch_ct[/* n-1 */][2], |
46 | 8.68M | const unsigned int num_events[/* n */]) { |
47 | 8.68M | const int tree_len = n - 1; |
48 | 8.68M | int t = 0; |
49 | | |
50 | 8.68M | assert(tree_len); |
51 | | |
52 | 94.2M | do { |
53 | 94.2M | branch_ct[t][0] = branch_ct[t][1] = 0; |
54 | 94.2M | } while (++t < tree_len); |
55 | | |
56 | 8.68M | t = 0; |
57 | | |
58 | 102M | do { |
59 | 102M | int L = tok[t].Len; |
60 | 102M | const int enc = tok[t].value; |
61 | 102M | const unsigned int ct = num_events[t]; |
62 | | |
63 | 102M | vp8_tree_index i = 0; |
64 | | |
65 | 536M | do { |
66 | 536M | const int b = (enc >> --L) & 1; |
67 | 536M | const int j = i >> 1; |
68 | 536M | assert(j < tree_len && 0 <= L); |
69 | | |
70 | 536M | branch_ct[j][b] += ct; |
71 | 536M | i = tree[i + b]; |
72 | 536M | } while (i > 0); |
73 | | |
74 | 102M | assert(!L); |
75 | 102M | } while (++t < n); |
76 | 8.68M | } |
77 | | |
78 | | void vp8_tree_probs_from_distribution(int n, /* n = size of alphabet */ |
79 | | vp8_token tok[/* n */], vp8_tree tree, |
80 | | vp8_prob probs[/* n-1 */], |
81 | | unsigned int branch_ct[/* n-1 */][2], |
82 | | const unsigned int num_events[/* n */], |
83 | 8.68M | unsigned int Pfactor, int Round) { |
84 | 8.68M | const int tree_len = n - 1; |
85 | 8.68M | int t = 0; |
86 | | |
87 | 8.68M | branch_counts(n, tok, tree, branch_ct, num_events); |
88 | | |
89 | 94.2M | do { |
90 | 94.2M | const unsigned int *const c = branch_ct[t]; |
91 | 94.2M | const unsigned int tot = c[0] + c[1]; |
92 | | |
93 | 94.2M | if (tot) { |
94 | 19.2M | const unsigned int p = |
95 | 19.2M | (unsigned int)(((uint64_t)c[0] * Pfactor) + (Round ? tot >> 1 : 0)) / |
96 | 19.2M | tot; |
97 | 19.2M | probs[t] = p < 256 ? (p ? p : 1) : 255; /* agree w/old version for now */ |
98 | 74.9M | } else { |
99 | 74.9M | probs[t] = vp8_prob_half; |
100 | 74.9M | } |
101 | 94.2M | } while (++t < tree_len); |
102 | 8.68M | } |