1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan *
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Use of this source code is governed by a BSD-style license
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  that can be found in the LICENSE file in the root of the source
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  tree. An additional intellectual property rights grant can be found
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  in the file PATENTS.  All contributing project authors may
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  be found in the AUTHORS file in the root of the source tree.
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "dboolhuff.h"
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan
14233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp8dx_start_decode(BOOL_DECODER *br,
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       const unsigned char *source,
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       unsigned int source_sz,
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       vp8_decrypt_cb *decrypt_cb,
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       void *decrypt_state)
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
20233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->user_buffer_end = source+source_sz;
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->user_buffer     = source;
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->value    = 0;
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->count    = -8;
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->range    = 255;
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->decrypt_cb = decrypt_cb;
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->decrypt_state = decrypt_state;
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (source_sz && !source)
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return 1;
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* Populate the buffer */
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8dx_bool_decoder_fill(br);
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan
37233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp8dx_bool_decoder_fill(BOOL_DECODER *br)
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const unsigned char *bufptr = br->user_buffer;
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VP8_BD_VALUE value = br->value;
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int count = br->count;
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int shift = VP8_BD_VALUE_SIZE - 8 - (count + 8);
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan    size_t bytes_left = br->user_buffer_end - bufptr;
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan    size_t bits_left = bytes_left * CHAR_BIT;
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int x = (int)(shift + CHAR_BIT - bits_left);
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int loop_end = 0;
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned char decrypted[sizeof(VP8_BD_VALUE) + 1];
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (br->decrypt_cb) {
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t n = bytes_left > sizeof(decrypted) ? sizeof(decrypted) : bytes_left;
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan        br->decrypt_cb(br->decrypt_state, bufptr, decrypted, (int)n);
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bufptr = decrypted;
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if(x >= 0)
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan        count += VP8_LOTS_OF_BITS;
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan        loop_end = x;
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (x < 0 || bits_left)
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while(shift >= loop_end)
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan            count += CHAR_BIT;
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan            value |= (VP8_BD_VALUE)*bufptr << shift;
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ++bufptr;
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ++br->user_buffer;
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan            shift -= CHAR_BIT;
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->value = value;
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->count = count;
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
76