1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Use of this source code is governed by a BSD-style license
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  that can be found in the LICENSE file in the root of the source
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  tree. An additional intellectual property rights grant can be found
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  in the file PATENTS.  All contributing project authors may
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */
10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
11474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
128b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org#ifndef VP8_DECODER_DBOOLHUFF_H_
138b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org#define VP8_DECODER_DBOOLHUFF_H_
144b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org
15474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <stddef.h>
16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <limits.h>
174b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org
18167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#include "vpx_config.h"
19474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx_ports/mem.h"
20693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#include "vpx/vp8dx.h"
21474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx/vpx_integer.h"
22474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
23dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef __cplusplus
24dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgextern "C" {
25dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
26dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
27474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgtypedef size_t VP8_BD_VALUE;
28474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
294b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org#define VP8_BD_VALUE_SIZE ((int)sizeof(VP8_BD_VALUE)*CHAR_BIT)
304b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org
31474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*This is meant to be a large, positive constant that can still be efficiently
32474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org   loaded as an immediate (on platforms like ARM, for example).
33474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org  Even relatively modest values like 100 would work fine.*/
344b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org#define VP8_LOTS_OF_BITS (0x40000000)
35474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
36474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgtypedef struct
37474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
38474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    const unsigned char *user_buffer_end;
39474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    const unsigned char *user_buffer;
40474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_BD_VALUE         value;
41474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int                  count;
42474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned int         range;
43693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    vpx_decrypt_cb       decrypt_cb;
446ffb5d8eaaa9cb68c354c46f375ccc5b9bc8b107jpet@google.com    void                *decrypt_state;
45474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} BOOL_DECODER;
46474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
47474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgDECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
48474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
49474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgint vp8dx_start_decode(BOOL_DECODER *br,
50474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                       const unsigned char *source,
51ba5ab470649de22c7c2c0b8cf4726a08b2058b44johannkoenig@chromium.org                       unsigned int source_sz,
52693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                       vpx_decrypt_cb decrypt_cb,
536ffb5d8eaaa9cb68c354c46f375ccc5b9bc8b107jpet@google.com                       void *decrypt_state);
54474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
55474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8dx_bool_decoder_fill(BOOL_DECODER *br);
56474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
57474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
58474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
59474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned int bit = 0;
60474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_BD_VALUE value;
61474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned int split;
62474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_BD_VALUE bigsplit;
63474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int count;
64474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned int range;
65474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
66474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    split = 1 + (((br->range - 1) * probability) >> 8);
67474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
68474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if(br->count < 0)
69474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vp8dx_bool_decoder_fill(br);
70474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
71474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    value = br->value;
72474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    count = br->count;
73474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
74474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8);
75474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
76474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    range = split;
77474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
78474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (value >= bigsplit)
79474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
80474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        range = br->range - split;
81474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        value = value - bigsplit;
82474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        bit = 1;
83474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
84474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
85474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
86474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        register unsigned int shift = vp8_norm[range];
87474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        range <<= shift;
88474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        value <<= shift;
89474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        count -= shift;
90474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
91474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    br->value = value;
92474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    br->count = count;
93474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    br->range = range;
94474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
95474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return bit;
96474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
97474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
98474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int vp8_decode_value(BOOL_DECODER *br, int bits)
99474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
100474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int z = 0;
101474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int bit;
102474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
103474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (bit = bits - 1; bit >= 0; bit--)
104474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
105474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        z |= (vp8dx_decode_bool(br, 0x80) << bit);
106474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
107474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
108474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return z;
109474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
110474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
111474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int vp8dx_bool_error(BOOL_DECODER *br)
112474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
113474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    /* Check if we have reached the end of the buffer.
114474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     *
115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * Variable 'count' stores the number of bits in the 'value' buffer, minus
116474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * 8. The top byte is part of the algorithm, and the remainder is buffered
117474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * to be shifted into it. So if count == 8, the top 16 bits of 'value' are
118474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * occupied, 8 for the algorithm and 8 in the buffer.
119474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     *
120474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * When reading a byte from the user's buffer, count is filled with 8 and
121474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * one byte is filled into the value buffer. When we reach the end of the
122474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * data, count is additionally filled with VP8_LOTS_OF_BITS. So when
123474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     * count == VP8_LOTS_OF_BITS - 1, the user's data has been exhausted.
124474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org     */
125474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((br->count > VP8_BD_VALUE_SIZE) && (br->count < VP8_LOTS_OF_BITS))
126474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
127474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org       /* We have tried to decode bits after the end of
128474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        * stream was encountered.
129474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        */
130474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return 1;
131474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
133474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    /* No error. */
134474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return 0;
135474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1364b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org
137dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef __cplusplus
138dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}  // extern "C"
139dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
140dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1418b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org#endif  // VP8_DECODER_DBOOLHUFF_H_
142