]>
Commit | Line | Data |
---|---|---|
3584b223 KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::bitreader::*; | |
3 | use super::vpcommon::*; | |
4 | use super::vp56::*; | |
5 | ||
6 | struct VP5BR {} | |
7 | ||
8 | impl VP5BR { | |
9 | fn new() -> Self { | |
10 | Self {} | |
11 | } | |
12 | } | |
13 | ||
14 | impl 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 | ||
237 | struct VP5Decoder { | |
238 | dec: VP56Decoder, | |
239 | info: NACodecInfoRef, | |
240 | br: VP5BR, | |
241 | } | |
242 | ||
243 | impl 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 | ||
253 | impl 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 | 280 | pub fn get_decoder() -> Box<NADecoder + Send> { |
3584b223 KS |
281 | Box::new(VP5Decoder::new()) |
282 | } | |
283 | ||
284 | #[cfg(test)] | |
285 | mod 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 | ||
306 | const 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 | ||
358 | const 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 | ||
397 | const 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 | ]; |