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