John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 1 | /* |
John Koleszar | c2140b8 | 2010-09-09 08:16:39 -0400 | [diff] [blame] | 2 | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 3 | * |
John Koleszar | 94c52e4 | 2010-06-18 12:39:21 -0400 | [diff] [blame] | 4 | * Use of this source code is governed by a BSD-style license |
John Koleszar | 09202d8 | 2010-06-04 16:19:40 -0400 | [diff] [blame] | 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 |
John Koleszar | 94c52e4 | 2010-06-18 12:39:21 -0400 | [diff] [blame] | 7 | * in the file PATENTS. All contributing project authors may |
John Koleszar | 09202d8 | 2010-06-04 16:19:40 -0400 | [diff] [blame] | 8 | * be found in the AUTHORS file in the root of the source tree. |
John Koleszar | 0ea50ce | 2010-05-18 11:58:33 -0400 | [diff] [blame] | 9 | */ |
| 10 | |
| 11 | |
| 12 | #include "boolhuff.h" |
| 13 | #include "blockd.h" |
| 14 | |
| 15 | |
| 16 | |
| 17 | #if defined(SECTIONBITS_OUTPUT) |
| 18 | unsigned __int64 Sectionbits[500]; |
| 19 | |
| 20 | #endif |
| 21 | |
| 22 | #ifdef ENTROPY_STATS |
| 23 | unsigned int active_section = 0; |
| 24 | #endif |
| 25 | |
| 26 | const unsigned int vp8_prob_cost[256] = |
| 27 | { |
| 28 | 2047, 2047, 1791, 1641, 1535, 1452, 1385, 1328, 1279, 1235, 1196, 1161, 1129, 1099, 1072, 1046, |
| 29 | 1023, 1000, 979, 959, 940, 922, 905, 889, 873, 858, 843, 829, 816, 803, 790, 778, |
| 30 | 767, 755, 744, 733, 723, 713, 703, 693, 684, 675, 666, 657, 649, 641, 633, 625, |
| 31 | 617, 609, 602, 594, 587, 580, 573, 567, 560, 553, 547, 541, 534, 528, 522, 516, |
| 32 | 511, 505, 499, 494, 488, 483, 477, 472, 467, 462, 457, 452, 447, 442, 437, 433, |
| 33 | 428, 424, 419, 415, 410, 406, 401, 397, 393, 389, 385, 381, 377, 373, 369, 365, |
| 34 | 361, 357, 353, 349, 346, 342, 338, 335, 331, 328, 324, 321, 317, 314, 311, 307, |
| 35 | 304, 301, 297, 294, 291, 288, 285, 281, 278, 275, 272, 269, 266, 263, 260, 257, |
| 36 | 255, 252, 249, 246, 243, 240, 238, 235, 232, 229, 227, 224, 221, 219, 216, 214, |
| 37 | 211, 208, 206, 203, 201, 198, 196, 194, 191, 189, 186, 184, 181, 179, 177, 174, |
| 38 | 172, 170, 168, 165, 163, 161, 159, 156, 154, 152, 150, 148, 145, 143, 141, 139, |
| 39 | 137, 135, 133, 131, 129, 127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, |
| 40 | 105, 103, 101, 99, 97, 95, 93, 92, 90, 88, 86, 84, 82, 81, 79, 77, |
| 41 | 75, 73, 72, 70, 68, 66, 65, 63, 61, 60, 58, 56, 55, 53, 51, 50, |
| 42 | 48, 46, 45, 43, 41, 40, 38, 37, 35, 33, 32, 30, 29, 27, 25, 24, |
| 43 | 22, 21, 19, 18, 16, 15, 13, 12, 10, 9, 7, 6, 4, 3, 1, 1 |
| 44 | }; |
| 45 | |
| 46 | void vp8_start_encode(BOOL_CODER *br, unsigned char *source) |
| 47 | { |
| 48 | |
| 49 | br->lowvalue = 0; |
| 50 | br->range = 255; |
| 51 | br->value = 0; |
| 52 | br->count = -24; |
| 53 | br->buffer = source; |
| 54 | br->pos = 0; |
| 55 | } |
| 56 | |
| 57 | void vp8_stop_encode(BOOL_CODER *br) |
| 58 | { |
| 59 | int i; |
| 60 | |
| 61 | for (i = 0; i < 32; i++) |
| 62 | vp8_encode_bool(br, 0, 128); |
| 63 | } |
| 64 | |
| 65 | DECLARE_ALIGNED(16, static const unsigned int, norm[256]) = |
| 66 | { |
| 67 | 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
| 68 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 69 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 70 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 71 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 72 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 73 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 74 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 75 | }; |
| 76 | |
| 77 | void vp8_encode_bool(BOOL_CODER *br, int bit, int probability) |
| 78 | { |
| 79 | unsigned int split; |
| 80 | int count = br->count; |
| 81 | unsigned int range = br->range; |
| 82 | unsigned int lowvalue = br->lowvalue; |
| 83 | register unsigned int shift; |
| 84 | |
| 85 | #ifdef ENTROPY_STATS |
| 86 | #if defined(SECTIONBITS_OUTPUT) |
| 87 | |
| 88 | if (bit) |
| 89 | Sectionbits[active_section] += vp8_prob_cost[255-probability]; |
| 90 | else |
| 91 | Sectionbits[active_section] += vp8_prob_cost[probability]; |
| 92 | |
| 93 | #endif |
| 94 | #endif |
| 95 | |
| 96 | split = 1 + (((range - 1) * probability) >> 8); |
| 97 | |
| 98 | range = split; |
| 99 | |
| 100 | if (bit) |
| 101 | { |
| 102 | lowvalue += split; |
| 103 | range = br->range - split; |
| 104 | } |
| 105 | |
| 106 | shift = norm[range]; |
| 107 | |
| 108 | range <<= shift; |
| 109 | count += shift; |
| 110 | |
| 111 | if (count >= 0) |
| 112 | { |
| 113 | int offset = shift - count; |
| 114 | |
| 115 | if ((lowvalue << (offset - 1)) & 0x80000000) |
| 116 | { |
| 117 | int x = br->pos - 1; |
| 118 | |
| 119 | while (x >= 0 && br->buffer[x] == 0xff) |
| 120 | { |
| 121 | br->buffer[x] = (unsigned char)0; |
| 122 | x--; |
| 123 | } |
| 124 | |
| 125 | br->buffer[x] += 1; |
| 126 | } |
| 127 | |
| 128 | br->buffer[br->pos++] = (lowvalue >> (24 - offset)); |
| 129 | lowvalue <<= offset; |
| 130 | shift = count; |
| 131 | lowvalue &= 0xffffff; |
| 132 | count -= 8 ; |
| 133 | } |
| 134 | |
| 135 | lowvalue <<= shift; |
| 136 | br->count = count; |
| 137 | br->lowvalue = lowvalue; |
| 138 | br->range = range; |
| 139 | } |
| 140 | |
| 141 | void vp8_encode_value(BOOL_CODER *br, int data, int bits) |
| 142 | { |
| 143 | int bit; |
| 144 | |
| 145 | for (bit = bits - 1; bit >= 0; bit--) |
| 146 | vp8_encode_bool(br, (1 & (data >> bit)), 0x80); |
| 147 | |
| 148 | } |