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/****************************************************************************
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan*
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan*   Module Title :     boolhuff.h
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan*
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan*   Description  :     Bool Coder header file.
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan*
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan****************************************************************************/
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef VP8_ENCODER_BOOLHUFF_H_
20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define VP8_ENCODER_BOOLHUFF_H_
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_ports/mem.h"
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/internal/vpx_codec_internal.h"
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef __cplusplus
26233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern "C" {
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan
29233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int lowvalue;
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int range;
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int count;
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int pos;
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned char *buffer;
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned char *buffer_end;
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct vpx_internal_error_info *error;
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* Variables used to track bit costs without outputing to the bitstream */
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int  measure_cost;
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned long bit_counter;
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan} BOOL_CODER;
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan
44233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern void vp8_start_encode(BOOL_CODER *bc, unsigned char *buffer, unsigned char *buffer_end);
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan
46233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern void vp8_encode_value(BOOL_CODER *br, int data, int bits);
47233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern void vp8_stop_encode(BOOL_CODER *bc);
48233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern const unsigned int vp8_prob_cost[256];
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan
51233d2500723e5594f3e7c70896ffeeef32b9c950ywanDECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan
53233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int validate_buffer(const unsigned char *start,
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           size_t               len,
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           const unsigned char *end,
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           struct vpx_internal_error_info *error)
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (start + len > start && start + len < end)
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return 1;
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_internal_error(error, VPX_CODEC_CORRUPT_FRAME,
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan            "Truncated packet or corrupt partition ");
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
66233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void vp8_encode_bool(BOOL_CODER *br, int bit, int probability)
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int split;
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int count = br->count;
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int range = br->range;
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int lowvalue = br->lowvalue;
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan    register unsigned int shift;
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef VP8_ENTROPY_STATS
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if defined(SECTIONBITS_OUTPUT)
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bit)
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Sectionbits[active_section] += vp8_prob_cost[255-probability];
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan        Sectionbits[active_section] += vp8_prob_cost[probability];
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan    split = 1 + (((range - 1) * probability) >> 8);
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan    range = split;
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bit)
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan        lowvalue += split;
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan        range = br->range - split;
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan    shift = vp8_norm[range];
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan    range <<= shift;
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan    count += shift;
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (count >= 0)
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int offset = shift - count;
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((lowvalue << (offset - 1)) & 0x80000000)
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int x = br->pos - 1;
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan            while (x >= 0 && br->buffer[x] == 0xff)
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan                br->buffer[x] = (unsigned char)0;
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x--;
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
113233d2500723e5594f3e7c70896ffeeef32b9c950ywan
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan            br->buffer[x] += 1;
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan        validate_buffer(br->buffer + br->pos, 1, br->buffer_end, br->error);
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan        br->buffer[br->pos++] = (lowvalue >> (24 - offset));
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan
120233d2500723e5594f3e7c70896ffeeef32b9c950ywan        lowvalue <<= offset;
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan        shift = count;
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan        lowvalue &= 0xffffff;
123233d2500723e5594f3e7c70896ffeeef32b9c950ywan        count -= 8 ;
124233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
125233d2500723e5594f3e7c70896ffeeef32b9c950ywan
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan    lowvalue <<= shift;
127233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->count = count;
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->lowvalue = lowvalue;
129233d2500723e5594f3e7c70896ffeeef32b9c950ywan    br->range = range;
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan
132233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef __cplusplus
133233d2500723e5594f3e7c70896ffeeef32b9c950ywan}  // extern "C"
134233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
135233d2500723e5594f3e7c70896ffeeef32b9c950ywan
136233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif  // VP8_ENCODER_BOOLHUFF_H_
137