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 :
12 : #if CONFIG_DEBUG
13 : #include <assert.h>
14 : #endif
15 : #include <stdio.h>
16 :
17 : #include "treecoder.h"
18 :
19 0 : static void tree2tok(
20 : struct vp8_token_struct *const p,
21 : vp8_tree t,
22 : int i,
23 : int v,
24 : int L
25 : )
26 : {
27 0 : v += v;
28 0 : ++L;
29 :
30 : do
31 : {
32 0 : const vp8_tree_index j = t[i++];
33 :
34 0 : if (j <= 0)
35 : {
36 0 : p[-j].value = v;
37 0 : p[-j].Len = L;
38 : }
39 : else
40 0 : tree2tok(p, t, j, v, L);
41 : }
42 0 : while (++v & 1);
43 0 : }
44 :
45 0 : void vp8_tokens_from_tree(struct vp8_token_struct *p, vp8_tree t)
46 : {
47 0 : tree2tok(p, t, 0, 0, 0);
48 0 : }
49 :
50 0 : void vp8_tokens_from_tree_offset(struct vp8_token_struct *p, vp8_tree t,
51 : int offset)
52 : {
53 0 : tree2tok(p - offset, t, 0, 0, 0);
54 0 : }
55 :
56 0 : static void branch_counts(
57 : int n, /* n = size of alphabet */
58 : vp8_token tok [ /* n */ ],
59 : vp8_tree tree,
60 : unsigned int branch_ct [ /* n-1 */ ] [2],
61 : const unsigned int num_events[ /* n */ ]
62 : )
63 : {
64 0 : const int tree_len = n - 1;
65 0 : int t = 0;
66 :
67 : #if CONFIG_DEBUG
68 : assert(tree_len);
69 : #endif
70 :
71 : do
72 : {
73 0 : branch_ct[t][0] = branch_ct[t][1] = 0;
74 : }
75 0 : while (++t < tree_len);
76 :
77 0 : t = 0;
78 :
79 : do
80 : {
81 0 : int L = tok[t].Len;
82 0 : const int enc = tok[t].value;
83 0 : const unsigned int ct = num_events[t];
84 :
85 0 : vp8_tree_index i = 0;
86 :
87 : do
88 : {
89 0 : const int b = (enc >> --L) & 1;
90 0 : const int j = i >> 1;
91 : #if CONFIG_DEBUG
92 : assert(j < tree_len && 0 <= L);
93 : #endif
94 :
95 0 : branch_ct [j] [b] += ct;
96 0 : i = tree[ i + b];
97 : }
98 0 : while (i > 0);
99 :
100 : #if CONFIG_DEBUG
101 : assert(!L);
102 : #endif
103 : }
104 0 : while (++t < n);
105 :
106 0 : }
107 :
108 :
109 0 : void vp8_tree_probs_from_distribution(
110 : int n, /* n = size of alphabet */
111 : vp8_token tok [ /* n */ ],
112 : vp8_tree tree,
113 : vp8_prob probs [ /* n-1 */ ],
114 : unsigned int branch_ct [ /* n-1 */ ] [2],
115 : const unsigned int num_events[ /* n */ ],
116 : unsigned int Pfac,
117 : int rd
118 : )
119 : {
120 0 : const int tree_len = n - 1;
121 0 : int t = 0;
122 :
123 0 : branch_counts(n, tok, tree, branch_ct, num_events);
124 :
125 : do
126 : {
127 0 : const unsigned int *const c = branch_ct[t];
128 0 : const unsigned int tot = c[0] + c[1];
129 :
130 : #if CONFIG_DEBUG
131 : assert(tot < (1 << 24)); /* no overflow below */
132 : #endif
133 :
134 0 : if (tot)
135 : {
136 0 : const unsigned int p = ((c[0] * Pfac) + (rd ? tot >> 1 : 0)) / tot;
137 0 : probs[t] = p < 256 ? (p ? p : 1) : 255; /* agree w/old version for now */
138 : }
139 : else
140 0 : probs[t] = vp8_prob_half;
141 : }
142 0 : while (++t < tree_len);
143 0 : }
|