OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
video.cpp
Go to the documentation of this file.
1#include "video.h"
2
3#ifdef __GNUC__
4// TODO: fix clang warnings
5#pragma GCC diagnostic ignored "-Wconversion"
6#endif
7
8#include <stdexcept>
9#include <iostream>
10#include <cmath>
11#include <cstring>
12#include <algorithm>
13#include <limits>
14
15using namespace Bink;
16
17static const float sqrthalf = std::sqrt(0.5f);
18
19static const uint16_t ff_wma_critical_freqs[25] = {
20 100, 200, 300, 400, 510, 630, 770, 920,
21 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150,
22 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
23 24500,
24 };
25
26// Bink DCT and residue 8x8 block scan order
27static const uint8_t bink_scan[64] = {
28 0, 1, 8, 9, 2, 3, 10, 11,
29 4, 5, 12, 13, 6, 7, 14, 15,
30 20, 21, 28, 29, 22, 23, 30, 31,
31 16, 17, 24, 25, 32, 33, 40, 41,
32 34, 35, 42, 43, 48, 49, 56, 57,
33 50, 51, 58, 59, 18, 19, 26, 27,
34 36, 37, 44, 45, 38, 39, 46, 47,
35 52, 53, 60, 61, 54, 55, 62, 63
36 };
37static const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 };
38static const uint8_t bink_tree_lens [16][16] = {
39 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
40 { 1, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
41 { 2, 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
42 { 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
43 { 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 },
44 { 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 },
45 { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5 },
46 { 1, 3, 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
47 { 1, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
48 { 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6 },
49 { 2, 2, 3, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
50 { 1, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
51 { 2, 2, 2, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
52 { 1, 3, 3, 3, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7 },
53 { 1, 3, 3, 3, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
54 { 2, 2, 3, 3, 3, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 },
55 };
56static const uint8_t bink_patterns [16][64] = {
57 {
58 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
59 0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01,
60 0x02, 0x0A, 0x12, 0x1A, 0x22, 0x2A, 0x32, 0x3A,
61 0x3B, 0x33, 0x2B, 0x23, 0x1B, 0x13, 0x0B, 0x03,
62 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C,
63 0x3D, 0x35, 0x2D, 0x25, 0x1D, 0x15, 0x0D, 0x05,
64 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E,
65 0x3F, 0x37, 0x2F, 0x27, 0x1F, 0x17, 0x0F, 0x07,
66 },
67 {
68 0x3B, 0x3A, 0x39, 0x38, 0x30, 0x31, 0x32, 0x33,
69 0x2B, 0x2A, 0x29, 0x28, 0x20, 0x21, 0x22, 0x23,
70 0x1B, 0x1A, 0x19, 0x18, 0x10, 0x11, 0x12, 0x13,
71 0x0B, 0x0A, 0x09, 0x08, 0x00, 0x01, 0x02, 0x03,
72 0x04, 0x05, 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x0C,
73 0x14, 0x15, 0x16, 0x17, 0x1F, 0x1E, 0x1D, 0x1C,
74 0x24, 0x25, 0x26, 0x27, 0x2F, 0x2E, 0x2D, 0x2C,
75 0x34, 0x35, 0x36, 0x37, 0x3F, 0x3E, 0x3D, 0x3C,
76 },
77 {
78 0x19, 0x11, 0x12, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
79 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08, 0x10, 0x18,
80 0x20, 0x28, 0x30, 0x38, 0x39, 0x31, 0x29, 0x2A,
81 0x32, 0x3A, 0x3B, 0x33, 0x2B, 0x23, 0x22, 0x21,
82 0x1D, 0x15, 0x16, 0x1E, 0x1F, 0x17, 0x0F, 0x07,
83 0x06, 0x0E, 0x0D, 0x05, 0x04, 0x0C, 0x14, 0x1C,
84 0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x35, 0x2D, 0x2E,
85 0x36, 0x3E, 0x3F, 0x37, 0x2F, 0x27, 0x26, 0x25,
86 },
87 {
88 0x03, 0x0B, 0x02, 0x0A, 0x01, 0x09, 0x00, 0x08,
89 0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
90 0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
91 0x30, 0x38, 0x31, 0x39, 0x32, 0x3A, 0x33, 0x3B,
92 0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
93 0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
94 0x1C, 0x14, 0x1D, 0x15, 0x1E, 0x16, 0x1F, 0x17,
95 0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04,
96 },
97 {
98 0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
99 0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
100 0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
101 0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
102 0x27, 0x26, 0x2F, 0x2E, 0x37, 0x36, 0x3F, 0x3E,
103 0x3D, 0x3C, 0x35, 0x34, 0x2D, 0x2C, 0x25, 0x24,
104 0x23, 0x22, 0x2B, 0x2A, 0x33, 0x32, 0x3B, 0x3A,
105 0x39, 0x38, 0x31, 0x30, 0x29, 0x28, 0x21, 0x20,
106 },
107 {
108 0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B,
109 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B,
110 0x20, 0x21, 0x22, 0x23, 0x28, 0x29, 0x2A, 0x2B,
111 0x30, 0x31, 0x32, 0x33, 0x38, 0x39, 0x3A, 0x3B,
112 0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F,
113 0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F,
114 0x24, 0x25, 0x26, 0x27, 0x2C, 0x2D, 0x2E, 0x2F,
115 0x34, 0x35, 0x36, 0x37, 0x3C, 0x3D, 0x3E, 0x3F,
116 },
117 {
118 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x05, 0x0C, 0x04,
119 0x03, 0x0B, 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08,
120 0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
121 0x14, 0x1C, 0x15, 0x1D, 0x16, 0x1E, 0x17, 0x1F,
122 0x27, 0x2F, 0x26, 0x2E, 0x25, 0x2D, 0x24, 0x2C,
123 0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
124 0x31, 0x30, 0x38, 0x39, 0x3A, 0x32, 0x3B, 0x33,
125 0x3C, 0x34, 0x3D, 0x35, 0x36, 0x37, 0x3F, 0x3E,
126 },
127 {
128 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
129 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
130 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
131 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
132 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
133 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28,
134 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
135 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38,
136 },
137 {
138 0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
139 0x12, 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x10, 0x18,
140 0x20, 0x28, 0x29, 0x21, 0x22, 0x23, 0x2B, 0x2A,
141 0x32, 0x31, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
142 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37, 0x36, 0x35,
143 0x2D, 0x2C, 0x24, 0x25, 0x26, 0x2E, 0x2F, 0x27,
144 0x1F, 0x17, 0x16, 0x1E, 0x1D, 0x1C, 0x14, 0x15,
145 0x0D, 0x0C, 0x04, 0x05, 0x06, 0x0E, 0x0F, 0x07,
146 },
147 {
148 0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
149 0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
150 0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
151 0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
152 0x26, 0x27, 0x2E, 0x2F, 0x36, 0x37, 0x3E, 0x3F,
153 0x3C, 0x3D, 0x34, 0x35, 0x2C, 0x2D, 0x24, 0x25,
154 0x22, 0x23, 0x2A, 0x2B, 0x32, 0x33, 0x3A, 0x3B,
155 0x38, 0x39, 0x30, 0x31, 0x28, 0x29, 0x20, 0x21,
156 },
157 {
158 0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
159 0x13, 0x1B, 0x12, 0x1A, 0x11, 0x19, 0x10, 0x18,
160 0x20, 0x28, 0x21, 0x29, 0x22, 0x2A, 0x23, 0x2B,
161 0x33, 0x3B, 0x32, 0x3A, 0x31, 0x39, 0x30, 0x38,
162 0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
163 0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
164 0x1F, 0x17, 0x1E, 0x16, 0x1D, 0x15, 0x1C, 0x14,
165 0x0C, 0x04, 0x0D, 0x05, 0x0E, 0x06, 0x0F, 0x07,
166 },
167 {
168 0x00, 0x08, 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13,
169 0x0B, 0x03, 0x02, 0x01, 0x09, 0x11, 0x12, 0x0A,
170 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F, 0x17,
171 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x15, 0x16, 0x0E,
172 0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37,
173 0x2F, 0x27, 0x26, 0x25, 0x2D, 0x35, 0x36, 0x2E,
174 0x20, 0x28, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
175 0x2B, 0x23, 0x22, 0x21, 0x29, 0x31, 0x32, 0x2A,
176 },
177 {
178 0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
179 0x13, 0x1B, 0x1A, 0x12, 0x11, 0x10, 0x18, 0x19,
180 0x21, 0x20, 0x28, 0x29, 0x2A, 0x22, 0x23, 0x2B,
181 0x33, 0x3B, 0x3A, 0x32, 0x31, 0x39, 0x38, 0x30,
182 0x34, 0x3C, 0x3D, 0x35, 0x36, 0x3E, 0x3F, 0x37,
183 0x2F, 0x27, 0x26, 0x2E, 0x2D, 0x2C, 0x24, 0x25,
184 0x1D, 0x1C, 0x14, 0x15, 0x16, 0x1E, 0x1F, 0x17,
185 0x0E, 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x0C, 0x04,
186 },
187 {
188 0x18, 0x10, 0x08, 0x00, 0x01, 0x02, 0x03, 0x0B,
189 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x0A, 0x09, 0x12,
190 0x1C, 0x14, 0x0C, 0x04, 0x05, 0x06, 0x07, 0x0F,
191 0x17, 0x1F, 0x1E, 0x1D, 0x15, 0x0E, 0x0D, 0x16,
192 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27, 0x2F,
193 0x37, 0x3F, 0x3E, 0x3D, 0x35, 0x2E, 0x2D, 0x36,
194 0x38, 0x30, 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B,
195 0x33, 0x3B, 0x3A, 0x39, 0x31, 0x2A, 0x29, 0x32,
196 },
197 {
198 0x00, 0x08, 0x09, 0x01, 0x02, 0x0A, 0x12, 0x11,
199 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
200 0x07, 0x06, 0x0E, 0x0F, 0x17, 0x16, 0x15, 0x0D,
201 0x05, 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F,
202 0x3F, 0x3E, 0x36, 0x37, 0x2F, 0x2E, 0x2D, 0x35,
203 0x3D, 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27,
204 0x38, 0x30, 0x31, 0x39, 0x3A, 0x32, 0x2A, 0x29,
205 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B, 0x33, 0x3B,
206 },
207 {
208 0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19,
209 0x20, 0x21, 0x28, 0x29, 0x30, 0x31, 0x38, 0x39,
210 0x3A, 0x3B, 0x32, 0x33, 0x2A, 0x2B, 0x22, 0x23,
211 0x1A, 0x1B, 0x12, 0x13, 0x0A, 0x0B, 0x02, 0x03,
212 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
213 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x3C, 0x3D,
214 0x3E, 0x3F, 0x36, 0x37, 0x2E, 0x2F, 0x26, 0x27,
215 0x1E, 0x1F, 0x16, 0x17, 0x0E, 0x0F, 0x06, 0x07,
216 }
217};
218static const uint32_t bink_intra_quant[16][64] = {
219{
220 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C,
221 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552,
222 0x021F88, 0x01DC53, 0x027FAD, 0x01F697, 0x014819, 0x00A743, 0x015A31, 0x009688,
223 0x02346F, 0x030EE5, 0x01FBFA, 0x02C096, 0x01D000, 0x028396, 0x019247, 0x01F9AA,
224 0x02346F, 0x01FBFA, 0x01DC53, 0x0231B8, 0x012F12, 0x01E06C, 0x00CB10, 0x0119A8,
225 0x01C48C, 0x019748, 0x014E86, 0x0122AF, 0x02C628, 0x027F20, 0x0297B5, 0x023F32,
226 0x025000, 0x01AB6B, 0x01D122, 0x0159B3, 0x012669, 0x008D43, 0x00EE1F, 0x0075ED,
227 0x01490C, 0x010288, 0x00F735, 0x00EF51, 0x00E0F1, 0x0072AD, 0x00A4D8, 0x006517,
228},
229{
230 0x015555, 0x01D971, 0x028AFC, 0x0386F1, 0x01BDF9, 0x01DC9F, 0x03ED33, 0x034311,
231 0x015555, 0x013E78, 0x030158, 0x01FF7A, 0x00FE00, 0x00817D, 0x01604F, 0x00DC6D,
232 0x02D4B5, 0x027B19, 0x0354E7, 0x029E1F, 0x01B577, 0x00DF04, 0x01CD96, 0x00C8B6,
233 0x02F095, 0x0413DC, 0x02A54E, 0x03AB73, 0x026AAB, 0x035A1E, 0x02185E, 0x02A238,
234 0x02F095, 0x02A54E, 0x027B19, 0x02ECF5, 0x019418, 0x028090, 0x010EC0, 0x01778A,
235 0x025B66, 0x021F0B, 0x01BE09, 0x018394, 0x03B2E0, 0x03542A, 0x0374F1, 0x02FEEE,
236 0x031555, 0x0239E4, 0x026C2D, 0x01CCEE, 0x01888C, 0x00BC59, 0x013D7E, 0x009D3C,
237 0x01B6BB, 0x0158B5, 0x01499C, 0x013F17, 0x012BEC, 0x0098E6, 0x00DBCB, 0x0086C9,
238},
239{
240 0x01AAAB, 0x024FCE, 0x032DBB, 0x0468AD, 0x022D78, 0x0253C7, 0x04E87F, 0x0413D5,
241 0x01AAAB, 0x018E16, 0x03C1AE, 0x027F58, 0x013D80, 0x00A1DC, 0x01B863, 0x011388,
242 0x0389E2, 0x0319DF, 0x042A21, 0x0345A7, 0x0222D4, 0x0116C5, 0x0240FC, 0x00FAE3,
243 0x03ACBA, 0x0518D3, 0x034EA1, 0x04964F, 0x030555, 0x0430A5, 0x029E76, 0x034AC5,
244 0x03ACBA, 0x034EA1, 0x0319DF, 0x03A833, 0x01F91E, 0x0320B4, 0x015270, 0x01D56D,
245 0x02F23F, 0x02A6CE, 0x022D8B, 0x01E479, 0x049F98, 0x042935, 0x04522D, 0x03BEA9,
246 0x03DAAB, 0x02C85D, 0x030738, 0x02402A, 0x01EAAF, 0x00EB6F, 0x018CDE, 0x00C48A,
247 0x022469, 0x01AEE2, 0x019C02, 0x018EDD, 0x0176E7, 0x00BF20, 0x0112BE, 0x00A87B,
248},
249{
250 0x020000, 0x02C62A, 0x03D07A, 0x054A69, 0x029CF6, 0x02CAEF, 0x05E3CC, 0x04E499,
251 0x020000, 0x01DDB4, 0x048204, 0x02FF36, 0x017D01, 0x00C23C, 0x021077, 0x014AA3,
252 0x043F0F, 0x03B8A6, 0x04FF5A, 0x03ED2E, 0x029032, 0x014E86, 0x02B461, 0x012D11,
253 0x0468DF, 0x061DCA, 0x03F7F5, 0x05812C, 0x03A000, 0x05072C, 0x03248D, 0x03F353,
254 0x0468DF, 0x03F7F5, 0x03B8A6, 0x046370, 0x025E24, 0x03C0D8, 0x019620, 0x02334F,
255 0x038919, 0x032E91, 0x029D0D, 0x02455E, 0x058C50, 0x04FE3F, 0x052F69, 0x047E65,
256 0x04A000, 0x0356D6, 0x03A243, 0x02B365, 0x024CD2, 0x011A85, 0x01DC3E, 0x00EBD9,
257 0x029218, 0x020510, 0x01EE69, 0x01DEA2, 0x01C1E2, 0x00E559, 0x0149B0, 0x00CA2D,
258},
259{
260 0x02AAAB, 0x03B2E3, 0x0515F8, 0x070DE2, 0x037BF2, 0x03B93E, 0x07DA65, 0x068621,
261 0x02AAAB, 0x027CF0, 0x0602B1, 0x03FEF3, 0x01FC01, 0x0102FA, 0x02C09F, 0x01B8DA,
262 0x05A96A, 0x04F632, 0x06A9CE, 0x053C3E, 0x036AED, 0x01BE09, 0x039B2D, 0x01916B,
263 0x05E129, 0x0827B8, 0x054A9C, 0x0756E5, 0x04D555, 0x06B43B, 0x0430BC, 0x05446F,
264 0x05E129, 0x054A9C, 0x04F632, 0x05D9EB, 0x032830, 0x050121, 0x021D80, 0x02EF14,
265 0x04B6CC, 0x043E16, 0x037C11, 0x030728, 0x0765C0, 0x06A855, 0x06E9E2, 0x05FDDB,
266 0x062AAB, 0x0473C8, 0x04D85A, 0x0399DC, 0x031118, 0x0178B2, 0x027AFD, 0x013A77,
267 0x036D76, 0x02B16A, 0x029337, 0x027E2E, 0x0257D8, 0x0131CC, 0x01B796, 0x010D91,
268},
269{
270 0x038000, 0x04DACA, 0x06ACD5, 0x094238, 0x0492AE, 0x04E322, 0x0A4EA5, 0x08900C,
271 0x038000, 0x0343FB, 0x07E388, 0x053E9F, 0x029AC1, 0x0153E8, 0x039CD0, 0x02429E,
272 0x076E5B, 0x068322, 0x08BEDE, 0x06DF11, 0x047C57, 0x02496B, 0x04BBAB, 0x020EDD,
273 0x07B786, 0x0AB421, 0x06F1ED, 0x09A20D, 0x065800, 0x08CC8E, 0x057FF7, 0x06E9D2,
274 0x07B786, 0x06F1ED, 0x068322, 0x07AE04, 0x0424BF, 0x06917B, 0x02C6B8, 0x03D9CB,
275 0x062FEB, 0x05917D, 0x0492D7, 0x03F964, 0x09B58C, 0x08BCEF, 0x0912F8, 0x07DD30,
276 0x081800, 0x05D7F7, 0x065BF6, 0x04B9F1, 0x040670, 0x01EE69, 0x03416C, 0x019CBC,
277 0x047FAA, 0x0388DC, 0x036138, 0x03459C, 0x03134C, 0x01915C, 0x0240F5, 0x0161CF,
278},
279{
280 0x040000, 0x058C54, 0x07A0F4, 0x0A94D3, 0x0539EC, 0x0595DD, 0x0BC798, 0x09C932,
281 0x040000, 0x03BB68, 0x090409, 0x05FE6D, 0x02FA01, 0x018477, 0x0420EE, 0x029547,
282 0x087E1F, 0x07714C, 0x09FEB5, 0x07DA5D, 0x052064, 0x029D0D, 0x0568C3, 0x025A21,
283 0x08D1BE, 0x0C3B94, 0x07EFEA, 0x0B0258, 0x074000, 0x0A0E59, 0x06491A, 0x07E6A7,
284 0x08D1BE, 0x07EFEA, 0x07714C, 0x08C6E0, 0x04BC48, 0x0781B1, 0x032C3F, 0x04669F,
285 0x071232, 0x065D22, 0x053A1A, 0x048ABC, 0x0B18A0, 0x09FC7F, 0x0A5ED3, 0x08FCC9,
286 0x094000, 0x06ADAC, 0x074487, 0x0566CA, 0x0499A5, 0x02350B, 0x03B87B, 0x01D7B3,
287 0x052430, 0x040A20, 0x03DCD3, 0x03BD45, 0x0383C5, 0x01CAB3, 0x029361, 0x01945A,
288},
289{
290 0x050000, 0x06EF69, 0x098931, 0x0D3A07, 0x068867, 0x06FB55, 0x0EB97E, 0x0C3B7E,
291 0x050000, 0x04AA42, 0x0B450B, 0x077E08, 0x03B881, 0x01E595, 0x05292A, 0x033A99,
292 0x0A9DA7, 0x094D9F, 0x0C7E62, 0x09D0F4, 0x06687D, 0x034450, 0x06C2F4, 0x02F0AA,
293 0x0B062D, 0x0F4A78, 0x09EBE4, 0x0DC2EE, 0x091000, 0x0C91EF, 0x07DB61, 0x09E050,
294 0x0B062D, 0x09EBE4, 0x094D9F, 0x0AF898, 0x05EB59, 0x09621D, 0x03F74F, 0x058046,
295 0x08D6BE, 0x07F46A, 0x0688A0, 0x05AD6B, 0x0DDEC8, 0x0C7B9F, 0x0CF687, 0x0B3BFB,
296 0x0B9000, 0x085917, 0x0915A8, 0x06C07D, 0x05C00E, 0x02C24D, 0x04A69A, 0x024D9F,
297 0x066D3C, 0x050CA7, 0x04D407, 0x04AC96, 0x0464B6, 0x023D5F, 0x033839, 0x01F971,
298},
299{
300 0x060000, 0x08527E, 0x0B716E, 0x0FDF3C, 0x07D6E1, 0x0860CC, 0x11AB63, 0x0EADCB,
301 0x060000, 0x05991C, 0x0D860D, 0x08FDA3, 0x047702, 0x0246B3, 0x063165, 0x03DFEA,
302 0x0CBD2E, 0x0B29F1, 0x0EFE0F, 0x0BC78B, 0x07B096, 0x03EB93, 0x081D24, 0x038732,
303 0x0D3A9C, 0x12595D, 0x0BE7DF, 0x108384, 0x0AE000, 0x0F1585, 0x096DA8, 0x0BD9FA,
304 0x0D3A9C, 0x0BE7DF, 0x0B29F1, 0x0D2A50, 0x071A6B, 0x0B4289, 0x04C25F, 0x0699EE,
305 0x0A9B4A, 0x098BB2, 0x07D727, 0x06D01A, 0x10A4F0, 0x0EFABE, 0x0F8E3C, 0x0D7B2E,
306 0x0DE000, 0x0A0482, 0x0AE6CA, 0x081A2F, 0x06E677, 0x034F90, 0x0594B9, 0x02C38C,
307 0x07B649, 0x060F2F, 0x05CB3C, 0x059BE7, 0x0545A7, 0x02B00C, 0x03DD11, 0x025E87,
308},
309{
310 0x080000, 0x0B18A8, 0x0F41E8, 0x1529A5, 0x0A73D7, 0x0B2BBB, 0x178F2F, 0x139264,
311 0x080000, 0x0776CF, 0x120812, 0x0BFCD9, 0x05F402, 0x0308EF, 0x0841DC, 0x052A8E,
312 0x10FC3E, 0x0EE297, 0x13FD69, 0x0FB4B9, 0x0A40C8, 0x053A1A, 0x0AD186, 0x04B442,
313 0x11A37B, 0x187727, 0x0FDFD4, 0x1604B0, 0x0E8000, 0x141CB1, 0x0C9235, 0x0FCD4D,
314 0x11A37B, 0x0FDFD4, 0x0EE297, 0x118DC0, 0x09788F, 0x0F0362, 0x06587F, 0x08CD3D,
315 0x0E2463, 0x0CBA43, 0x0A7434, 0x091577, 0x163140, 0x13F8FE, 0x14BDA5, 0x11F992,
316 0x128000, 0x0D5B58, 0x0E890D, 0x0ACD94, 0x093349, 0x046A15, 0x0770F7, 0x03AF65,
317 0x0A4861, 0x08143F, 0x07B9A6, 0x077A89, 0x070789, 0x039565, 0x0526C2, 0x0328B4,
318},
319{
320 0x0C0000, 0x10A4FD, 0x16E2DB, 0x1FBE78, 0x0FADC3, 0x10C198, 0x2356C7, 0x1D5B96,
321 0x0C0000, 0x0B3237, 0x1B0C1A, 0x11FB46, 0x08EE03, 0x048D66, 0x0C62CA, 0x07BFD5,
322 0x197A5D, 0x1653E3, 0x1DFC1E, 0x178F16, 0x0F612C, 0x07D727, 0x103A49, 0x070E64,
323 0x1A7539, 0x24B2BB, 0x17CFBD, 0x210709, 0x15C000, 0x1E2B0A, 0x12DB4F, 0x17B3F4,
324 0x1A7539, 0x17CFBD, 0x1653E3, 0x1A54A0, 0x0E34D7, 0x168513, 0x0984BE, 0x0D33DC,
325 0x153695, 0x131765, 0x0FAE4E, 0x0DA033, 0x2149E1, 0x1DF57D, 0x1F1C78, 0x1AF65B,
326 0x1BC000, 0x140904, 0x15CD94, 0x10345E, 0x0DCCEE, 0x069F20, 0x0B2972, 0x058718,
327 0x0F6C91, 0x0C1E5E, 0x0B9678, 0x0B37CE, 0x0A8B4E, 0x056018, 0x07BA22, 0x04BD0E,
328},
329{
330 0x110000, 0x179466, 0x206C0C, 0x2CF87F, 0x16362A, 0x17BCED, 0x321044, 0x299714,
331 0x110000, 0x0FDC79, 0x265125, 0x19794E, 0x0CA685, 0x0672FB, 0x118BF4, 0x0AFA6D,
332 0x241804, 0x1FA181, 0x2A7A80, 0x21600A, 0x15C9A9, 0x0B1B77, 0x16FD3C, 0x09FF0D,
333 0x257B66, 0x33FD33, 0x21BBA2, 0x2EC9F7, 0x1ED000, 0x2ABCF9, 0x1AB6B0, 0x219444,
334 0x257B66, 0x21BBA2, 0x1FA181, 0x254D38, 0x142030, 0x1FE730, 0x0D7C0E, 0x12B423,
335 0x1E0D52, 0x1B0BCF, 0x1636EE, 0x134D9E, 0x2F28A9, 0x2A711B, 0x2C12FF, 0x263256,
336 0x275000, 0x1C621B, 0x1EE33C, 0x16F4DB, 0x138CFB, 0x09616E, 0x0FD00C, 0x07D4B7,
337 0x15D9CE, 0x112B06, 0x106A80, 0x0FE464, 0x0EF004, 0x079D77, 0x0AF25B, 0x06B67F,
338},
339{
340 0x160000, 0x1E83CF, 0x29F53D, 0x3A3286, 0x1CBE90, 0x1EB842, 0x40C9C2, 0x35D293,
341 0x160000, 0x1486BA, 0x319630, 0x20F756, 0x105F06, 0x085891, 0x16B51E, 0x0E3506,
342 0x2EB5AA, 0x28EF20, 0x36F8E1, 0x2B30FE, 0x1C3225, 0x0E5FC7, 0x1DC030, 0x0CEFB7,
343 0x308193, 0x4347AC, 0x2BA786, 0x3C8CE5, 0x27E000, 0x374EE7, 0x229212, 0x2B7494,
344 0x308193, 0x2BA786, 0x28EF20, 0x3045D0, 0x1A0B89, 0x29494D, 0x11735D, 0x183469,
345 0x26E410, 0x230039, 0x1CBF8F, 0x18FB09, 0x3D0771, 0x36ECBA, 0x390986, 0x316E52,
346 0x32E000, 0x24BB33, 0x27F8E4, 0x1DB557, 0x194D09, 0x0C23BB, 0x1476A6, 0x0A2256,
347 0x1C470A, 0x1637AD, 0x153E87, 0x1490FA, 0x1354B9, 0x09DAD6, 0x0E2A94, 0x08AFF0,
348},
349{
350 0x1C0000, 0x26D64D, 0x3566AA, 0x4A11C2, 0x249572, 0x27190E, 0x527525, 0x44805E,
351 0x1C0000, 0x1A1FD6, 0x3F1C3E, 0x29F4F9, 0x14D607, 0x0A9F44, 0x1CE683, 0x1214F0,
352 0x3B72D9, 0x341911, 0x45F6F0, 0x36F889, 0x23E2BB, 0x124B5B, 0x25DD54, 0x1076E9,
353 0x3DBC30, 0x55A109, 0x378F64, 0x4D1069, 0x32C000, 0x46646C, 0x2BFFB9, 0x374E8E,
354 0x3DBC30, 0x378F64, 0x341911, 0x3D7020, 0x2125F5, 0x348BD6, 0x1635BC, 0x1ECE57,
355 0x317F5B, 0x2C8BEB, 0x2496B6, 0x1FCB22, 0x4DAC61, 0x45E778, 0x4897C2, 0x3EE97F,
356 0x40C000, 0x2EBFB5, 0x32DFAE, 0x25CF86, 0x203380, 0x0F734B, 0x1A0B5F, 0x0CE5E2,
357 0x23FD53, 0x1C46DC, 0x1B09C4, 0x1A2CE1, 0x189A60, 0x0C8AE2, 0x1207A5, 0x0B0E77,
358},
359{
360 0x220000, 0x2F28CC, 0x40D818, 0x59F0FE, 0x2C6C53, 0x2F79DA, 0x642089, 0x532E29,
361 0x220000, 0x1FB8F1, 0x4CA24B, 0x32F29C, 0x194D09, 0x0CE5F7, 0x2317E8, 0x15F4DB,
362 0x483007, 0x3F4303, 0x54F4FF, 0x42C014, 0x2B9351, 0x1636EE, 0x2DFA79, 0x13FE1A,
363 0x4AF6CC, 0x67FA67, 0x437743, 0x5D93EE, 0x3DA000, 0x5579F1, 0x356D61, 0x432888,
364 0x4AF6CC, 0x437743, 0x3F4303, 0x4A9A70, 0x284060, 0x3FCE60, 0x1AF81B, 0x256845,
365 0x3C1AA5, 0x36179D, 0x2C6DDD, 0x269B3C, 0x5E5152, 0x54E237, 0x5825FE, 0x4C64AD,
366 0x4EA000, 0x38C437, 0x3DC678, 0x2DE9B5, 0x2719F7, 0x12C2DB, 0x1FA018, 0x0FA96E,
367 0x2BB39B, 0x22560C, 0x20D500, 0x1FC8C8, 0x1DE007, 0x0F3AEE, 0x15E4B7, 0x0D6CFE,
368},
369{
370 0x2C0000, 0x3D079E, 0x53EA79, 0x74650C, 0x397D20, 0x3D7083, 0x819383, 0x6BA525,
371 0x2C0000, 0x290D75, 0x632C61, 0x41EEAC, 0x20BE0C, 0x10B121, 0x2D6A3B, 0x1C6A0C,
372 0x5D6B54, 0x51DE40, 0x6DF1C2, 0x5661FB, 0x38644B, 0x1CBF8F, 0x3B8060, 0x19DF6D,
373 0x610326, 0x868F57, 0x574F0B, 0x7919CA, 0x4FC000, 0x6E9DCE, 0x452423, 0x56E928,
374 0x610326, 0x574F0B, 0x51DE40, 0x608BA0, 0x341713, 0x52929A, 0x22E6BA, 0x3068D2,
375 0x4DC821, 0x460071, 0x397F1E, 0x31F611, 0x7A0EE2, 0x6DD974, 0x72130C, 0x62DCA3,
376 0x65C000, 0x497665, 0x4FF1C9, 0x3B6AAE, 0x329A12, 0x184776, 0x28ED4D, 0x1444AC,
377 0x388E14, 0x2C6F5A, 0x2A7D0F, 0x2921F4, 0x26A973, 0x13B5AD, 0x1C5528, 0x115FDF,
378},
379};
380static const uint32_t bink_inter_quant[16][64] = {
381{
382 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA,
383 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095,
384 0x01B701, 0x016959, 0x01B0B9, 0x0153FD, 0x00F8E7, 0x007EE4, 0x00EA30, 0x007763,
385 0x01B701, 0x0260EB, 0x019DE9, 0x023E1B, 0x017000, 0x01FE6E, 0x012DB5, 0x01A27B,
386 0x01E0D1, 0x01B0B9, 0x018A33, 0x01718D, 0x00D87A, 0x014449, 0x007B9A, 0x00AB71,
387 0x013178, 0x0112EA, 0x00AD08, 0x009BB9, 0x023D97, 0x020437, 0x021CCC, 0x01E6B4,
388 0x018000, 0x012DB5, 0x0146D9, 0x0100CE, 0x00CFD2, 0x006E5C, 0x00B0E4, 0x005A2D,
389 0x00E9CC, 0x00B7B1, 0x00846F, 0x006B85, 0x008337, 0x0042E5, 0x004A10, 0x002831,
390},
391{
392 0x015555, 0x01F708, 0x023237, 0x030BD0, 0x01D9D9, 0x01C389, 0x03053B, 0x02B7E3,
393 0x018000, 0x012DB5, 0x024FCE, 0x01D0FA, 0x00DB5D, 0x006FD5, 0x014048, 0x00AB71,
394 0x024957, 0x01E1CC, 0x0240F7, 0x01C551, 0x014BDE, 0x00A92F, 0x013840, 0x009F2F,
395 0x024957, 0x032BE4, 0x0227E1, 0x02FD7A, 0x01EAAB, 0x02A893, 0x019247, 0x022DF9,
396 0x028116, 0x0240F7, 0x020D99, 0x01ECBC, 0x0120A3, 0x01B061, 0x00A4CE, 0x00E497,
397 0x01974B, 0x016E8E, 0x00E6B5, 0x00CFA2, 0x02FCC9, 0x02B04A, 0x02D110, 0x0288F1,
398 0x020000, 0x019247, 0x01B3CC, 0x015668, 0x011518, 0x009325, 0x00EBDA, 0x00783D,
399 0x0137BB, 0x00F4ED, 0x00B093, 0x008F5C, 0x00AEF4, 0x005931, 0x0062BF, 0x003597,
400},
401{
402 0x01AAAB, 0x0274CB, 0x02BEC4, 0x03CEC4, 0x02504F, 0x02346C, 0x03C689, 0x0365DC,
403 0x01E000, 0x017922, 0x02E3C1, 0x024539, 0x011235, 0x008BCA, 0x01905A, 0x00D64D,
404 0x02DBAD, 0x025A40, 0x02D134, 0x0236A5, 0x019ED6, 0x00D37B, 0x018650, 0x00C6FB,
405 0x02DBAD, 0x03F6DD, 0x02B1D9, 0x03BCD8, 0x026555, 0x0352B8, 0x01F6D8, 0x02B977,
406 0x03215C, 0x02D134, 0x029100, 0x0267EB, 0x0168CC, 0x021C7A, 0x00CE01, 0x011DBD,
407 0x01FD1E, 0x01CA31, 0x012062, 0x01038A, 0x03BBFB, 0x035C5C, 0x038554, 0x032B2D,
408 0x028000, 0x01F6D8, 0x0220C0, 0x01AC02, 0x015A5E, 0x00B7EF, 0x0126D1, 0x00964C,
409 0x0185A9, 0x013228, 0x00DCB8, 0x00B333, 0x00DAB2, 0x006F7D, 0x007B6F, 0x0042FC,
410},
411{
412 0x020000, 0x02F28D, 0x034B52, 0x0491B8, 0x02C6C5, 0x02A54E, 0x0487D8, 0x0413D5,
413 0x024000, 0x01C48F, 0x0377B5, 0x02B977, 0x01490C, 0x00A7BF, 0x01E06C, 0x01012A,
414 0x036E03, 0x02D2B3, 0x036172, 0x02A7FA, 0x01F1CE, 0x00FDC7, 0x01D460, 0x00EEC7,
415 0x036E03, 0x04C1D6, 0x033BD1, 0x047C37, 0x02E000, 0x03FCDD, 0x025B6A, 0x0344F5,
416 0x03C1A1, 0x036172, 0x031466, 0x02E31B, 0x01B0F5, 0x028892, 0x00F735, 0x0156E2,
417 0x0262F1, 0x0225D5, 0x015A10, 0x013772, 0x047B2D, 0x04086E, 0x043998, 0x03CD69,
418 0x030000, 0x025B6A, 0x028DB3, 0x02019B, 0x019FA3, 0x00DCB8, 0x0161C7, 0x00B45B,
419 0x01D398, 0x016F63, 0x0108DD, 0x00D70A, 0x01066F, 0x0085C9, 0x00941F, 0x005062,
420},
421{
422 0x02AAAB, 0x03EE11, 0x04646D, 0x0617A0, 0x03B3B2, 0x038713, 0x060A75, 0x056FC6,
423 0x030000, 0x025B6A, 0x049F9B, 0x03A1F4, 0x01B6BB, 0x00DFAA, 0x028090, 0x0156E2,
424 0x0492AE, 0x03C399, 0x0481ED, 0x038AA2, 0x0297BD, 0x01525F, 0x027080, 0x013E5E,
425 0x0492AE, 0x0657C8, 0x044FC1, 0x05FAF4, 0x03D555, 0x055126, 0x03248D, 0x045BF2,
426 0x05022D, 0x0481ED, 0x041B33, 0x03D979, 0x024147, 0x0360C3, 0x01499C, 0x01C92E,
427 0x032E96, 0x02DD1C, 0x01CD6A, 0x019F43, 0x05F991, 0x056093, 0x05A220, 0x0511E1,
428 0x040000, 0x03248D, 0x036799, 0x02ACCF, 0x022A2F, 0x01264B, 0x01D7B5, 0x00F079,
429 0x026F75, 0x01E9D9, 0x016127, 0x011EB8, 0x015DE9, 0x00B262, 0x00C57F, 0x006B2D,
430},
431{
432 0x038000, 0x052876, 0x05C3CF, 0x07FF02, 0x04DBD9, 0x04A148, 0x07EDBA, 0x0722B4,
433 0x03F000, 0x0317FB, 0x06117C, 0x04C491, 0x023FD5, 0x01258F, 0x0348BD, 0x01C209,
434 0x060085, 0x04F0B9, 0x05EA87, 0x04A5F5, 0x036728, 0x01BC1C, 0x0333A8, 0x01A1DB,
435 0x060085, 0x085336, 0x05A8AE, 0x07D960, 0x050800, 0x06FA82, 0x041FF9, 0x05B8AE,
436 0x0692DA, 0x05EA87, 0x0563B2, 0x050D6E, 0x02F5AD, 0x046F00, 0x01B09C, 0x02580C,
437 0x042D25, 0x03C235, 0x025D9B, 0x022108, 0x07D78F, 0x070EC1, 0x0764CA, 0x06A777,
438 0x054000, 0x041FF9, 0x0477F9, 0x0382D0, 0x02D75E, 0x018242, 0x026B1D, 0x013B9F,
439 0x03324A, 0x0282ED, 0x01CF83, 0x017851, 0x01CB42, 0x00EA21, 0x010336, 0x008CAC,
440},
441{
442 0x040000, 0x05E519, 0x0696A4, 0x092370, 0x058D8A, 0x054A9C, 0x090FB0, 0x0827AA,
443 0x048000, 0x03891F, 0x06EF69, 0x0572EE, 0x029218, 0x014F7E, 0x03C0D8, 0x020254,
444 0x06DC05, 0x05A565, 0x06C2E4, 0x054FF3, 0x03E39B, 0x01FB8E, 0x03A8C0, 0x01DD8D,
445 0x06DC05, 0x0983AC, 0x0677A2, 0x08F86E, 0x05C000, 0x07F9B9, 0x04B6D4, 0x0689EB,
446 0x078343, 0x06C2E4, 0x0628CC, 0x05C635, 0x0361EA, 0x051124, 0x01EE69, 0x02ADC5,
447 0x04C5E1, 0x044BAA, 0x02B41F, 0x026EE5, 0x08F65A, 0x0810DD, 0x087330, 0x079AD1,
448 0x060000, 0x04B6D4, 0x051B65, 0x040337, 0x033F47, 0x01B970, 0x02C38F, 0x0168B6,
449 0x03A730, 0x02DEC6, 0x0211BA, 0x01AE14, 0x020CDD, 0x010B93, 0x01283E, 0x00A0C4,
450},
451{
452 0x050000, 0x075E60, 0x083C4D, 0x0B6C4C, 0x06F0ED, 0x069D43, 0x0B539C, 0x0A3194,
453 0x05A000, 0x046B67, 0x08AB44, 0x06CFAA, 0x03369E, 0x01A35E, 0x04B10F, 0x0282E8,
454 0x089307, 0x070EBF, 0x08739C, 0x06A3F0, 0x04DC82, 0x027A72, 0x0492F0, 0x0254F0,
455 0x089307, 0x0BE497, 0x08158B, 0x0B3689, 0x073000, 0x09F827, 0x05E489, 0x082C66,
456 0x096413, 0x08739C, 0x07B2FF, 0x0737C2, 0x043A64, 0x06556D, 0x026A04, 0x035936,
457 0x05F75A, 0x055E94, 0x036127, 0x030A9E, 0x0B33F1, 0x0A1514, 0x0A8FFC, 0x098186,
458 0x078000, 0x05E489, 0x06623F, 0x050405, 0x040F19, 0x0227CC, 0x037473, 0x01C2E3,
459 0x0490FC, 0x039677, 0x029629, 0x021999, 0x029015, 0x014E78, 0x01724E, 0x00C8F5,
460},
461{
462 0x060000, 0x08D7A6, 0x09E1F6, 0x0DB528, 0x085450, 0x07EFEA, 0x0D9788, 0x0C3B7E,
463 0x06C000, 0x054DAE, 0x0A671E, 0x082C66, 0x03DB24, 0x01F73E, 0x05A145, 0x03037D,
464 0x0A4A08, 0x087818, 0x0A2455, 0x07F7ED, 0x05D569, 0x02F955, 0x057D20, 0x02CC54,
465 0x0A4A08, 0x0E4582, 0x09B373, 0x0D74A5, 0x08A000, 0x0BF696, 0x07123E, 0x09CEE0,
466 0x0B44E4, 0x0A2455, 0x093D32, 0x08A950, 0x0512DF, 0x0799B6, 0x02E59E, 0x0404A7,
467 0x0728D2, 0x06717F, 0x040E2F, 0x03A657, 0x0D7187, 0x0C194B, 0x0CACC8, 0x0B683A,
468 0x090000, 0x07123E, 0x07A918, 0x0604D2, 0x04DEEA, 0x029629, 0x042556, 0x021D11,
469 0x057AC8, 0x044E28, 0x031A97, 0x02851E, 0x03134C, 0x01915C, 0x01BC5D, 0x00F126,
470},
471{
472 0x080000, 0x0BCA33, 0x0D2D48, 0x1246E0, 0x0B1B15, 0x0A9538, 0x121F5F, 0x104F53,
473 0x090000, 0x07123E, 0x0DDED2, 0x0AE5DD, 0x052430, 0x029EFD, 0x0781B1, 0x0404A7,
474 0x0DB80B, 0x0B4ACB, 0x0D85C7, 0x0A9FE7, 0x07C736, 0x03F71D, 0x075180, 0x03BB1A,
475 0x0DB80B, 0x130757, 0x0CEF44, 0x11F0DC, 0x0B8000, 0x0FF372, 0x096DA8, 0x0D13D6,
476 0x0F0686, 0x0D85C7, 0x0C5198, 0x0B8C6A, 0x06C3D4, 0x0A2248, 0x03DCD3, 0x055B8A,
477 0x098BC3, 0x089754, 0x05683E, 0x04DDC9, 0x11ECB4, 0x1021B9, 0x10E661, 0x0F35A3,
478 0x0C0000, 0x096DA8, 0x0A36CB, 0x08066E, 0x067E8E, 0x0372E1, 0x05871E, 0x02D16B,
479 0x074E60, 0x05BD8B, 0x042374, 0x035C28, 0x0419BB, 0x021726, 0x02507C, 0x014188,
480},
481{
482 0x0C0000, 0x11AF4C, 0x13C3EC, 0x1B6A50, 0x10A89F, 0x0FDFD4, 0x1B2F0F, 0x1876FD,
483 0x0D8000, 0x0A9B5D, 0x14CE3C, 0x1058CB, 0x07B649, 0x03EE7B, 0x0B4289, 0x0606FB,
484 0x149410, 0x10F030, 0x1448AB, 0x0FEFDA, 0x0BAAD2, 0x05F2AB, 0x0AFA40, 0x0598A7,
485 0x149410, 0x1C8B03, 0x1366E6, 0x1AE949, 0x114000, 0x17ED2B, 0x0E247C, 0x139DC1,
486 0x1689C8, 0x1448AB, 0x127A63, 0x11529F, 0x0A25BE, 0x0F336D, 0x05CB3C, 0x08094E,
487 0x0E51A4, 0x0CE2FE, 0x081C5D, 0x074CAE, 0x1AE30E, 0x183296, 0x195991, 0x16D074,
488 0x120000, 0x0E247C, 0x0F5230, 0x0C09A5, 0x09BDD5, 0x052C51, 0x084AAC, 0x043A21,
489 0x0AF590, 0x089C51, 0x06352E, 0x050A3B, 0x062698, 0x0322B9, 0x0378BA, 0x01E24D,
490},
491{
492 0x110000, 0x190DAC, 0x1C0039, 0x26D69C, 0x17998C, 0x167D16, 0x2682AB, 0x22A891,
493 0x132000, 0x0F06C3, 0x1D797F, 0x172876, 0x0AECE7, 0x0591D9, 0x0FF398, 0x0889E3,
494 0x1D2717, 0x17FEEF, 0x1CBC47, 0x1693CA, 0x108754, 0x086D1D, 0x0F8D30, 0x07ED98,
495 0x1D2717, 0x286F9A, 0x1B7C71, 0x261FD3, 0x187000, 0x21E552, 0x140904, 0x1BCA27,
496 0x1FEDDC, 0x1CBC47, 0x1A2D62, 0x188A62, 0x0E6022, 0x1588DA, 0x083540, 0x0B6284,
497 0x1448FE, 0x124192, 0x0B7D84, 0x0A574B, 0x2616FF, 0x2247AA, 0x23E98D, 0x2051FA,
498 0x198000, 0x140904, 0x15B46F, 0x110DAA, 0x0DCCEE, 0x07541E, 0x0BBF1F, 0x05FD04,
499 0x0F868B, 0x0C32C8, 0x08CB57, 0x0723D4, 0x08B6AD, 0x047130, 0x04EB08, 0x02AB42,
500},
501{
502 0x160000, 0x206C0C, 0x243C86, 0x3242E8, 0x1E8A79, 0x1D1A59, 0x31D646, 0x2CDA25,
503 0x18C000, 0x13722A, 0x2624C3, 0x1DF820, 0x0E2385, 0x073537, 0x14A4A7, 0x0B0CCC,
504 0x25BA1D, 0x1F0DAE, 0x252FE4, 0x1D37BB, 0x1563D6, 0x0AE78E, 0x142021, 0x0A4288,
505 0x25BA1D, 0x345430, 0x2391FB, 0x31565C, 0x1FA000, 0x2BDD7A, 0x19ED8D, 0x23F68C,
506 0x2951EF, 0x252FE4, 0x21E061, 0x1FC224, 0x129A87, 0x1BDE47, 0x0A9F44, 0x0EBBBA,
507 0x1A4058, 0x17A026, 0x0EDEAB, 0x0D61E9, 0x314AEF, 0x2C5CBE, 0x2E798A, 0x29D380,
508 0x210000, 0x19ED8D, 0x1C16AE, 0x1611AE, 0x11DC06, 0x097BEA, 0x0F3391, 0x07BFE7,
509 0x141787, 0x0FC93E, 0x0B617F, 0x093D6D, 0x0B46C1, 0x05BFA8, 0x065D55, 0x037437,
510},
511{
512 0x1C0000, 0x2943B2, 0x2E1E7C, 0x3FF810, 0x26DEC9, 0x250A43, 0x3F6DCE, 0x3915A3,
513 0x1F8000, 0x18BFD8, 0x308BE1, 0x262485, 0x11FEA9, 0x092C75, 0x1A45EB, 0x0E1049,
514 0x300425, 0x2785C6, 0x2F5439, 0x252FA8, 0x1B393F, 0x0DE0E4, 0x199D41, 0x0D0EDC,
515 0x300425, 0x4299B2, 0x2D456E, 0x3ECB00, 0x284000, 0x37D40F, 0x20FFCB, 0x2DC56D,
516 0x3496D3, 0x2F5439, 0x2B1D93, 0x286B74, 0x17AD66, 0x2377FE, 0x0D84E2, 0x12C062,
517 0x21692A, 0x1E11A5, 0x12ECDA, 0x110840, 0x3EBC76, 0x387608, 0x3B2652, 0x353BBA,
518 0x2A0000, 0x20FFCB, 0x23BFC6, 0x1C1681, 0x16BAF1, 0x0C1213, 0x1358E8, 0x09DCF8,
519 0x19924F, 0x141767, 0x0E7C16, 0x0BC28A, 0x0E5A0D, 0x075104, 0x0819B2, 0x04655D,
520},
521{
522 0x220000, 0x321B58, 0x380072, 0x4DAD38, 0x2F3318, 0x2CFA2D, 0x4D0556, 0x455122,
523 0x264000, 0x1E0D86, 0x3AF2FE, 0x2E50EB, 0x15D9CE, 0x0B23B2, 0x1FE730, 0x1113C7,
524 0x3A4E2D, 0x2FFDDF, 0x39788E, 0x2D2795, 0x210EA8, 0x10DA39, 0x1F1A61, 0x0FDB2F,
525 0x3A4E2D, 0x50DF33, 0x36F8E1, 0x4C3FA5, 0x30E000, 0x43CAA5, 0x281209, 0x37944D,
526 0x3FDBB7, 0x39788E, 0x345AC4, 0x3114C3, 0x1CC044, 0x2B11B4, 0x106A80, 0x16C509,
527 0x2891FC, 0x248324, 0x16FB08, 0x14AE97, 0x4C2DFD, 0x448F54, 0x47D31B, 0x40A3F5,
528 0x330000, 0x281209, 0x2B68DF, 0x221B53, 0x1B99DB, 0x0EA83B, 0x177E3E, 0x0BFA09,
529 0x1F0D17, 0x18658F, 0x1196AE, 0x0E47A8, 0x116D5A, 0x08E260, 0x09D60F, 0x055684,
530},
531{
532 0x2C0000, 0x40D818, 0x48790C, 0x6485D0, 0x3D14F2, 0x3A34B2, 0x63AC8D, 0x59B44A,
533 0x318000, 0x26E454, 0x4C4986, 0x3BF03F, 0x1C470A, 0x0E6A6E, 0x29494D, 0x161998,
534 0x4B743A, 0x3E1B5C, 0x4A5FC7, 0x3A6F75, 0x2AC7AC, 0x15CF1D, 0x284041, 0x148510,
535 0x4B743A, 0x68A861, 0x4723F6, 0x62ACB8, 0x3F4000, 0x57BAF3, 0x33DB1A, 0x47ED19,
536 0x52A3DE, 0x4A5FC7, 0x43C0C2, 0x3F8448, 0x25350D, 0x37BC8E, 0x153E87, 0x1D7775,
537 0x3480B0, 0x2F404C, 0x1DBD56, 0x1AC3D2, 0x6295DE, 0x58B97B, 0x5CF313, 0x53A701,
538 0x420000, 0x33DB1A, 0x382D5C, 0x2C235D, 0x23B80D, 0x12F7D4, 0x1E6723, 0x0F7FCF,
539 0x282F0E, 0x1F927D, 0x16C2FF, 0x127AD9, 0x168D83, 0x0B7F50, 0x0CBAAA, 0x06E86E,
540},
541};
542static const uint8_t rle_length_tab [16] = {
543 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
544 };
545
546struct VLCcode {
547 uint8_t bits;
548 uint16_t symbol;
549 // codeword, with the first bit-to-be-read in the msb
550 // (even if intended for a little-endian bitstream reader)
551 uint32_t code;
552 };
553
554struct VLC {
555 int bits = 0;
556 int16_t (*table)[2] = {}; // code, bits
557 int table_size = 0;
559 };
560
561static VLC bink_trees[16];
562
563static std::vector<float> ffCosTabs[18];
564
565static uint32_t AV_RL32(const char* v) {
566 uint32_t ret=0;
567 while(*v) {
568 ret *=256;
569 ret += *v;
570 ++v;
571 }
572 return ret;
573 }
574
575static int av_log2(unsigned v) {
576 return int(std::log2(v));
577 }
578
579template<class T>
580static void idctTransform(T* dest, const int* src,
581 int s0, int s1, int s2, int s3, int s4, int s5, int s6, int s7,
582 int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7,
583 T (*munge)(int)) {
584 enum {
585 A1 = 2896, /* (1/sqrt(2))<<12 */
586 A2 = 2217,
587 A3 = 3784,
588 A4 = -5352
589 };
590 static int (*mul)(int,int) = [](int x,int y) -> int { return int(uint32_t(x)*uint32_t(y)) >> 11; };
591
592 const int a0 = (src)[s0] + (src)[s4];
593 const int a1 = (src)[s0] - (src)[s4];
594 const int a2 = (src)[s2] + (src)[s6];
595 const int a3 = mul(A1, (src)[s2] - (src)[s6]);
596 const int a4 = (src)[s5] + (src)[s3];
597 const int a5 = (src)[s5] - (src)[s3];
598 const int a6 = (src)[s1] + (src)[s7];
599 const int a7 = (src)[s1] - (src)[s7];
600 const int b0 = a4 + a6;
601 const int b1 = mul(A3, a5 + a7);
602 const int b2 = mul(A4, a5) - b0 + b1;
603 const int b3 = mul(A1, a6 - a4) - b2;
604 const int b4 = mul(A2, a7) + b3 - b1;
605 dest[d0] = munge(a0+a2 +b0);
606 dest[d1] = munge(a1+a3-a2+b2);
607 dest[d2] = munge(a1-a3+a2+b3);
608 dest[d3] = munge(a0-a2 -b4);
609 dest[d4] = munge(a0-a2 +b4);
610 dest[d5] = munge(a1-a3+a2-b3);
611 dest[d6] = munge(a1+a3-a2-b2);
612 dest[d7] = munge(a0+a2 -b0);
613 }
614
615template<class T>
616static void idctCol(T* dest, const int* src) {
617 static T (*munge)(int) = [](int x) -> T { return T(x); };
618 idctTransform(dest,src,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,munge);
619 }
620
621template<class T>
622static void idctRow(T* dest, const int* src) {
623 static T (*munge)(int) = [](int x) -> T { return T((x + 0x7F)>>8); };
624 idctTransform(dest,src,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,munge);
625 }
626
627static void bink_idct_col(int *dest, const int32_t *src) {
628 if((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
629 dest[0] =
630 dest[8] =
631 dest[16] =
632 dest[24] =
633 dest[32] =
634 dest[40] =
635 dest[48] =
636 dest[56] = src[0];
637 } else {
638 idctCol(dest, src);
639 }
640 }
641
642template<class T>
643static void BF(T& x, T& y, const T& a, const T& b) {
644 x = a-b;
645 y = a+b;
646 }
647
648template<class T>
649static void CMUL(T& dre, T& dim, const T& are, const T& aim, const T& bre, const T& bim) {
650 dre = are*bre - aim*bim;
651 dim = are*bim + aim*bre;
652 }
653
655 float& t1, float& t2, float& t3, float& t4, float& t5, float& t6) {
656 BF(t3, t5, t5, t1);
657 BF(a2.re, a0.re, a0.re, t5);
658 BF(a3.im, a1.im, a1.im, t3);
659 BF(t4, t6, t2, t6);
660 BF(a3.re, a1.re, a1.re, t4);
661 BF(a2.im, a0.im, a0.im, t6);
662 }
663
664static void transform(Video::FFTComplex& a0, Video::FFTComplex& a1, Video::FFTComplex& a2, Video::FFTComplex& a3, const float wre, const float wim,
665 float& t1, float& t2, float& t3, float& t4, float& t5, float& t6) {
666 CMUL(t1, t2, a2.re, a2.im, wre, -wim);
667 CMUL(t5, t6, a3.re, a3.im, wre, wim);
668 BUTTERFLIES(a0,a1,a2,a3, t1,t2,t3,t4,t5,t6);
669 }
670
672 float& t1, float& t2, float& t3, float& t4, float& t5, float& t6) {
673 t1 = a2.re;
674 t2 = a2.im;
675 t5 = a3.re;
676 t6 = a3.im;
677 BUTTERFLIES(a0,a1,a2,a3, t1,t2,t3,t4,t5,t6);
678 }
679
680static void fftPass(Video::FFTComplex *z, const float *wre, unsigned int n) {
681 int o1 = 2*n;
682 int o2 = 4*n;
683 int o3 = 6*n;
684 const float *wim = wre+o1;
685 n--;
686
687 float t1, t2, t3, t4, t5, t6;
688 transformZero(z[0],z[o1],z[o2],z[o3], t1,t2,t3,t4,t5,t6);
689 transform(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1], t1,t2,t3,t4,t5,t6);
690 do {
691 z += 2;
692 wre += 2;
693 wim -= 2;
694 transform(z[0],z[o1],z[o2],z[o3],wre[0],wim[0], t1,t2,t3,t4,t5,t6);
695 transform(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1], t1,t2,t3,t4,t5,t6);
696 } while(--n);
697 }
698
699template<int n, int ord>
700static void fft(Video::FFTComplex *z) {
701 fft<n/2,ord-1>(z);
702 fft<n/4,ord-2>(z+(n/4)*2);
703 fft<n/4,ord-2>(z+(n/4)*3);
704 fftPass(z,ffCosTabs[ord].data(),(n/4)/2);
705 }
706
707template<>
709 float t1, t2, t3, t4, t5, t6, t7, t8;
710
711 BF(t3, t1, z[0].re, z[1].re);
712 BF(t8, t6, z[3].re, z[2].re);
713 BF(z[2].re, z[0].re, t1, t6);
714 BF(t4, t2, z[0].im, z[1].im);
715 BF(t7, t5, z[2].im, z[3].im);
716 BF(z[3].im, z[1].im, t4, t8);
717 BF(z[3].re, z[1].re, t3, t7);
718 BF(z[2].im, z[0].im, t2, t5);
719 }
720
721template<>
723 fft<4,2>(z);
724
725 float t1, t2, t3, t4, t5, t6;
726 BF(t1, z[5].re, z[4].re, -z[5].re);
727 BF(t2, z[5].im, z[4].im, -z[5].im);
728 BF(t5, z[7].re, z[6].re, -z[7].re);
729 BF(t6, z[7].im, z[6].im, -z[7].im);
730
731 BUTTERFLIES(z[0],z[2],z[4],z[6], t1,t2,t3,t4,t5,t6);
732 transform (z[1],z[3],z[5],z[7],sqrthalf,sqrthalf, t1,t2,t3,t4,t5,t6);
733 }
734
735template<>
737 float cos_16_1 = ffCosTabs[4][1];
738 float cos_16_3 = ffCosTabs[4][3];
739
740 fft<8,3>(z);
741 fft<4,2>(z+8);
742 fft<4,2>(z+12);
743
744 float t1, t2, t3, t4, t5, t6;
745 transformZero(z[0],z[4],z[8],z[12], t1,t2,t3,t4,t5,t6);
746 transform (z[2],z[6],z[10],z[14], sqrthalf,sqrthalf, t1,t2,t3,t4,t5,t6);
747 transform (z[1],z[5],z[9],z[13], cos_16_1,cos_16_3, t1,t2,t3,t4,t5,t6);
748 transform (z[3],z[7],z[11],z[15], cos_16_3,cos_16_1, t1,t2,t3,t4,t5,t6);
749 }
750
753
754 void skip(size_t n) {
755 if(at+n>bitCount)
756 throw std::runtime_error("io error");
757 at+=n;
758 }
759
760 float getFloat() {
761 int power = int(getBits(5));
762 float f = std::ldexp(float(getBits(23)), power - 23);
763 if(getBit())
764 return -f;
765 return f;
766 }
767
768 int getInt32(){
769 return int(getBits(32));
770 }
771
772 uint32_t getBit() {
773 if(at>=bitCount)
774 throw std::runtime_error("io error");
775 uint8_t d = data[at >> 3];
776 size_t mask = 1 << (at & 7);
777 at++;
778 return (d & mask) ? 1 : 0;
779 }
780
781 uint32_t getBits(int n) {
782 if(at+n>bitCount)
783 throw std::runtime_error("io error");
784 uint32_t v = fetch32();
785 at+=n;
786 return v & ((uint32_t(1)<<n)-1);
787 }
788
789 uint32_t showBits(int n) {
790 if(at>=bitCount)
791 throw std::runtime_error("io error");
792 uint32_t v = fetch32();
793 return v & ((uint32_t(1)<<n)-1);
794 }
795
796 uint32_t fetch32() {
797 size_t byteAt = at >> 3;
798 size_t offset = at & 7;
799
800 uint8_t buf[8]={};
801 for(size_t i=0; i<5; ++i) {
802 if(i+byteAt>=byteCount)
803 break;
804 buf[i] = data[byteAt+i];
805 }
806 uint64_t& v64 = *reinterpret_cast<uint64_t*>(buf);
807 v64 = v64 >> offset;
808 return uint32_t(v64 & uint32_t(-1));
809 }
810
811 size_t position() const { return at; }
812 size_t bitsLeft() const { return bitCount-at; };
813 void align32 () {
814 if(position() & 0x1F)
815 skip(32 - (position()&0x1F));
816 }
817
818 const uint8_t* data = nullptr;
819 size_t at = 0;
820 size_t bitCount = 0;
821 size_t byteCount = 0;
822 };
823
824Video::AudioCtx::AudioCtx(uint16_t sampleRate, uint8_t channels, bool isDct)
825 :sampleRate(sampleRate), channelsCnt(channels), isDct(isDct) {
826 }
827
828Video::Video(Input* file) : fin(file) {
829 packet.reserve(4*1024*1024);
830
831 uint32_t codec = rl32();
832 if(codec!=BINK_TAG)
833 throw std::runtime_error("invalid codec");
834
835 uint32_t file_size = rl32() + 8;
836 uint32_t duration = rl32();
837 if(rl32() > file_size)
838 throw std::runtime_error("invalid header: largest frame size greater than file size");
839 (void)rl32();
840
841 width = rl32();
842 height = rl32();
843
844 fRate.num = rl32();
845 fRate.den = rl32();
846 if(fRate.num==0 || fRate.den==0) {
847 char buf[256]={};
848 std::snprintf(buf, sizeof(buf), "invalid header: invalid fps (%d / %d)", fRate.num, fRate.den);
849 throw std::runtime_error(buf);
850 }
851
852 flags = BinkVidFlags(rl32());
853
854 uint32_t num_audio_tracks = rl32();
855
856 const uint32_t signature = (codec & 0xFFFFFF);
857 revision = uint8_t((codec >> 24) % 0xFF);
858
859 if((signature == AV_RL32("BIK") && (revision == 'k')) ||
860 (signature == AV_RL32("KB2") && (revision == 'i' || revision == 'j' || revision == 'k')))
861 (void)rl32(); // unknown new field
862
863 if(num_audio_tracks>0) {
864 // max decoded size
865 fin->skip(4*num_audio_tracks);
866
867 audProp.resize(num_audio_tracks);
868 for(uint32_t i=0; i<num_audio_tracks; i++) {
869 const uint16_t sampleRate = rl16();
870 const uint16_t flags = rl16();
871 aud.emplace_back(sampleRate,(flags & BINK_AUD_STEREO) ? 2 : 1,(flags & BINK_AUD_USEDCT));
872
873 audProp[i].sampleRate = uint16_t(aud[i].sampleRate);
874 audProp[i].isMono = (flags & BINK_AUD_STEREO)==0;
875 }
876
877 for(uint32_t i=0; i<num_audio_tracks; i++) {
878 auto audio_i_id = rl32();
879 (void)audio_i_id;
880 }
881 }
882
883 // frame index table
884 uint32_t next_pos = 0;
885 uint32_t pos = 0;
886 bool nextKeyframe = true;
887 bool keyframe = false;
888
889 next_pos = rl32();
890 for(uint32_t i = 0; i<duration; i++) {
891 pos = next_pos;
892 keyframe = nextKeyframe;
893 if(i+1==duration) {
894 next_pos = file_size;
895 nextKeyframe = false;
896 } else {
897 next_pos = rl32();
898 nextKeyframe = next_pos & 1;
899 }
900 pos &= ~1;
901 next_pos &= ~1;
902
903 if(next_pos <= pos)
904 throw std::runtime_error("invalid frame index table");
905
906 Index id;
907 id.pos = pos;
908 id.size = next_pos - pos;
909 id.keyFrame = keyframe;
910 index.push_back(id);
911 }
912
913 if(index.size()>0)
914 fin->seek(index[0].pos + smush_size); else
915 fin->skip(4);
916
917 decodeInit();
918
919 for(auto& i:aud)
920 decodeAudioInit(i);
921 for(auto& f:frames)
922 f.setAudioChannels(uint8_t(aud.size()));
923 }
924
927
929 if(frameCounter==index.size())
930 return frames[frameCounter%2];
931 try {
932 readPacket();
933 }
934 catch(const VideoDecodingException&) {
935 frameCounter++;
936 throw;
937 }
938 auto& f = frames[frameCounter%2];
939 frameCounter++;
940 return f;
941 }
942
943size_t Video::frameCount() const {
944 return index.size();
945 }
946
947uint32_t Video::rl32() {
948 uint32_t ret = 0;
949 fin->read(&ret,4);
950 return ret;
951 }
952
953uint16_t Video::rl16() {
954 uint16_t ret = 0;
955 fin->read(&ret,2);
956 return ret;
957 }
958
959void Video::readPacket() {
960 const Index& id = index[frameCounter];
961
962 fin->seek(id.pos+smush_size);
963
964 uint32_t videoSize = id.size;
965 for(size_t i=0; i<aud.size(); ++i) {
966 uint32_t audioSize = rl32();
967 if(audioSize+4 > videoSize) {
968 char buf[256] = {};
969 std::snprintf(buf,sizeof(buf),"audio size in header (%u) > size of packet left (%u)", audioSize, videoSize);
970 throw std::runtime_error(buf);
971 }
972 if(audioSize >= 4) { // This doesn't look good
973 packet.resize(audioSize);
974 fin->read(packet.data(),packet.size());
975 parseAudio(packet,i);
976 } else {
977 fin->skip(audioSize);
978 frames[frameCounter%2].aud[i].samples.clear();
979 }
980 videoSize -= (audioSize+4);
981 }
982
983 packet.resize(videoSize);
984 fin->read(packet.data(),packet.size());
985 parseFrame(packet);
986 }
987
988void Video::merge(BitStream& gb, uint8_t *dst, uint8_t *src, int size) {
989 uint8_t *src2 = src + size;
990 int size2 = size;
991
992 do {
993 if(!gb.getBit()) {
994 *dst++ = *src++;
995 size--;
996 } else {
997 *dst++ = *src2++;
998 size2--;
999 }
1000 } while(size && size2);
1001
1002 while (size--)
1003 *dst++ = *src++;
1004 while (size2--)
1005 *dst++ = *src2++;
1006 }
1007
1008void Video::decodeInit() {
1009 static int16_t table[16 * 128][2] = {
1010 {0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4}, {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}, {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}, {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}, {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}, {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}, {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}, {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},
1011 {0, 1}, {1, 4}, {0, 1}, {2, 5}, {0, 1}, {3, 5}, {0, 1}, {4, 5}, {0, 1}, {5, 5}, {0, 1}, {6, 5}, {0, 1}, {7, 5}, {0, 1}, {8, 5}, {0, 1}, {1, 4}, {0, 1}, {9, 5}, {0, 1}, {10, 5}, {0, 1}, {11, 5}, {0, 1}, {12, 5}, {0, 1}, {13, 5}, {0, 1}, {14, 5}, {0, 1}, {15, 5}, {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}, {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}, {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}, {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}, {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}, {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},
1012 {0, 2}, {2, 4}, {1, 2}, {8, 5}, {0, 2}, {4, 5}, {1, 2}, {12, 5}, {0, 2}, {3, 4}, {1, 2}, {10, 5}, {0, 2}, {6, 5}, {1, 2}, {14, 5}, {0, 2}, {2, 4}, {1, 2}, {9, 5}, {0, 2}, {5, 5}, {1, 2}, {13, 5}, {0, 2}, {3, 4}, {1, 2}, {11, 5}, {0, 2}, {7, 5}, {1, 2}, {15, 5}, {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}, {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}, {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}, {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}, {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}, {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},
1013 {0, 2}, {3, 4}, {1, 3}, {8, 5}, {0, 2}, {5, 4}, {2, 3}, {12, 5}, {0, 2}, {4, 4}, {1, 3}, {10, 5}, {0, 2}, {6, 5}, {2, 3}, {14, 5}, {0, 2}, {3, 4}, {1, 3}, {9, 5}, {0, 2}, {5, 4}, {2, 3}, {13, 5}, {0, 2}, {4, 4}, {1, 3}, {11, 5}, {0, 2}, {7, 5}, {2, 3}, {15, 5}, {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}, {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}, {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}, {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}, {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}, {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},
1014 {0, 3}, {4, 4}, {2, 3}, {8, 5}, {1, 3}, {6, 4}, {3, 3}, {12, 5}, {0, 3}, {5, 4}, {2, 3}, {10, 5}, {1, 3}, {7, 4}, {3, 3}, {14, 5}, {0, 3}, {4, 4}, {2, 3}, {9, 5}, {1, 3}, {6, 4}, {3, 3}, {13, 5}, {0, 3}, {5, 4}, {2, 3}, {11, 5}, {1, 3}, {7, 4}, {3, 3}, {15, 5}, {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}, {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}, {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}, {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}, {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}, {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},
1015 {0, 3}, {6, 4}, {2, 4}, {10, 4}, {1, 3}, {8, 4}, {4, 4}, {12, 5}, {0, 3}, {7, 4}, {3, 4}, {11, 4}, {1, 3}, {9, 4}, {5, 4}, {14, 5}, {0, 3}, {6, 4}, {2, 4}, {10, 4}, {1, 3}, {8, 4}, {4, 4}, {13, 5}, {0, 3}, {7, 4}, {3, 4}, {11, 4}, {1, 3}, {9, 4}, {5, 4}, {15, 5}, {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}, {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}, {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}, {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}, {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}, {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},
1016 {0, 2}, {5, 4}, {1, 4}, {9, 4}, {0, 2}, {7, 4}, {3, 4}, {12, 5}, {0, 2}, {6, 4}, {2, 4}, {10, 5}, {0, 2}, {8, 4}, {4, 4}, {14, 5}, {0, 2}, {5, 4}, {1, 4}, {9, 4}, {0, 2}, {7, 4}, {3, 4}, {13, 5}, {0, 2}, {6, 4}, {2, 4}, {11, 5}, {0, 2}, {8, 4}, {4, 4}, {15, 5}, {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}, {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}, {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}, {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}, {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}, {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},
1017 {0, 1}, {1, 3}, {0, 1}, {3, 5}, {0, 1}, {2, 3}, {0, 1}, {8, 6}, {0, 1}, {1, 3}, {0, 1}, {5, 5}, {0, 1}, {2, 3}, {0, 1}, {12, 6}, {0, 1}, {1, 3}, {0, 1}, {4, 5}, {0, 1}, {2, 3}, {0, 1}, {10, 6}, {0, 1}, {1, 3}, {0, 1}, {6, 6}, {0, 1}, {2, 3}, {0, 1}, {14, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 5}, {0, 1}, {2, 3}, {0, 1}, {9, 6}, {0, 1}, {1, 3}, {0, 1}, {5, 5}, {0, 1}, {2, 3}, {0, 1}, {13, 6}, {0, 1}, {1, 3}, {0, 1}, {4, 5}, {0, 1}, {2, 3}, {0, 1}, {11, 6}, {0, 1}, {1, 3}, {0, 1}, {7, 6}, {0, 1}, {2, 3}, {0, 1}, {15, 6}, {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}, {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}, {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}, {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},
1018 {0, 1}, {1, 2}, {0, 1}, {2, 5}, {0, 1}, {1, 2}, {0, 1}, {8, 6}, {0, 1}, {1, 2}, {0, 1}, {4, 6}, {0, 1}, {1, 2}, {0, 1}, {12, 6}, {0, 1}, {1, 2}, {0, 1}, {3, 5}, {0, 1}, {1, 2}, {0, 1}, {10, 6}, {0, 1}, {1, 2}, {0, 1}, {6, 6}, {0, 1}, {1, 2}, {0, 1}, {14, 6}, {0, 1}, {1, 2}, {0, 1}, {2, 5}, {0, 1}, {1, 2}, {0, 1}, {9, 6}, {0, 1}, {1, 2}, {0, 1}, {5, 6}, {0, 1}, {1, 2}, {0, 1}, {13, 6}, {0, 1}, {1, 2}, {0, 1}, {3, 5}, {0, 1}, {1, 2}, {0, 1}, {11, 6}, {0, 1}, {1, 2}, {0, 1}, {7, 6}, {0, 1}, {1, 2}, {0, 1}, {15, 6}, {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}, {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}, {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}, {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},
1019 {0, 1}, {1, 3}, {0, 1}, {4, 5}, {0, 1}, {2, 4}, {0, 1}, {8, 6}, {0, 1}, {1, 3}, {0, 1}, {6, 5}, {0, 1}, {3, 4}, {0, 1}, {12, 6}, {0, 1}, {1, 3}, {0, 1}, {5, 5}, {0, 1}, {2, 4}, {0, 1}, {10, 6}, {0, 1}, {1, 3}, {0, 1}, {7, 5}, {0, 1}, {3, 4}, {0, 1}, {14, 6}, {0, 1}, {1, 3}, {0, 1}, {4, 5}, {0, 1}, {2, 4}, {0, 1}, {9, 6}, {0, 1}, {1, 3}, {0, 1}, {6, 5}, {0, 1}, {3, 4}, {0, 1}, {13, 6}, {0, 1}, {1, 3}, {0, 1}, {5, 5}, {0, 1}, {2, 4}, {0, 1}, {11, 6}, {0, 1}, {1, 3}, {0, 1}, {7, 5}, {0, 1}, {3, 4}, {0, 1}, {15, 6}, {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}, {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}, {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}, {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},
1020 {0, 2}, {2, 3}, {1, 2}, {5, 5}, {0, 2}, {3, 4}, {1, 2}, {9, 5}, {0, 2}, {2, 3}, {1, 2}, {7, 5}, {0, 2}, {4, 4}, {1, 2}, {12, 6}, {0, 2}, {2, 3}, {1, 2}, {6, 5}, {0, 2}, {3, 4}, {1, 2}, {10, 6}, {0, 2}, {2, 3}, {1, 2}, {8, 5}, {0, 2}, {4, 4}, {1, 2}, {14, 6}, {0, 2}, {2, 3}, {1, 2}, {5, 5}, {0, 2}, {3, 4}, {1, 2}, {9, 5}, {0, 2}, {2, 3}, {1, 2}, {7, 5}, {0, 2}, {4, 4}, {1, 2}, {13, 6}, {0, 2}, {2, 3}, {1, 2}, {6, 5}, {0, 2}, {3, 4}, {1, 2}, {11, 6}, {0, 2}, {2, 3}, {1, 2}, {8, 5}, {0, 2}, {4, 4}, {1, 2}, {15, 6}, {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}, {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}, {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}, {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},
1021 {0, 1}, {1, 4}, {0, 1}, {5, 5}, {0, 1}, {3, 4}, {0, 1}, {9, 5}, {0, 1}, {2, 4}, {0, 1}, {7, 5}, {0, 1}, {4, 4}, {0, 1}, {12, 6}, {0, 1}, {1, 4}, {0, 1}, {6, 5}, {0, 1}, {3, 4}, {0, 1}, {10, 6}, {0, 1}, {2, 4}, {0, 1}, {8, 5}, {0, 1}, {4, 4}, {0, 1}, {14, 6}, {0, 1}, {1, 4}, {0, 1}, {5, 5}, {0, 1}, {3, 4}, {0, 1}, {9, 5}, {0, 1}, {2, 4}, {0, 1}, {7, 5}, {0, 1}, {4, 4}, {0, 1}, {13, 6}, {0, 1}, {1, 4}, {0, 1}, {6, 5}, {0, 1}, {3, 4}, {0, 1}, {11, 6}, {0, 1}, {2, 4}, {0, 1}, {8, 5}, {0, 1}, {4, 4}, {0, 1}, {15, 6}, {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}, {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}, {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}, {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},
1022 {0, 2}, {2, 2}, {1, 2}, {3, 5}, {0, 2}, {2, 2}, {1, 2}, {8, 6}, {0, 2}, {2, 2}, {1, 2}, {5, 5}, {0, 2}, {2, 2}, {1, 2}, {12, 6}, {0, 2}, {2, 2}, {1, 2}, {4, 5}, {0, 2}, {2, 2}, {1, 2}, {10, 6}, {0, 2}, {2, 2}, {1, 2}, {6, 6}, {0, 2}, {2, 2}, {1, 2}, {14, 6}, {0, 2}, {2, 2}, {1, 2}, {3, 5}, {0, 2}, {2, 2}, {1, 2}, {9, 6}, {0, 2}, {2, 2}, {1, 2}, {5, 5}, {0, 2}, {2, 2}, {1, 2}, {13, 6}, {0, 2}, {2, 2}, {1, 2}, {4, 5}, {0, 2}, {2, 2}, {1, 2}, {11, 6}, {0, 2}, {2, 2}, {1, 2}, {7, 6}, {0, 2}, {2, 2}, {1, 2}, {15, 6}, {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}, {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}, {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}, {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},
1023 {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {4, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {8, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {6, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {12, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {5, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {10, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {7, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {14, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {4, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {9, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {6, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {13, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {5, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {11, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {7, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {15, 7},
1024 {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {4, 5}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {8, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {5, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {12, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {4, 5}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {10, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {6, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {14, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {4, 5}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {9, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {5, 6}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {13, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {4, 5}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {11, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {7, 7}, {0, 1}, {1, 3}, {0, 1}, {3, 3}, {0, 1}, {2, 3}, {0, 1}, {15, 7},
1025 {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {5, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {9, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {7, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {12, 7}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {6, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {10, 7}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {8, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {14, 7}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {5, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {9, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {7, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {13, 7}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {6, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {11, 7}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {8, 6}, {0, 2}, {2, 3}, {1, 2}, {4, 3}, {0, 2}, {3, 3}, {1, 2}, {15, 7},
1026 };
1027
1028 swap_planes = (revision >= 'h');
1029 if(!bink_trees[15].table) {
1030 for(int i=0; i<16; i++) {
1031 const int maxbits = bink_tree_lens[i][15];
1032 bink_trees[i].table = table + i*128;
1033 bink_trees[i].table_allocated = 1 << maxbits;
1034 }
1035 }
1036 bink_trees[0].bits = 4;
1037 bink_trees[0].table_size = 16;
1038 bink_trees[1].bits = 5;
1039 bink_trees[1].table_size = 32;
1040 bink_trees[2].bits = 5;
1041 bink_trees[2].table_size = 32;
1042 bink_trees[3].bits = 5;
1043 bink_trees[3].table_size = 32;
1044 bink_trees[4].bits = 5;
1045 bink_trees[4].table_size = 32;
1046 bink_trees[5].bits = 5;
1047 bink_trees[5].table_size = 32;
1048 bink_trees[6].bits = 5;
1049 bink_trees[6].table_size = 32;
1050 bink_trees[7].bits = 6;
1051 bink_trees[7].table_size = 64;
1052 bink_trees[8].bits = 6;
1053 bink_trees[8].table_size = 64;
1054 bink_trees[9].bits = 6;
1055 bink_trees[9].table_size = 64;
1056 bink_trees[10].bits = 6;
1057 bink_trees[10].table_size = 64;
1058 bink_trees[11].bits = 6;
1059 bink_trees[11].table_size = 64;
1060 bink_trees[12].bits = 6;
1061 bink_trees[12].table_size = 64;
1062 bink_trees[13].bits = 7;
1063 bink_trees[13].table_size = 128;
1064 bink_trees[14].bits = 7;
1065 bink_trees[14].table_size = 128;
1066 bink_trees[15].bits = 7;
1067 bink_trees[15].table_size = 128;
1068
1069 for(auto& i:frames)
1070 i.setSize(width,height);
1071
1072 const int bw = (width + 7) >> 3;
1073 const int bh = (height + 7) >> 3;
1074 const int blocks = bw * bh;
1075 for(auto& b:bundle) {
1076 b.data.resize(blocks * 64);
1077 b.data_end = b.data.data() + blocks * 64;
1078 }
1079
1080/*
1081 if(revision == 'b') {
1082 static int binkb_initialised = 0;
1083 if(!binkb_initialised) {
1084 binkb_calc_quant();
1085 binkb_initialised = 1;
1086 }
1087 }
1088 */
1089 }
1090
1091int Video::setIdx(BitStream& gb, int code, int& n, int& nb_bits, const int16_t (*table)[2]) {
1092 unsigned idx;
1093
1094 nb_bits = -n;
1095 idx = gb.showBits(nb_bits) + code;
1096 n = table[idx][1];
1097
1098 return table[idx][0];
1099 }
1100
1101int Video::getVlc2(BitStream& gb, int16_t (*table)[2], int bits, int max_depth) {
1102 unsigned idx = gb.showBits(bits);
1103 int code = table[idx][0];
1104 int n = table[idx][1];
1105
1106 int nb_bits=0;
1107
1108 if(max_depth>1 && n<0) {
1109 gb.skip(bits);
1110 code = setIdx(gb, code, n, nb_bits, table);
1111 if(max_depth > 2 && n < 0) {
1112 gb.skip(nb_bits);
1113 code = setIdx(gb, code, n, nb_bits, table);
1114 }
1115 }
1116 gb.skip(n);
1117 return code;
1118 }
1119
1120uint8_t Video::getHuff(BitStream& gb, const Tree& tree) {
1121 int vlc = getVlc2(gb, bink_trees[tree.vlc_num].table, bink_trees[tree.vlc_num].bits, 1);
1122 return tree.syms[vlc];
1123 }
1124
1125void Video::initLengths(int width, int bw) {
1126 width = ((width+7)/8)*8;
1127
1128 bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1;
1129 bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1;
1130 bundle[BINK_SRC_COLORS].len = av_log2(bw*64 + 511) + 1;
1131 bundle[BINK_SRC_INTRA_DC].len =
1132 bundle[BINK_SRC_INTER_DC].len =
1133 bundle[BINK_SRC_X_OFF].len =
1134 bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1;
1135
1136 bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1;
1137 bundle[BINK_SRC_RUN].len = av_log2(bw*48 + 511) + 1;
1138 }
1139
1140void Video::parseFrame(const std::vector<uint8_t>& data) {
1141 const bool swap_planes = (revision >= 'h');
1142 const size_t bits_count = data.size()<<3;
1143
1144 BitStream gb(data.data(),bits_count);
1145
1146 if((flags&BINK_FLAG_ALPHA) == BINK_FLAG_ALPHA) {
1147 if(revision >= 'i')
1148 gb.skip(32);
1149 decodePlane(gb,3,false);
1150 }
1151 if(revision >= 'i')
1152 gb.skip(32);
1153
1154 for(int plane=0; plane<3; plane++) {
1155 const int planeId = (!plane || !swap_planes) ? plane : (plane ^ 3);
1156
1157 if(revision>'b') {
1158 decodePlane(gb, planeId, plane!=0);
1159 } else {
1160 //decodePlaneB(gb, planeId, frameCounter==0, plane!=0);
1161 throw std::runtime_error("not implemented");
1162 }
1163
1164 if(gb.position()>=bits_count)
1165 break;
1166 }
1167 }
1168
1169void Video::decodePlane(BitStream& gb, int planeId, bool chroma) {
1170 const int bw = chroma ? (this->width + 15) >> 4 : (this->width + 7) >> 3;
1171 const int bh = chroma ? (this->height + 15) >> 4 : (this->height + 7) >> 3;
1172 const int width = this->width >> (chroma ? 1 : 0);
1173
1174 auto& plane = frames[frameCounter%2] .planes[planeId];
1175 auto& last = frames[(frameCounter+1)%2].planes[planeId];
1176
1177 if(revision == 'k' && gb.getBit()) {
1178 uint8_t value = uint8_t(gb.getBits(8));
1179 plane.fill(value);
1180 //next plane data starts at 32-bit boundary
1181 gb.align32();
1182 return;
1183 }
1184
1185 initLengths(std::max(width,8),bw);
1186 for(int i=0; i<BINK_NB_SRC; i++)
1187 readBundle(gb,i);
1188
1189 uint8_t dst[8*8] = {};
1190 for(int by = 0; by < bh; by++) {
1191 readBlockTypes (gb,bundle[BINK_SRC_BLOCK_TYPES]);
1192 readBlockTypes (gb,bundle[BINK_SRC_SUB_BLOCK_TYPES]);
1193 readColors (gb,bundle[BINK_SRC_COLORS]);
1194 readPatterns (gb,bundle[BINK_SRC_PATTERN]);
1195 readMotionValues(gb,bundle[BINK_SRC_X_OFF]);
1196 readMotionValues(gb,bundle[BINK_SRC_Y_OFF]);
1197 readDcs (gb,bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0);
1198 readDcs (gb,bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1);
1199 readRuns (gb,bundle[BINK_SRC_RUN]);
1200
1201 for(int bx=0; bx<bw; ++bx) {
1202 BlockTypes blk = BlockTypes(getValue(BINK_SRC_BLOCK_TYPES));
1203 // 16x16 block type on odd line means part of the already decoded block, so skip it
1204 if((by & 1) && blk == SCALED_BLOCK) {
1205 bx++;
1206 continue;
1207 }
1208
1209 bool isScaled = false;
1210 if(blk==SCALED_BLOCK){
1211 blk = BlockTypes(getValue(BINK_SRC_SUB_BLOCK_TYPES));
1212 isScaled = true;
1213 }
1214
1215 switch(blk) {
1216 case SCALED_BLOCK:
1217 throw VideoDecodingException("unsupported type of superblock");
1218 case SKIP_BLOCK:
1219 last.getBlock8x8(bx,by,dst);
1220 break;
1221 case FILL_BLOCK: {
1222 const uint8_t v = uint8_t(getValue(BINK_SRC_COLORS));
1223 std::memset(dst,v,sizeof(dst));
1224 break;
1225 }
1226 case RESIDUE_BLOCK: {
1227 uint8_t prev[8*8] = {};
1228 const int xoff = getValue(BINK_SRC_X_OFF);
1229 const int yoff = getValue(BINK_SRC_Y_OFF);
1230 last.getPixels8x8(bx*8+xoff, by*8+yoff, prev);
1231
1232 int16_t block[64] = {};
1233 int v = gb.getBits(7);
1234 readResidue(gb,block,v);
1235 for(int i=0; i<64; ++i)
1236 dst[i] = uint8_t(prev[i]+block[i]);
1237 break;
1238 }
1239 case INTRA_BLOCK: {
1240 int32_t dctblock[64] = {};
1241 dctblock[0] = getValue(BINK_SRC_INTRA_DC);
1242 int coef_count=0, coef_idx[64]={};
1243 int quant_idx = readDctCoeffs(gb, dctblock, bink_scan, coef_count, coef_idx, -1);
1244 unquantizeDctCoeffs(dctblock, bink_intra_quant[quant_idx], coef_count, coef_idx, bink_scan);
1245 int temp[64]={};
1246 for(int i=0; i<8; i++)
1247 bink_idct_col(&temp[i], &dctblock[i]);
1248 for(int i=0; i<8; i++)
1249 idctRow(&dst[i*8], &temp[8*i]);
1250 break;
1251 }
1252 case INTER_BLOCK: {
1253 uint8_t prev[8*8] = {};
1254 const int xoff = getValue(BINK_SRC_X_OFF);
1255 const int yoff = getValue(BINK_SRC_Y_OFF);
1256 last.getPixels8x8(bx*8+xoff, by*8+yoff, prev);
1257
1258 int32_t dctblock[64] = {};
1259 dctblock[0] = getValue(BINK_SRC_INTER_DC);
1260 int coef_count=0, coef_idx[64]={};
1261 int quant_idx = readDctCoeffs(gb, dctblock, bink_scan, coef_count, coef_idx, -1);
1262 unquantizeDctCoeffs(dctblock, bink_inter_quant[quant_idx], coef_count, coef_idx, bink_scan);
1263
1264 int temp[64]={};
1265 for(int i=0; i<8; i++)
1266 bink_idct_col(&temp[i], &dctblock[i]);
1267 for(int i = 0; i < 8; i++)
1268 idctRow(&dctblock[i*8], &temp[8*i]);
1269 for(int i=0; i<64; ++i)
1270 dst[i] = uint8_t(prev[i]+dctblock[i]);
1271 break;
1272 }
1273 case RUN_BLOCK: {
1274 const uint8_t* scan = bink_patterns[gb.getBits(4)];
1275 int i = 0;
1276 do {
1277 const int run = getValue(BINK_SRC_RUN) + 1;
1278 i += run;
1279 if(i > 64)
1280 throw VideoDecodingException("Run went out of bounds");
1281 if(gb.getBit()) {
1282 int v = getValue(BINK_SRC_COLORS);
1283 for(int j = 0; j < run; j++)
1284 dst[*scan++] = uint8_t(v);
1285 } else {
1286 for(int j = 0; j < run; j++)
1287 dst[*scan++] = uint8_t(getValue(BINK_SRC_COLORS));
1288 }
1289 } while (i < 63);
1290 if(i == 63)
1291 dst[*scan++] = uint8_t(getValue(BINK_SRC_COLORS));
1292 break;
1293 }
1294 case MOTION_BLOCK: {
1295 if(isScaled)
1296 throw VideoDecodingException("unsupported type of superblock");
1297 const int xoff = getValue(BINK_SRC_X_OFF);
1298 const int yoff = getValue(BINK_SRC_Y_OFF);
1299 last.getPixels8x8(bx*8+xoff, by*8+yoff, dst);
1300 break;
1301 }
1302 case PATTERN_BLOCK: {
1303 uint8_t col[2] = {};
1304 for(int i=0; i<2; i++)
1305 col[i] = uint8_t(getValue(BINK_SRC_COLORS));
1306 for(int i=0; i<8; i++) {
1307 int v = getValue(BINK_SRC_PATTERN);
1308 for(int j=0; j<8; j++, v >>= 1)
1309 dst[i*8+j] = col[v & 1];
1310 }
1311 break;
1312 }
1313 case RAW_BLOCK: {
1314 std::memcpy(dst,bundle[BINK_SRC_COLORS].cur_ptr,64);
1315 bundle[BINK_SRC_COLORS].cur_ptr += 64;
1316 break;
1317 }
1318 default:
1319 throw VideoDecodingException("not implemented block type");
1320 }
1321
1322 if(isScaled) {
1323 plane.putScaledBlock(bx,by,dst);
1324 bx++;
1325 } else {
1326 plane.putBlock8x8(bx,by,dst);
1327 }
1328 }
1329 }
1330
1331 //next plane data starts at 32-bit boundary
1332 gb.align32();
1333 }
1334
1335void Video::readBundle(BitStream& gb, int bundle_num) {
1336 if(bundle_num == BINK_SRC_COLORS) {
1337 for(int i=0; i<16; i++)
1338 readTree(gb, col_high[i]);
1339 col_lastval = 0;
1340 }
1341
1342 if(bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC)
1343 readTree(gb, bundle[bundle_num].tree);
1344
1345 bundle[bundle_num].cur_dec =
1346 bundle[bundle_num].cur_ptr = bundle[bundle_num].data.data();
1347 }
1348
1349void Video::readTree(BitStream& gb, Tree& tree) {
1350 uint8_t tmp1[16] = {}, tmp2[16] = {}, *in = tmp1, *out = tmp2;
1351
1352 tree.vlc_num = gb.getBits(4);
1353 if(0==tree.vlc_num) {
1354 for(uint8_t i=0; i<16; i++)
1355 tree.syms[i] = i;
1356 return;
1357 }
1358
1359 if(gb.getBit()) {
1360 uint32_t len = gb.getBits(3);
1361 for(uint32_t i=0; i<=len; i++) {
1362 tree.syms[i] = uint8_t(gb.getBits(4));
1363 tmp1[tree.syms[i]] = 1;
1364 }
1365 for(uint8_t i=0; i<16 && len<16-1; i++)
1366 if(!tmp1[i])
1367 tree.syms[++len] = i;
1368 } else {
1369 uint32_t len = gb.getBits(2);
1370 for(uint32_t i=0; i<16; i++)
1371 in[i] = uint8_t(i);
1372 for(uint32_t i=0; i<=len; i++) {
1373 int size = 1 << i;
1374 for(int t=0; t<16; t+=(size<<1))
1375 merge(gb, out + t, in + t, size);
1376 std::swap(in, out);
1377 }
1378 std::memcpy(tree.syms, in, 16);
1379 }
1380 }
1381
1382template<class T>
1383bool Video::checkReadVal(BitStream& gb, Bundle& b, T& t){
1384 if(b.cur_dec==nullptr || (b.cur_dec>b.cur_ptr))
1385 return false;
1386 t = gb.getBits(b.len);
1387 if(t==0){
1388 b.cur_dec = nullptr;
1389 return false;
1390 }
1391 return true;
1392 }
1393
1394void Video::readBlockTypes(BitStream& gb, Bundle& b) {
1395 uint32_t t = 0; //520
1396 int v = 0;
1397 int last = 0;
1398 const uint8_t* dec_end;
1399
1400 if(!checkReadVal(gb,b,t))
1401 return;
1402
1403 if(revision == 'k') {
1404 t ^= 0xBBu;
1405 if(t==0) {
1406 b.cur_dec = nullptr;
1407 return;
1408 }
1409 }
1410 dec_end = b.cur_dec + t;
1411 if(dec_end > b.data_end)
1412 throw VideoDecodingException("Too many block type values");
1413
1414 if(gb.getBit()) {
1415 v = gb.getBits(4);
1416 std::memset(b.cur_dec, v, t);
1417 b.cur_dec += t;
1418 } else {
1419 while(b.cur_dec < dec_end) {
1420 v = getHuff(gb, b.tree);
1421 if(v < 12) {
1422 last = v;
1423 *b.cur_dec++ = uint8_t(v);
1424 } else {
1425 int run = bink_rlelens[v - 12];
1426
1427 if(dec_end - b.cur_dec < run)
1428 throw VideoDecodingException("decoding block error");
1429 std::memset(b.cur_dec, last, run);
1430 b.cur_dec += run;
1431 }
1432 }
1433 }
1434 }
1435
1436void Video::readColors(BitStream& gb, Bundle& b) {
1437 int t=0, sign=0, v=0;
1438 const uint8_t *dec_end = nullptr;
1439
1440 if(!checkReadVal(gb,b,t))
1441 return;
1442
1443 dec_end = b.cur_dec + t;
1444 if(dec_end>b.data_end)
1445 throw VideoDecodingException("Too many color values");
1446
1447 if(gb.getBit()) {
1448 col_lastval = getHuff(gb, col_high[col_lastval]);
1449 v = getHuff(gb, b.tree);
1450 v = (col_lastval << 4) | v;
1451 if(revision<'i') {
1452 sign = ((int8_t) v) >> 7;
1453 v = ((v & 0x7F) ^ sign) - sign;
1454 v += 0x80;
1455 }
1456 std::memset(b.cur_dec, v, t);
1457 b.cur_dec += t;
1458 } else {
1459 while(b.cur_dec<dec_end) {
1460 col_lastval = getHuff(gb, col_high[col_lastval]);
1461 v = getHuff(gb, b.tree);
1462 v = (col_lastval << 4) | v;
1463 if(revision<'i') {
1464 sign = ((int8_t) v) >> 7;
1465 v = ((v & 0x7F) ^ sign) - sign;
1466 v += 0x80;
1467 }
1468 *b.cur_dec++ = uint8_t(v);
1469 }
1470 }
1471 }
1472
1473void Video::readPatterns(BitStream& gb, Bundle& b) { // note: not tested
1474 int t = 0, v = 0;
1475 const uint8_t *dec_end = nullptr;
1476
1477 if(!checkReadVal(gb,b,t))
1478 return;
1479 dec_end = b.cur_dec + t;
1480 if(dec_end>b.data_end)
1481 throw VideoDecodingException("Too many pattern values");
1482
1483 while(b.cur_dec < dec_end) {
1484 v = getHuff(gb, b.tree);
1485 v |= getHuff(gb, b.tree) << 4;
1486 *b.cur_dec++ = uint8_t(v);
1487 }
1488 }
1489
1490void Video::readMotionValues(BitStream& gb, Bundle& b) { // note: not tested
1491 int t = 0, sign = 0, v = 0;
1492 const uint8_t *dec_end = nullptr;
1493
1494 if(!checkReadVal(gb,b,t))
1495 return;
1496 dec_end = b.cur_dec + t;
1497 if(dec_end>b.data_end)
1498 throw VideoDecodingException("Too many motion values");
1499 if (gb.getBit()) {
1500 v = gb.getBits(4);
1501 if(v) {
1502 sign = -int(gb.getBit());
1503 v = (v ^ sign) - sign;
1504 }
1505 std::memset(b.cur_dec, v, t);
1506 b.cur_dec += t;
1507 } else {
1508 while(b.cur_dec < dec_end) {
1509 v = getHuff(gb, b.tree);
1510 if(v) {
1511 sign = -int(gb.getBit());
1512 v = (v ^ sign) - sign;
1513 }
1514 *b.cur_dec++ = uint8_t(v);
1515 }
1516 }
1517 }
1518
1519void Video::readDcs(BitStream& gb, Bundle& b, int start_bits, int has_sign) {
1520 int len = 0, sign = 0, v, v2;
1521 int16_t *dst = reinterpret_cast<int16_t*>(b.cur_dec);
1522 int16_t *dst_end = reinterpret_cast<int16_t*>(b.data_end);
1523
1524 if(!checkReadVal(gb,b,len))
1525 return;
1526 v = gb.getBits(start_bits - has_sign);
1527 if(v && has_sign) {
1528 sign = -int(gb.getBit());
1529 v = (v ^ sign) - sign;
1530 }
1531 if(dst_end - dst < 1)
1532 throw std::runtime_error("io error");
1533 *dst++ = int16_t(v);
1534 len--;
1535 for(int i = 0; i < len; i += 8) {
1536 const int len2 = std::min(len - i, 8);
1537 if(dst_end - dst < len2)
1538 throw std::runtime_error("io error");
1539 uint32_t bsize = gb.getBits(4);
1540 if(bsize>0) {
1541 for(int j = 0; j < len2; j++) {
1542 v2 = gb.getBits(bsize);
1543 if(v2!=0) {
1544 sign = -int(gb.getBit());
1545 v2 = (v2 ^ sign) - sign;
1546 }
1547 v += v2;
1548 *dst++ = int16_t(v);
1549 if(v < -32768 || v > 32767) {
1550 char buf[128]={};
1551 std::snprintf(buf,sizeof(buf),"DC value went out of bounds: %d", v);
1552 throw VideoDecodingException(buf);
1553 }
1554 }
1555 } else {
1556 for(int j = 0; j < len2; j++)
1557 *dst++ = int16_t(v);
1558 }
1559 }
1560
1561 b.cur_dec = reinterpret_cast<uint8_t*>(dst);
1562 }
1563
1564void Video::readRuns(BitStream& gb, Bundle& b) {
1565 int t, v;
1566 const uint8_t *dec_end;
1567
1568 if(!checkReadVal(gb,b,t))
1569 return;
1570
1571 dec_end = b.cur_dec + t;
1572 if(dec_end > b.data_end)
1573 throw VideoDecodingException("Run value went out of bounds\n");
1574 if(gb.getBit()) {
1575 v = gb.getBits(4);
1576 std::memset(b.cur_dec, v, t);
1577 b.cur_dec += t;
1578 } else {
1579 while (b.cur_dec < dec_end)
1580 *b.cur_dec++ = getHuff(gb, b.tree);
1581 }
1582 }
1583
1584int Video::getValue(Sources b) {
1585 if(b<BINK_SRC_X_OFF || b==BINK_SRC_RUN)
1586 return *bundle[int(b)].cur_ptr++;
1587 if(b==BINK_SRC_X_OFF || b==BINK_SRC_Y_OFF)
1588 return *reinterpret_cast<int8_t*&>(bundle[b].cur_ptr)++;
1589 int16_t ret = *reinterpret_cast<int16_t*&>(bundle[b].cur_ptr);
1590 bundle[b].cur_ptr += 2;
1591 return ret;
1592 }
1593
1594int Video::readDctCoeffs(BitStream& gb, int32_t block[],
1595 const uint8_t *scan, int& coef_count,
1596 int coef_idx[], int q) {
1597 int coef_list[128] = {};
1598 int mode_list[128] = {};
1599 int t, ccoef, mode, sign;
1600 int list_start = 64, list_end = 64;
1601
1602 coef_count = 0;
1603
1604 coef_list[list_end] = 4; mode_list[list_end++] = 0;
1605 coef_list[list_end] = 24; mode_list[list_end++] = 0;
1606 coef_list[list_end] = 44; mode_list[list_end++] = 0;
1607 coef_list[list_end] = 1; mode_list[list_end++] = 3;
1608 coef_list[list_end] = 2; mode_list[list_end++] = 3;
1609 coef_list[list_end] = 3; mode_list[list_end++] = 3;
1610
1611 for(int bits = int(gb.getBits(4))-1; bits >= 0; bits--) {
1612 int list_pos = list_start;
1613 while(list_pos < list_end) {
1614 if (!(mode_list[list_pos] | coef_list[list_pos]) || !gb.getBit()) {
1615 list_pos++;
1616 continue;
1617 }
1618 ccoef = coef_list[list_pos];
1619 mode = mode_list[list_pos];
1620 switch (mode) {
1621 case 0:
1622 coef_list[list_pos] = ccoef + 4;
1623 mode_list[list_pos] = 1;
1624 case 2:
1625 if (mode == 2) {
1626 coef_list[list_pos] = 0;
1627 mode_list[list_pos++] = 0;
1628 }
1629 for(int i = 0; i < 4; i++, ccoef++) {
1630 if(gb.getBit()) {
1631 coef_list[--list_start] = ccoef;
1632 mode_list[ list_start] = 3;
1633 } else {
1634 if (!bits) {
1635 t = 1 - int(gb.getBit() << 1);
1636 } else {
1637 t = gb.getBits(bits) | 1 << bits;
1638 sign = -int(gb.getBit());
1639 t = (t ^ sign) - sign;
1640 }
1641 block[scan[ccoef]] = t;
1642 coef_idx[coef_count++] = ccoef;
1643 }
1644 }
1645 break;
1646 case 1:
1647 mode_list[list_pos] = 2;
1648 for(int i = 0; i < 3; i++) {
1649 ccoef += 4;
1650 coef_list[list_end] = ccoef;
1651 mode_list[list_end++] = 2;
1652 }
1653 break;
1654 case 3:
1655 if(!bits) {
1656 t = 1 - int(gb.getBit() << 1);
1657 } else {
1658 t = gb.getBits(bits) | 1 << bits;
1659 sign = -int(gb.getBit());
1660 t = (t ^ sign) - sign;
1661 }
1662 block[scan[ccoef]] = t;
1663 coef_idx[coef_count++] = ccoef;
1664 coef_list[list_pos] = 0;
1665 mode_list[list_pos++] = 0;
1666 break;
1667 }
1668 }
1669 }
1670
1671 uint32_t quant_idx=0;
1672 if(q == -1) {
1673 quant_idx = gb.getBits(4);
1674 } else {
1675 quant_idx = q;
1676 if(quant_idx > 15U) {
1677 char buf[128]={};
1678 std::snprintf(buf,sizeof(buf),"quant_index %d out of range\n", quant_idx);
1679 throw SoundDecodingException(buf);
1680 }
1681 }
1682 return quant_idx;
1683 }
1684
1685
1686void Video::unquantizeDctCoeffs(int32_t block[], const uint32_t quant[],
1687 int coef_count, int coef_idx[],
1688 const uint8_t *scan) {
1689 block[0] = int(block[0] * quant[0]) >> 11;
1690 for(int i = 0; i < coef_count; i++) {
1691 int idx = coef_idx[i];
1692 block[scan[idx]] = int(block[scan[idx]] * quant[idx]) >> 11;
1693 }
1694 }
1695
1696void Video::readResidue(BitStream& gb, int16_t block[], int masks_count) {
1697 int coef_list[128];
1698 int mode_list[128];
1699 int sign;
1700 int list_start = 64, list_end = 64;
1701 int nz_coeff[64];
1702 int nz_coeff_count = 0;
1703
1704 coef_list[list_end] = 4; mode_list[list_end++] = 0;
1705 coef_list[list_end] = 24; mode_list[list_end++] = 0;
1706 coef_list[list_end] = 44; mode_list[list_end++] = 0;
1707 coef_list[list_end] = 0; mode_list[list_end++] = 2;
1708
1709 for(int mask = 1 << gb.getBits(3); mask; mask >>= 1) {
1710 for(int i = 0; i<nz_coeff_count; i++) {
1711 if(!gb.getBit())
1712 continue;
1713 if(block[nz_coeff[i]] < 0)
1714 block[nz_coeff[i]] = int16_t(block[nz_coeff[i]] - mask);
1715 else
1716 block[nz_coeff[i]] = int16_t(block[nz_coeff[i]] + mask);
1717 masks_count--;
1718 if(masks_count<0)
1719 return;
1720 }
1721 int list_pos = list_start;
1722 while(list_pos < list_end) {
1723 if(!(coef_list[list_pos] | mode_list[list_pos]) || !gb.getBit()) {
1724 list_pos++;
1725 continue;
1726 }
1727 int ccoef = coef_list[list_pos];
1728 int mode = mode_list[list_pos];
1729 switch (mode) {
1730 case 0:
1731 coef_list[list_pos] = ccoef + 4;
1732 mode_list[list_pos] = 1;
1733 case 2:
1734 if (mode == 2) {
1735 coef_list[list_pos] = 0;
1736 mode_list[list_pos++] = 0;
1737 }
1738 for(int i = 0; i < 4; i++, ccoef++) {
1739 if(gb.getBit()) {
1740 coef_list[--list_start] = ccoef;
1741 mode_list[ list_start] = 3;
1742 } else {
1743 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
1744 sign = -int(gb.getBit());
1745 block[bink_scan[ccoef]] = int16_t((mask ^ sign) - sign);
1746 masks_count--;
1747 if(masks_count<0)
1748 return;
1749 }
1750 }
1751 break;
1752 case 1:
1753 mode_list[list_pos] = 2;
1754 for(int i=0; i<3; i++) {
1755 ccoef += 4;
1756 coef_list[list_end] = ccoef;
1757 mode_list[list_end++] = 2;
1758 }
1759 break;
1760 case 3:
1761 nz_coeff[nz_coeff_count++] = bink_scan[ccoef];
1762 sign = -int(gb.getBit());
1763 block[bink_scan[ccoef]] = int16_t((mask ^ sign) - sign);
1764 coef_list[list_pos] = 0;
1765 mode_list[list_pos++] = 0;
1766 masks_count--;
1767 if (masks_count < 0)
1768 return;
1769 break;
1770 }
1771 }
1772 }
1773 }
1774
1775
1776static int splitRadixPermutation(int i, int n, int inverse) {
1777 if(n <= 2)
1778 return i&1;
1779 int m = n >> 1;
1780 if(!(i&m))
1781 return splitRadixPermutation(i, m, inverse)*2;
1782 m >>= 1;
1783 if(inverse == !(i&m))
1784 return splitRadixPermutation(i, m, inverse)*4 + 1;
1785 return splitRadixPermutation(i, m, inverse)*4 - 1;
1786 }
1787
1788template<class T>
1789static void processFftPerm(T* revtab, int n, bool inverse){
1790 for(int i = 0; i < n; i++) {
1791 int k = -splitRadixPermutation(i, n, inverse) & (n - 1);
1792 revtab[k] = T(i);
1793 }
1794 }
1795
1796void Video::decodeAudioInit(AudioCtx& aud) {
1797 int frame_len_bits;
1798 // determine frame length
1799 if(aud.sampleRate < 22050)
1800 frame_len_bits = 9; else
1801 if(aud.sampleRate < 44100)
1802 frame_len_bits = 10; else
1803 frame_len_bits = 11;
1804
1805 if(aud.channelsCnt < 1 || aud.channelsCnt > 2) {
1806 char buf[128] = {};
1807 std::snprintf(buf,sizeof(buf),"invalid number of channels: %d\n", aud.channelsCnt);
1808 throw std::runtime_error(buf);
1809 }
1810
1811 if(!aud.isDct) {
1812 // audio is already interleaved for the RDFT format variant
1813 if(aud.sampleRate > uint32_t(std::numeric_limits<int32_t>::max())/aud.channelsCnt)
1814 throw std::runtime_error("too many audio samples");
1815 aud.sampleRate *= aud.channelsCnt;
1816 if(revision!='b')
1817 frame_len_bits += av_log2(aud.channelsCnt);
1818 aud.channelsCnt = 1;
1819 } else {
1820 // NOP
1821 }
1822
1823 aud.frameLen = 1 << frame_len_bits;
1824 aud.overlapLen = aud.frameLen / 16;
1825 aud.nbits = frame_len_bits;
1826 const uint32_t sample_rate_half = (aud.sampleRate + 1) / 2;
1827
1828 if(!aud.isDct)
1829 aud.root = 2.f /float(std::sqrt(aud.frameLen)*32768.0); else
1830 aud.root = float(aud.frameLen)/float(std::sqrt(aud.frameLen)*32768.0);
1831 for(int i=0; i<96; i++) {
1832 // constant is result of 0.066399999/log10(M_E)
1833 quantTable[i] = std::exp(float(i) * 0.15289164787221953823f)*aud.root;
1834 }
1835
1836 // calculate number of bands
1837 uint32_t numBands = 0;
1838 for(numBands = 1; numBands < 25; numBands++)
1839 if(sample_rate_half<=ff_wma_critical_freqs[numBands - 1])
1840 break;
1841 aud.numBands = numBands;
1842
1843 // populate bands data
1844 aud.bands[0] = 2;
1845 for(uint32_t i=1; i<numBands; i++)
1846 aud.bands[i] = (ff_wma_critical_freqs[i-1] * aud.frameLen / sample_rate_half) & ~1;
1847 aud.bands[numBands] = aud.frameLen;
1848
1849 initFfCosTabs(aud.nbits);
1850 aud.tcos = ffCosTabs[aud.nbits].data();
1851 aud.tsin = ffCosTabs[aud.nbits].data() + ((1<<aud.nbits) >> 2);
1852
1853 const int fftNBits = aud.nbits-1;
1854 aud.tmpBuf.resize(1 << fftNBits);
1855
1856 aud.revtab .resize(1<<fftNBits);
1857 aud.revtab32.resize(1<<fftNBits);
1858 processFftPerm(aud.revtab.data(), 1<<fftNBits, aud.isDct);
1859 processFftPerm(aud.revtab32.data(),32, aud.isDct);
1860
1861 int n = 1 << fftNBits;
1862 initFfCosTabs(aud.nbits+2);
1863 aud.csc2.resize(n);
1864 for(int i = 0; i<n; i++)
1865 aud.csc2[i] = 0.5f/std::sin((float(M_PI)/float(4*n) * float(2*i+1)));
1866
1867 for(int i=0; i<18; ++i)
1868 initFfCosTabs(i);
1869 }
1870
1871void Video::initFfCosTabs(size_t index) {
1872 size_t m = 1<<index;
1873 double freq = 2*M_PI/double(m);
1874 auto& tab = ffCosTabs[index];
1875
1876 if(tab.size()!=0)
1877 return;
1878 tab.resize(m);
1879
1880 for(size_t i=0; i<=m/4; i++)
1881 tab[i] = std::cos(float(double(i)*freq));
1882 for(size_t i=1; i<m/4; i++)
1883 tab[m/2-i] = tab[i];
1884 }
1885
1886void Video::parseAudio(const std::vector<uint8_t>& data, size_t id) {
1887 BitStream gb(data.data(),data.size()*8);
1888 gb.skip(32); // skip reported size
1889
1890 auto& aud = this->aud[id];
1891 auto& ret = frames[frameCounter%2].aud[id].samples;
1892 ret.reserve(ret.capacity());
1893 ret.clear();
1894
1895 while(true) {
1896 parseAudioBlock(gb,aud);
1897
1898 if(aud.channelsCnt==1) {
1899 auto& smp = aud.samples[0];
1900 size_t size = aud.frameLen - aud.overlapLen;
1901 ret.resize(ret.size()+size);
1902 std::memcpy(ret.data()+ret.size()-size,smp.data(),size*sizeof(smp[0]));
1903 } else {
1904 auto smp0 = aud.samples[0].data();
1905 auto smp1 = aud.samples[1].data();
1906
1907 size_t size = aud.frameLen - aud.overlapLen;
1908 ret.resize(ret.size()+2*size);
1909
1910 float* s = ret.data()+ret.size()-2*size;
1911 for(size_t i=0; i<size; ++i) {
1912 s[i*2+0] = smp0[i];
1913 s[i*2+1] = smp1[i];
1914 }
1915 }
1916
1917 gb.align32();
1918 if(gb.bitsLeft()==0)
1919 break;
1920 }
1921
1922 // frames[frameCounter%2].setSamples(uint8_t(id),ret.data(),ret.size());
1923 }
1924
1925void Video::parseAudioBlock(BitStream& gb, AudioCtx& aud) {
1926 float quant[25] = {};
1927
1928 if(aud.isDct)
1929 gb.skip(2);
1930
1931 for(uint8_t ch=0; ch<aud.channelsCnt; ++ch) {
1932 aud.samples[ch].resize(aud.frameLen);
1933
1934 float* coeffs = aud.samples[ch].data();
1935 if(revision=='b') {
1936 int32_t c0 = gb.getInt32();
1937 int32_t c1 = gb.getInt32();
1938
1939 coeffs[0] = reinterpret_cast<float&>(c0)*aud.root;
1940 coeffs[1] = reinterpret_cast<float&>(c1)*aud.root;
1941 } else {
1942 coeffs[0] = gb.getFloat()*aud.root;
1943 coeffs[1] = gb.getFloat()*aud.root;
1944 }
1945
1946 for(uint32_t i=0; i<aud.numBands; i++) {
1947 uint32_t value = gb.getBits(8);
1948 quant[i] = quantTable[std::min<uint32_t>(value, 95)];
1949 }
1950
1951 int k = 0;
1952 float q = quant[0];
1953
1954 // parse coefficients
1955 uint32_t i=2, j=0;
1956 while(i<aud.frameLen) {
1957 if(revision=='b') {
1958 j = i + 16;
1959 } else {
1960 int v = gb.getBit();
1961 if(v!=0) {
1962 v = gb.getBits(4);
1963 j = i + rle_length_tab[v] * 8;
1964 } else {
1965 j = i + 8;
1966 }
1967 }
1968
1969 j = std::min(j,aud.frameLen);
1970
1971 uint32_t width = gb.getBits(4);
1972 if(width == 0) {
1973 std::memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
1974 i = j;
1975 while(aud.bands[k] < i)
1976 q = quant[k++];
1977 } else {
1978 while(i < j) {
1979 if(aud.bands[k] == i)
1980 q = quant[k++];
1981 uint32_t coeff = gb.getBits(width);
1982 if(coeff!=0) {
1983 int v = gb.getBit();
1984 if(v)
1985 coeffs[i] = -q*float(coeff); else
1986 coeffs[i] = q*float(coeff);
1987 } else {
1988 coeffs[i] = 0.0f;
1989 }
1990 i++;
1991 }
1992 }
1993 }
1994
1995 if(aud.isDct) {
1996 coeffs[0] /= 0.5f;
1997 dctCalc3C(aud,coeffs);
1998 } else {
1999 rdftCalcC(aud,coeffs,false);
2000 }
2001 }
2002
2003 for(uint8_t ch=0; ch<aud.channelsCnt; ++ch) {
2004 uint32_t count = aud.overlapLen*aud.channelsCnt;
2005
2006 float* samples = aud.samples[ch].data();
2007 float* previous = aud.previous[ch];
2008
2009 if(!aud.first) {
2010 uint32_t j = ch;
2011 for(uint32_t i = 0; i<aud.overlapLen; i++, j += aud.channelsCnt)
2012 samples[i] = (previous[i]*float(count-j) + samples[i]*float(j))/float(count);
2013 }
2014 std::memcpy(previous, &samples[aud.frameLen-aud.overlapLen], aud.overlapLen*sizeof(*previous));
2015 }
2016
2017 aud.first = false;
2018 }
2019
2020void Video::dctCalc3C(AudioCtx& aud, float *data) {
2021 int n = 1 << (aud.nbits);
2022
2023 float next = data[n-1];
2024 float inv_n = 1.0f / float(n);
2025 float* costab = ffCosTabs[aud.nbits + 2].data();
2026
2027 for(int i = n-2; i>=2; i-=2) {
2028 float val1 = data[i];
2029 float val2 = data[i-1] - data[i+1];
2030 float c = costab[i];
2031 float s = costab[n-i];
2032
2033 data[i] = c * val1 + s * val2;
2034 data[i + 1] = s * val1 - c * val2;
2035 }
2036
2037 data[1] = 2 * next;
2038
2039 rdftCalcC(aud, data, true);
2040
2041 for(int i=0; i<n/2; i++) {
2042 float tmp1 = data[i] * inv_n;
2043 float tmp2 = data[n-i-1] * inv_n;
2044 float csc = aud.csc2[i] * (tmp1 - tmp2);
2045
2046 tmp1 += tmp2;
2047 data[i] = tmp1 + csc;
2048 data[n - i - 1] = tmp1 - csc;
2049 }
2050 }
2051
2052void Video::rdftCalcC(AudioCtx& aud, float *data, bool negativeSign) {
2053 FFTComplex ev, od, odsum;
2054 const int n = 1 << aud.nbits;
2055 const float k1 = 0.5;
2056 const float k2 = -0.5;
2057 const float *tcos = aud.tcos;
2058 const float *tsin = aud.tsin;
2059
2060 float signConvention = negativeSign ? -1.f : 1.f;
2061 float signConventionInv = negativeSign ? 1.f : -1.f;
2062
2063 // i=0 is a special case because of packing, the DC term is real, so we
2064 // are going to throw the N/2 term (also real) in with it.
2065
2066 ev.re = data[0];
2067 data[0] = ev.re+data[1];
2068 data[1] = ev.re-data[1];
2069
2070 int i = 0;
2071 for(i = 1; i < (n>>2); i++) {
2072 int i1 = 2*i;
2073 int i2 = n-i1;
2074 ev.re = k1*(data[i1 ]+data[i2 ]);
2075 od.im = k2*(data[i2 ]-data[i1 ]);
2076 ev.im = k1*(data[i1+1]-data[i2+1]);
2077 od.re = k2*(data[i1+1]+data[i2+1]);
2078 odsum.re = od.re*tcos[i] + signConvention *od.im*tsin[i];
2079 odsum.im = od.im*tcos[i] + signConventionInv*od.re*tsin[i];
2080 data[i1 ] = ev.re + odsum.re;
2081 data[i1+1] = ev.im + odsum.im;
2082 data[i2 ] = ev.re - odsum.re;
2083 data[i2+1] = odsum.im - ev.im;
2084 }
2085
2086 data[0] *= k1;
2087 data[1] *= k1;
2088
2089 data[2*i+1]=signConvention*data[2*i+1];
2090 fftPermute(aud, reinterpret_cast<FFTComplex*>(data));
2091 fftCalc (aud, reinterpret_cast<FFTComplex*>(data));
2092 }
2093
2094void Video::fftPermute(AudioCtx& aud, FFTComplex *z) {
2095 const uint16_t *revtab = aud.revtab.data();
2096 const uint32_t *revtab32 = aud.revtab32.data();
2097 int np = 1 << (aud.nbits-1);
2098 // TODO: handle split-radix permute in a more optimal way, probably in-place
2099 if(revtab) {
2100 for(int j=0; j<np; j++)
2101 aud.tmpBuf[revtab[j]] = z[j];
2102 } else {
2103 for(int j=0;j<np;j++)
2104 aud.tmpBuf[revtab32[j]] = z[j];
2105 }
2106 std::memcpy(z, aud.tmpBuf.data(), np*sizeof(FFTComplex));
2107 }
2108
2109void Video::fftCalc(const AudioCtx& aud, FFTComplex* z) {
2110 static void(*const dispatch[])(FFTComplex*) = {
2111 fft<4, 2>,
2112 fft<8, 3>,
2113 fft<16, 4>,
2114 fft<32, 5>,
2115 fft<64, 6>,
2116 fft<128, 7>,
2117 fft<256, 8>,
2118 fft<512, 9>,
2119 fft<1024, 10>,
2120 fft<2048, 11>,
2121 fft<4096, 12>,
2122 fft<8192, 13>,
2123 fft<16384, 14>,
2124 fft<32768, 15>,
2125 fft<65536, 16>,
2126 fft<131072, 17>
2127 };
2128 dispatch[aud.nbits-3](z);
2129 }
virtual void seek(size_t pos)=0
virtual void read(void *dest, size_t count)=0
virtual void skip(size_t count)=0
const Frame & nextFrame()
Definition video.cpp:928
size_t frameCount() const
Definition video.cpp:943
Video(Input *file)
Definition video.cpp:828
@ BINK_TAG
Definition video.h:26
Definition frame.h:7
Definition video.cpp:554
int16_t(* table)[2]
Definition video.cpp:556
int table_size
Definition video.cpp:557
int table_allocated
Definition video.cpp:558
int bits
Definition video.cpp:555
uint8_t bits
Definition video.cpp:547
uint16_t symbol
Definition video.cpp:548
uint32_t code
Definition video.cpp:551
BitStream(const uint8_t *data, size_t bitCount)
Definition video.cpp:752
uint32_t showBits(int n)
Definition video.cpp:789
size_t bitsLeft() const
Definition video.cpp:812
void skip(size_t n)
Definition video.cpp:754
uint32_t getBits(int n)
Definition video.cpp:781
const uint8_t * data
Definition video.cpp:818
size_t position() const
Definition video.cpp:811
static const uint8_t bink_rlelens[4]
Definition video.cpp:37
static const uint8_t rle_length_tab[16]
Definition video.cpp:542
static const uint32_t bink_inter_quant[16][64]
Definition video.cpp:380
static uint32_t AV_RL32(const char *v)
Definition video.cpp:565
static void CMUL(T &dre, T &dim, const T &are, const T &aim, const T &bre, const T &bim)
Definition video.cpp:649
static void BUTTERFLIES(Video::FFTComplex &a0, Video::FFTComplex &a1, Video::FFTComplex &a2, Video::FFTComplex &a3, float &t1, float &t2, float &t3, float &t4, float &t5, float &t6)
Definition video.cpp:654
static void fftPass(Video::FFTComplex *z, const float *wre, unsigned int n)
Definition video.cpp:680
static void BF(T &x, T &y, const T &a, const T &b)
Definition video.cpp:643
static void bink_idct_col(int *dest, const int32_t *src)
Definition video.cpp:627
static void idctRow(T *dest, const int *src)
Definition video.cpp:622
static const uint8_t bink_scan[64]
Definition video.cpp:27
void fft< 4, 2 >(Video::FFTComplex *z)
Definition video.cpp:708
void fft< 16, 4 >(Video::FFTComplex *z)
Definition video.cpp:736
static const uint16_t ff_wma_critical_freqs[25]
Definition video.cpp:19
static const uint8_t bink_patterns[16][64]
Definition video.cpp:56
static void transformZero(Video::FFTComplex &a0, Video::FFTComplex &a1, Video::FFTComplex &a2, Video::FFTComplex &a3, float &t1, float &t2, float &t3, float &t4, float &t5, float &t6)
Definition video.cpp:671
static void processFftPerm(T *revtab, int n, bool inverse)
Definition video.cpp:1789
static int splitRadixPermutation(int i, int n, int inverse)
Definition video.cpp:1776
static void transform(Video::FFTComplex &a0, Video::FFTComplex &a1, Video::FFTComplex &a2, Video::FFTComplex &a3, const float wre, const float wim, float &t1, float &t2, float &t3, float &t4, float &t5, float &t6)
Definition video.cpp:664
static const uint8_t bink_tree_lens[16][16]
Definition video.cpp:38
static const float sqrthalf
Definition video.cpp:17
void fft< 8, 3 >(Video::FFTComplex *z)
Definition video.cpp:722
static int av_log2(unsigned v)
Definition video.cpp:575
static void idctCol(T *dest, const int *src)
Definition video.cpp:616
static void idctTransform(T *dest, const int *src, int s0, int s1, int s2, int s3, int s4, int s5, int s6, int s7, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7, T(*munge)(int))
Definition video.cpp:580
static VLC bink_trees[16]
Definition video.cpp:561
static std::vector< float > ffCosTabs[18]
Definition video.cpp:563
static void fft(Video::FFTComplex *z)
Definition video.cpp:700
static const uint32_t bink_intra_quant[16][64]
Definition video.cpp:218