]> git.nihav.org Git - nihav.git/blame - nihav-duck/src/codecs/vp5.rs
vp7: skip DC transform for empty block
[nihav.git] / nihav-duck / src / codecs / vp5.rs
CommitLineData
3584b223
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitreader::*;
3use super::vpcommon::*;
4use super::vp56::*;
5
6struct VP5BR {}
7
8impl VP5BR {
9 fn new() -> Self {
10 Self {}
11 }
12}
13
14impl VP56Parser for VP5BR {
15 fn parse_header(&mut self, bc: &mut BoolCoder) -> DecoderResult<VP56Header> {
16 let mut hdr = VP56Header::default();
17 hdr.is_intra = !bc.read_bool();
18 hdr.is_golden = hdr.is_intra;
19 bc.read_bool();
20 hdr.quant = bc.read_bits(6) as u8;
21 if hdr.is_intra {
22 hdr.version = bc.read_bits(13) as u8;
23 validate!(hdr.version == 5);
24 hdr.profile = bc.read_bits(2) as u8;
25 hdr.interlaced = bc.read_bool();
26 validate!(!hdr.interlaced);
27 hdr.mb_h = bc.read_bits(8) as u8;
28 hdr.mb_w = bc.read_bits(8) as u8;
29 hdr.disp_h = bc.read_bits(8) as u8;
30 hdr.disp_w = bc.read_bits(8) as u8;
31 validate!((hdr.mb_h > 0) && (hdr.mb_w > 0) && (hdr.disp_w > 0) && (hdr.disp_h > 0));
32 validate!((hdr.disp_w <= hdr.mb_w) && (hdr.disp_h <= hdr.mb_h));
33 hdr.scale = bc.read_bits(2) as u8;
34 }
35
36 Ok(hdr)
37 }
38 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16 {
39 if bc.read_prob(model.nz_prob) {
40 let sign = bc.read_prob(model.sign_prob);
41 let b0 = bc.read_prob(model.raw_probs[0]) as i16;
42 let b1 = bc.read_prob(model.raw_probs[1]) as i16;
43 let top: i16 = vp_tree!(bc, model.tree_probs[0],
44 vp_tree!(bc, model.tree_probs[1],
45 vp_tree!(bc, model.tree_probs[2], 0, 1),
46 vp_tree!(bc, model.tree_probs[3], 2, 3)
47 ),
48 vp_tree!(bc, model.tree_probs[4],
49 vp_tree!(bc, model.tree_probs[5], 4, 5),
50 vp_tree!(bc, model.tree_probs[6], 6, 7)
51 )
52 );
53 let val = (top << 2) | (b1 << 1) | b0;
54 if !sign {
55 val
56 } else {
57 -val
58 }
59 } else {
60 0
61 }
62 }
63 fn reset_models(&self, models: &mut VP56Models) {
64 for mdl in models.mv_models.iter_mut() {
65 mdl.nz_prob = 128;
66 mdl.sign_prob = 128;
67 mdl.raw_probs[0] = 85;
68 mdl.raw_probs[1] = 128;
69 mdl.tree_probs = [128; 7];
70 }
71 }
72 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()> {
73 const HAS_NZ_PROB: [u8; 2] = [ 243, 235 ];
74 const HAS_SIGN_PROB: [u8; 2] = [ 220, 211 ];
75 const HAS_RAW0_PROB: [u8; 2] = [ 251, 246 ];
76 const HAS_RAW1_PROB: [u8; 2] = [ 253, 249 ];
77 const HAS_TREE_PROB: [[u8; 7]; 2] = [
78 [ 237, 232, 241, 245, 247, 251, 253 ],
79 [ 234, 231, 248, 249, 252, 252, 254 ]
80 ];
81 for comp in 0..2 {
82 if bc.read_prob(HAS_NZ_PROB[comp]) {
83 models[comp].nz_prob = bc.read_probability();
84 }
85 if bc.read_prob(HAS_SIGN_PROB[comp]) {
86 models[comp].sign_prob = bc.read_probability();
87 }
88 if bc.read_prob(HAS_RAW0_PROB[comp]) {
89 models[comp].raw_probs[0] = bc.read_probability();
90 }
91 if bc.read_prob(HAS_RAW1_PROB[comp]) {
92 models[comp].raw_probs[1] = bc.read_probability();
93 }
94 }
95 for comp in 0..2 {
96 for i in 0..7 {
97 if bc.read_prob(HAS_TREE_PROB[comp][i]) {
98 models[comp].tree_probs[i] = bc.read_probability();
99 }
100 }
101 }
102 Ok(())
103 }
104 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()> {
105 const COEF_PROBS: [[u8; 11]; 2] = [
106 [ 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 ],
107 [ 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 ]
108 ];
109
110 let mut def_prob = [128u8; 11];
111 for plane in 0..2 {
112 for i in 0..11 {
113 if bc.read_prob(COEF_PROBS[plane][i]) {
114 def_prob[i] = bc.read_probability();
115 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
116 } else if is_intra {
117 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
118 }
119 }
120 }
121 for ctype in 0..3 {
122 for plane in 0..2 {
123 for group in 0..6 {
124 for i in 0..11 {
125 if bc.read_prob(VP5_AC_PROBS[ctype][plane][group][i]) {
126 def_prob[i] = bc.read_probability();
127 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
128 } else if is_intra {
129 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
130 }
131 }
132 }
133 }
134 }
135 for plane in 0..2 {
136 let mdl = &mut models.coeff_models[plane];
137 for i in 0..6 {
138 for j in 0..6 {
139 for k in 0..5 {
140 mdl.dc_token_probs[i][j][k] = rescale_prob(mdl.dc_value_probs[k], &VP5_DC_WEIGHTS[k][i][j], 254);
141 }
142 }
143 }
144 for ctype in 0..3 {
145 for group in 0..3 {
146 for i in 0..6 {
147 for j in 0..5 {
148 mdl.ac_type_probs[ctype][group][i][j] = rescale_prob(mdl.ac_val_probs[ctype][group][j], &VP5_AC_WEIGHTS[ctype][group][j][i], 254);
149 }
150 }
151 }
152 }
153 }
154 Ok(())
155 }
156 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, _vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()> {
157 const COEF_GROUPS: [u8; 64] = [
158 0, 0, 1, 1, 2, 1, 1, 2,
159 2, 1, 1, 2, 2, 2, 1, 2,
160 2, 2, 2, 2, 1, 1, 2, 2,
161 3, 3, 4, 3, 4, 4, 4, 3,
162 3, 3, 3, 3, 4, 3, 3, 3,
163 4, 4, 4, 4, 4, 3, 3, 4,
164 4, 4, 3, 4, 4, 4, 4, 4,
165 4, 4, 5, 5, 5, 5, 5, 5
166 ];
167
168 let mut ctype = 1;
169 let left_ctx = fstate.coeff_cat[fstate.ctx_idx][0] as usize;
170 let top_ctx = fstate.top_ctx as usize;
171
172 let mut val_probs: &[u8; 11] = &model.dc_value_probs;
173 let mut tok_probs: &[u8] = &model.dc_token_probs[left_ctx][top_ctx];
174 let mut idx = 0;
175 loop {
176 let token = vp_tree!(bc, tok_probs[0],
177 if ctype != 0 { vp_tree!(bc, tok_probs[1], break, 0) } else { 0 },
178 vp_tree!(bc, tok_probs[2],
179 1,
180 vp_tree!(bc, tok_probs[3],
181 vp_tree!(bc, tok_probs[4], 2,
182 vp_tree!(bc, val_probs[5], 3, 4)),
183 TOKEN_LARGE)));
184 let val = expand_token_bc(bc, val_probs, token, 5);
185 ctype = token.min(2) as usize;
186 if token < TOKEN_LARGE {
187 fstate.coeff_cat[fstate.ctx_idx][idx] = token.min(3);
188 } else {
189 fstate.coeff_cat[fstate.ctx_idx][idx] = 4;
190 }
191 coeffs[ZIGZAG[idx]] = val;
192 if idx > 0 {
193 coeffs[ZIGZAG[idx]] *= fstate.ac_quant;
194 }
195
196 idx += 1;
197 if idx >= 64 {
198 break;
199 }
200 let group = COEF_GROUPS[idx] as usize;
201 val_probs = &model.ac_val_probs[ctype][group];
202 tok_probs = if group > 2 { val_probs
203 } else {
204 let ctx = fstate.coeff_cat[fstate.ctx_idx][idx] as usize;
205 &model.ac_type_probs[ctype][group][ctx]
206 };
207 }
208 let end = fstate.last_idx[fstate.ctx_idx].min(24);
209 fstate.last_idx[fstate.ctx_idx] = idx;
210 for i in idx..end {
211 fstate.coeff_cat[fstate.ctx_idx][i] = 5;
212 }
213 fstate.top_ctx = fstate.coeff_cat[fstate.ctx_idx][0];
214
215 Ok(())
216 }
217 fn decode_block_huff(&self, _br: &mut BitReader, _coeffs: &mut [i16; 64], _vp6model: &VP6Models, _model: &VP6HuffModels, _fstate: &mut FrameState) -> DecoderResult<()> {
218 unreachable!();
219 }
220 fn mc_block(&self, dst: &mut NASimpleVideoFrame<u8>, mc_buf: NAVideoBufferRef<u8>, src: NAVideoBufferRef<u8>, plane: usize, x: usize, y: usize, mv: MV, loop_str: i16) {
221 let (sx, sy, mx, my) = if (plane != 1) && (plane != 2) {
ab5baaf1 222 (mv.x >> 1, mv.y >> 1, mv.x & 1, mv.y & 1)
3584b223 223 } else {
6d3946fe 224 (mv.x >> 2, mv.y >> 2, if (mv.x & 3) != 0 { 1 } else { 0 }, if (mv.y & 3) != 0 { 1 } else { 0 })
ab5baaf1
KS
225 };
226 let mode1 = (mx as usize) + (my as usize) * 2;
227 let mode = if (mode1 == 3) && (mv.x ^ mv.y < 0) {
228 4
229 } else {
230 mode1
3584b223 231 };
3584b223
KS
232 vp_copy_block(dst, src, plane, x, y, sx, sy, 0, 1, loop_str,
233 mode, VP3_INTERP_FUNCS, mc_buf);
234 }
235}
236
237struct VP5Decoder {
238 dec: VP56Decoder,
239 info: NACodecInfoRef,
240 br: VP5BR,
241}
242
243impl VP5Decoder {
244 fn new() -> Self {
245 Self {
246 dec: VP56Decoder::new(5, false, true),
247 info: NACodecInfoRef::default(),
248 br: VP5BR::new(),
249 }
250 }
251}
252
253impl NADecoder for VP5Decoder {
254 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
255 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
256 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, YUV420_FORMAT);
257 let myinfo = NACodecTypeInfo::Video(myvinfo.clone());
258 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
259 self.dec.init(supp, myvinfo)?;
260 Ok(())
261 } else {
262 Err(DecoderError::InvalidData)
263 }
264 }
265 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
266 let src = pkt.get_buffer();
267
268 let (bufinfo, ftype) = self.dec.decode_frame(supp, src.as_slice(), &mut self.br)?;
269
270 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
271 frm.set_keyframe(ftype == FrameType::I);
272 frm.set_frame_type(ftype);
273 Ok(frm.into_ref())
274 }
f9be4e75
KS
275 fn flush(&mut self) {
276 self.dec.flush();
277 }
3584b223
KS
278}
279
08a1fab7 280pub fn get_decoder() -> Box<NADecoder + Send> {
3584b223
KS
281 Box::new(VP5Decoder::new())
282}
283
284#[cfg(test)]
285mod test {
286 use nihav_core::codecs::RegisteredDecoders;
287 use nihav_core::demuxers::RegisteredDemuxers;
288 use nihav_core::test::dec_video::*;
289 use crate::codecs::duck_register_all_codecs;
290 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
291
292 #[test]
293 fn test_vp5() {
294 let mut dmx_reg = RegisteredDemuxers::new();
295 generic_register_all_demuxers(&mut dmx_reg);
296 let mut dec_reg = RegisteredDecoders::new();
297 duck_register_all_codecs(&mut dec_reg);
298
299 let file = "assets/Duck/Cell-140.vp5";
300 //let file = "assets/Duck/Chocolat-500.vp5";
d5e94eaf
KS
301 test_decoding("avi", "vp5", file, Some(96), &dmx_reg, &dec_reg,
302 ExpectedTestResult::MD5([0x9ad78b0f, 0xed988ead, 0x88ed2ea9, 0xcdb75cdf]));
3584b223
KS
303 }
304}
305
306const VP5_AC_PROBS: [[[[u8; 11]; 6]; 2]; 3] = [
307 [
308 [
309 [ 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 ],
310 [ 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 ],
311 [ 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 ],
312 [ 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 ],
313 [ 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 ],
314 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
315 ], [
316 [ 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 ],
317 [ 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 ],
318 [ 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 ],
319 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
320 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
321 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
322 ]
323 ], [
324 [
325 [ 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 ],
326 [ 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 ],
327 [ 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 ],
328 [ 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 ],
329 [ 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 ],
330 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
331 ], [
332 [ 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 ],
333 [ 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 ],
334 [ 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
335 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
336 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
337 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
338 ]
339 ], [
340 [
341 [ 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 ],
342 [ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 ],
343 [ 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 ],
344 [ 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 ],
345 [ 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 ],
346 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
347 ], [
348 [ 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 ],
349 [ 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 ],
350 [ 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
351 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
352 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
353 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
354 ]
355 ]
356];
357
358const VP5_DC_WEIGHTS: [[[[i16; 2]; 6]; 6]; 5] = [
359 [
360 [ [154, 61], [141, 54], [ 90, 45], [ 54, 34], [ 54, 13], [128, 109] ],
361 [ [136, 54], [148, 45], [ 92, 41], [ 54, 33], [ 51, 15], [ 87, 113] ],
362 [ [ 87, 44], [ 97, 40], [ 67, 36], [ 46, 29], [ 41, 15], [ 64, 80] ],
363 [ [ 59, 33], [ 61, 31], [ 51, 28], [ 44, 22], [ 33, 12], [ 49, 63] ],
364 [ [ 69, 12], [ 59, 16], [ 46, 14], [ 31, 13], [ 26, 6], [ 92, 26] ],
365 [ [128, 108], [ 77, 119], [ 54, 84], [ 26, 71], [ 87, 19], [ 95, 155] ]
366 ], [
367 [ [154, 4], [182, 0], [159, -8], [128, -5], [143, -5], [187, 55] ],
368 [ [182, 0], [228, -3], [187, -7], [174, -9], [189, -11], [169, 79] ],
369 [ [161, -9], [192, -8], [187, -9], [169, -10], [136, -9], [184, 40] ],
370 [ [164, -11], [179, -10], [174, -10], [161, -10], [115, -7], [197, 20] ],
371 [ [195, -11], [195, -11], [146, -10], [110, -6], [ 95, -4], [195, 39] ],
372 [ [182, 55], [172, 77], [177, 37], [169, 29], [172, 52], [ 92, 162] ]
373 ], [
374 [ [174, 80], [164, 80], [ 95, 80], [ 46, 66], [ 56, 24], [ 36, 193] ],
375 [ [164, 80], [166, 77], [105, 76], [ 49, 68], [ 46, 31], [ 49, 186] ],
376 [ [ 97, 78], [110, 74], [ 72, 72], [ 44, 60], [ 33, 30], [ 69, 131] ],
377 [ [ 61, 61], [ 69, 63], [ 51, 57], [ 31, 48], [ 26, 27], [ 64, 89] ],
378 [ [ 67, 23], [ 51, 32], [ 36, 33], [ 26, 28], [ 20, 12], [ 44, 68] ],
379 [ [ 26, 197], [ 41, 189], [ 61, 129], [ 28, 103], [ 49, 52], [-12, 245] ]
380 ], [
381 [ [102, 141], [ 79, 166], [ 72, 162], [ 97, 125], [179, 4], [307, 0] ],
382 [ [ 72, 168], [ 69, 175], [ 84, 160], [105, 127], [148, 34], [310, 0] ],
383 [ [ 84, 151], [ 82, 161], [ 87, 153], [ 87, 135], [115, 51], [317, 0] ],
384 [ [ 97, 125], [102, 131], [105, 125], [ 87, 122], [ 84, 64], [ 54, 184] ],
385 [ [166, 18], [146, 43], [125, 51], [ 90, 64], [ 95, 7], [ 38, 154] ],
386 [ [294, 0], [ 13, 225], [ 10, 225], [ 67, 168], [ 0, 167], [161, 94] ]
387 ], [
388 [ [172, 76], [172, 75], [136, 80], [ 64, 98], [ 74, 67], [315, 0] ],
389 [ [169, 76], [207, 56], [164, 66], [ 97, 80], [ 67, 72], [328, 0] ],
390 [ [136, 80], [187, 53], [154, 62], [ 72, 85], [ -2, 105], [305, 0] ],
391 [ [ 74, 91], [128, 64], [113, 64], [ 61, 77], [ 41, 75], [259, 0] ],
392 [ [ 46, 84], [ 51, 81], [ 28, 89], [ 31, 78], [ 23, 77], [202, 0] ],
393 [ [323, 0], [323, 0], [300, 0], [236, 0], [195, 0], [328, 0] ]
394 ]
395];
396
397const VP5_AC_WEIGHTS: [[[[[i16; 2]; 6]; 5]; 3]; 3] = [
398 [
399 [
400 [ [276, 0], [238, 0], [195, 0], [156, 0], [113, 0], [274, 0] ],
401 [ [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1] ],
402 [ [192, 59], [182, 50], [141, 48], [110, 40], [ 92, 19], [125,128] ],
403 [ [169, 87], [169, 83], [184, 62], [220, 16], [184, 0], [264, 0] ],
404 [ [212, 40], [212, 36], [169, 49], [174, 27], [ 8,120], [182, 71] ]
405 ], [
406 [ [259, 10], [197, 19], [143, 22], [123, 16], [110, 8], [133, 88] ],
407 [ [ 0, 1], [256, 0], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1] ],
408 [ [207, 46], [187, 50], [ 97, 83], [ 23,100], [ 41, 56], [ 56,188] ],
409 [ [166, 90], [146,108], [161, 88], [136, 95], [174, 0], [266, 0] ],
410 [ [264, 7], [243, 18], [184, 43], [-14,154], [ 20,112], [ 20,199] ]
411 ], [
412 [ [230, 26], [197, 22], [159, 20], [146, 12], [136, 4], [ 54,162] ],
413 [ [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1] ],
414 [ [192, 59], [156, 72], [ 84,101], [ 49,101], [ 79, 47], [ 79,167] ],
415 [ [138,115], [136,116], [166, 80], [238, 0], [195, 0], [261, 0] ],
416 [ [225, 33], [205, 42], [159, 61], [ 79, 96], [ 92, 66], [ 28,195] ]
417 ]
418 ], [
419 [
420 [ [200, 37], [197, 18], [159, 13], [143, 7], [102, 5], [123,126] ],
421 [ [197, 3], [220, -9], [210,-12], [187, -6], [151, -2], [174, 80] ],
422 [ [200, 53], [187, 47], [159, 40], [118, 38], [100, 18], [141,111] ],
423 [ [179, 78], [166, 86], [197, 50], [207, 27], [187, 0], [115,139] ],
424 [ [218, 34], [220, 29], [174, 46], [128, 61], [ 54, 89], [187, 65] ]
425 ], [
426 [ [238, 14], [197, 18], [125, 26], [ 90, 25], [ 82, 13], [161, 86] ],
427 [ [189, 1], [205, -2], [156, -4], [143, -4], [146, -4], [172, 72] ],
428 [ [230, 31], [192, 45], [102, 76], [ 38, 85], [ 56, 41], [ 64,173] ],
429 [ [166, 91], [141,111], [128,116], [118,109], [177, 0], [ 23,222] ],
430 [ [253, 14], [236, 21], [174, 49], [ 33,118], [ 44, 93], [ 23,187] ]
431 ], [
432 [ [218, 28], [179, 28], [118, 35], [ 95, 30], [ 72, 24], [128,108] ],
433 [ [187, 1], [174, -1], [125, -1], [110, -1], [108, -1], [202, 52] ],
434 [ [197, 53], [146, 75], [ 46,118], [ 33,103], [ 64, 50], [118,126] ],
435 [ [138,114], [128,122], [161, 86], [243, -6], [195, 0], [ 38,210] ],
436 [ [215, 39], [179, 58], [ 97,101], [ 95, 85], [ 87, 70], [ 69,152] ]
437 ]
438 ], [
439 [
440 [ [236, 24], [205, 18], [172, 12], [154, 6], [125, 1], [169, 75] ],
441 [ [187, 4], [230, -2], [228, -4], [236, -4], [241, -2], [192, 66] ],
442 [ [200, 46], [187, 42], [159, 34], [136, 25], [105, 10], [179, 62] ],
443 [ [207, 55], [192, 63], [192, 54], [195, 36], [177, 1], [143, 98] ],
444 [ [225, 27], [207, 34], [200, 30], [131, 57], [ 97, 60], [197, 45] ]
445 ], [
446 [ [271, 8], [218, 13], [133, 19], [ 90, 19], [ 72, 7], [182, 51] ],
447 [ [179, 1], [225, -1], [154, -2], [110, -1], [ 92, 0], [195, 41] ],
448 [ [241, 26], [189, 40], [ 82, 64], [ 33, 60], [ 67, 17], [120, 94] ],
449 [ [192, 68], [151, 94], [146, 90], [143, 72], [161, 0], [113,128] ],
450 [ [256, 12], [218, 29], [166, 48], [ 44, 99], [ 31, 87], [148, 78] ]
451 ], [
452 [ [238, 20], [184, 22], [113, 27], [ 90, 22], [ 74, 9], [192, 37] ],
453 [ [184, 0], [215, -1], [141, -1], [ 97, 0], [ 49, 0], [264, 13] ],
454 [ [182, 51], [138, 61], [ 95, 63], [ 54, 59], [ 64, 25], [200, 45] ],
455 [ [179, 75], [156, 87], [174, 65], [177, 44], [174, 0], [164, 85] ],
456 [ [195, 45], [148, 65], [105, 79], [ 95, 72], [ 87, 60], [169, 63] ]
457 ]
458 ]
459];