some updates
[iv.d.git] / tremor.d
blob497d331abbb9d53dc6e9f04a87b18faa70b019e7
1 /*
2 Copyright (c) 2002, Xiph.org Foundation
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
23 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 // quick-and-dirty D translation by Ketmar // Invisible Vector
32 module iv.tremor /*is aliced*/;
33 //version = LOW_ACCURACY__;
34 private:
35 import iv.alice;
37 import core.stdc.errno : errno;
38 import core.stdc.stdio;
39 import core.stdc.string : memchr, memcmp, memcpy, memset, memmove, strlen, strcpy, strcat;
40 import core.stdc.stdlib : ogg_malloc_ = malloc, ogg_realloc_ = realloc, ogg_free_ = free, ogg_calloc_ = calloc;
42 version(XoggTremorNoVFS) {
43 public enum XoggTremorHasVFS = false;
44 } else {
45 static if (is(typeof((){import iv.vfs;}()))) {
46 public enum XoggTremorHasVFS = true;
47 import iv.vfs;
48 version = XoggTremorHasVFS;
49 } else {
50 version = XoggTremorNoVFS;
51 public enum XoggTremorHasVFS = false;
56 alias ogg_int64_t = long;
57 alias ogg_int32_t = int;
58 alias ogg_uint32_t = uint;
59 alias ogg_int16_t = short;
60 alias trm_long = int;
61 alias trm_ulong = uint;
63 enum LONG_MAX = trm_long.max;
65 extern(C) {
66 private alias compare_fp_t_ = int function (in void*, in void*) nothrow @trusted @nogc;
67 private extern(C) void qsort (void* base, usize nmemb, usize size, compare_fp_t_ compar) nothrow @trusted @nogc;
70 alias vorbis_info_floor = void;
71 alias vorbis_info_residue = void;
72 alias vorbis_info_mapping = void;
74 alias vorbis_look_mapping = void;
75 alias vorbis_look_floor = void;
76 alias vorbis_look_residue = void;
77 alias vorbis_look_transform = void;
80 /* mode ************************************************************/
81 struct vorbis_info_mode {
82 int blockflag;
83 int windowtype;
84 int transformtype;
85 int mapping;
88 struct private_state {
89 private alias tt = const(void)*;
90 /* local lookup storage */
91 tt[2] window;
93 /* backend lookups are tied to the mode, not the backend or naked mapping */
94 int modebits;
95 vorbis_look_mapping **mode;
97 ogg_int64_t sample_count;
101 /* codec_setup_info contains all the setup information specific to the
102 specific compression/decompression mode in progress (eg,
103 psychoacoustic settings, channel setup, options, codebook
104 etc).
105 *********************************************************************/
107 struct codec_setup_info {
108 /* Vorbis supports only short and long blocks, but allows the encoder to choose the sizes */
110 trm_long[2] blocksizes;
112 /* modes are the primary means of supporting on-the-fly different
113 blocksizes, different channel mappings (LR or M/A),
114 different residue backends, etc. Each mode consists of a
115 blocksize flag and a mapping (along with the mapping setup */
117 int modes;
118 int maps;
119 int times;
120 int floors;
121 int residues;
122 int books;
124 vorbis_info_mode*[64] mode_param;
125 int[64] map_type;
126 vorbis_info_mapping*[64] map_param;
127 int[64] time_type;
128 int[64] floor_type;
129 vorbis_info_floor*[64] floor_param;
130 int[64] residue_type;
131 vorbis_info_residue*[64] residue_param;
132 static_codebook*[256] book_param;
133 codebook* fullbooks;
135 int[32] passlimit; /* iteration limit per couple/quant pass */
136 int coupling_passes;
140 struct vorbis_func_floor {
141 vorbis_info_floor* function (vorbis_info *, oggpack_buffer *) nothrow @trusted @nogc unpack;
142 vorbis_look_floor* function (vorbis_dsp_state *, vorbis_info_mode *, vorbis_info_floor *) nothrow @trusted @nogc look;
143 void function (vorbis_info_floor *) nothrow @trusted @nogc free_info;
144 void function (vorbis_look_floor *) nothrow @trusted @nogc free_look;
145 void* function (vorbis_block *, vorbis_look_floor *) nothrow @trusted @nogc inverse1;
146 int function (vorbis_block *, vorbis_look_floor *, void *buffer, ogg_int32_t *) nothrow @trusted @nogc inverse2;
149 struct vorbis_info_floor0 {
150 int order;
151 trm_long rate;
152 trm_long barkmap;
154 int ampbits;
155 int ampdB;
157 int numbooks; /* <= 16 */
158 int[16] books;
162 enum VIF_POSIT = 63;
163 enum VIF_CLASS = 16;
164 enum VIF_PARTS = 31;
166 struct vorbis_info_floor1 {
167 int partitions; /* 0 to 31 */
168 int[VIF_PARTS] partitionclass; /* 0 to 15 */
170 int[VIF_CLASS] class_dim; /* 1 to 8 */
171 int[VIF_CLASS] class_subs; /* 0,1,2,3 (bits: 1<<n poss) */
172 int[VIF_CLASS] class_book; /* subs ^ dim entries */
173 int[8][VIF_CLASS] class_subbook; /* [VIF_CLASS][subs] */
176 int mult; /* 1 2 3 or 4 */
177 int[VIF_POSIT+2] postlist; /* first two implicit */
181 /* Residue backend generic *****************************************/
182 struct vorbis_func_residue {
183 vorbis_info_residue* function (vorbis_info *, oggpack_buffer *) nothrow @trusted @nogc unpack;
184 vorbis_look_residue* function (vorbis_dsp_state *, vorbis_info_mode *, vorbis_info_residue *) nothrow @trusted @nogc look;
185 void function (vorbis_info_residue *) nothrow @trusted @nogc free_info;
186 void function (vorbis_look_residue *) nothrow @trusted @nogc free_look;
187 int function (vorbis_block *, vorbis_look_residue *, ogg_int32_t **, int *, int) nothrow @trusted @nogc inverse;
190 struct vorbis_info_residue0 {
191 /* block-partitioned VQ coded straight residue */
192 trm_long begin;
193 trm_long end;
195 /* first stage (lossless partitioning) */
196 int grouping; /* group n vectors per partition */
197 int partitions; /* possible codebooks for a partition */
198 int partvals; /* partitions ^ groupbook dim */
199 int groupbook; /* huffbook for partitioning */
200 int[64] secondstages; /* expanded out to pointers in lookup */
201 int[512] booklist; /* list of second stage books */
204 /* Mapping backend generic *****************************************/
205 struct vorbis_func_mapping {
206 vorbis_info_mapping* function (vorbis_info *, oggpack_buffer *) nothrow @trusted @nogc unpack;
207 vorbis_look_mapping* function (vorbis_dsp_state *, vorbis_info_mode *, vorbis_info_mapping *) nothrow @trusted @nogc look;
208 void function (vorbis_info_mapping *) nothrow @trusted @nogc free_info;
209 void function (vorbis_look_mapping *) nothrow @trusted @nogc free_look;
210 int function (vorbis_block *vb, vorbis_look_mapping *) nothrow @trusted @nogc inverse;
213 struct vorbis_info_mapping0 {
214 int submaps; /* <= 16 */
215 int[256] chmuxlist; /* up to 256 channels in a Vorbis stream */
217 int[16] floorsubmap; /* [mux] submap to floors */
218 int[16] residuesubmap; /* [mux] submap to residue */
220 int[2] psy; /* by blocktype; impulse/padding for short,
221 transition/normal for long */
223 int coupling_steps;
224 int[256] coupling_mag;
225 int[256] coupling_ang;
229 /* ******************************************************************
230 function: libvorbis codec headers
231 ****************************************************************** */
233 public struct vorbis_info {
234 int ver; ///
235 int channels; ///
236 int rate; ///
238 /** The below bitrate declarations are *hints*.
239 Combinations of the three values carry the following implications:
241 all three set to the same value:
242 implies a fixed rate bitstream
243 only nominal set:
244 implies a VBR stream that averages the nominal bitrate. No hard
245 upper/lower limit
246 upper and or lower set:
247 implies a VBR bitstream that obeys the bitrate limits. nominal
248 may also be set to give a nominal rate.
249 none set:
250 the coder does not care to speculate.
252 int bitrate_upper; ///
253 int bitrate_nominal; ///
254 int bitrate_lower; ///
255 int bitrate_window; ///
257 private void *codec_setup;
260 /* vorbis_dsp_state buffers the current vorbis audio
261 analysis/synthesis state. The DSP state belongs to a specific
262 logical bitstream ****************************************************/
263 struct vorbis_dsp_state {
264 int analysisp;
265 vorbis_info *vi;
267 ogg_int32_t **pcm;
268 ogg_int32_t **pcmret;
269 int pcm_storage;
270 int pcm_current;
271 int pcm_returned;
273 int preextrapolate;
274 int eofflag;
276 int lW;
277 int W;
278 int nW;
279 int centerW;
281 ogg_int64_t granulepos;
282 ogg_int64_t sequence;
284 void *backend_state;
287 struct vorbis_block {
288 /* necessary stream state for linking to the framing abstraction */
289 ogg_int32_t** pcm; /* this is a pointer into local storage */
290 oggpack_buffer opb;
292 int lW;
293 int W;
294 int nW;
295 int pcmend;
296 int mode;
298 int eofflag;
299 ogg_int64_t granulepos;
300 ogg_int64_t sequence;
301 vorbis_dsp_state *vd; /* For read-only access of configuration */
303 /* local storage to avoid remallocing; it's up to the mapping to structure it */
304 void* localstore;
305 int localtop;
306 /*int*/usize localalloc;
307 int totaluse;
308 alloc_chain* reap;
311 /* vorbis_block is a single block of data to be processed as part of
312 the analysis/synthesis stream; it belongs to a specific logical
313 bitstream, but is independant from other vorbis_blocks belonging to
314 that logical bitstream. *************************************************/
316 struct alloc_chain {
317 void *ptr;
318 alloc_chain* next;
321 /* vorbis_info contains all the setup information specific to the
322 specific compression/decompression mode in progress (eg,
323 psychoacoustic settings, channel setup, options, codebook
324 etc). vorbis_info and substructures are in backends.h.
325 *********************************************************************/
327 /* the comments are not part of vorbis_info so that vorbis_info can be static storage */
329 public struct vorbis_comment {
330 // unlimited user comment fields. libvorbis writes 'libvorbis' whatever vendor is set to in encode
331 char** user_comments; ///
332 int* comment_lengths; ///
333 int comments; ///
334 char* vendor; ///
338 /* Vorbis ERRORS and return codes ***********************************/
340 public {
341 enum OV_FALSE = -1; ///
342 enum OV_EOF = -2; ///
343 enum OV_HOLE = -3; ///
345 enum OV_EREAD = -128; ///
346 enum OV_EFAULT = -129; ///
347 enum OV_EIMPL = -130; ///
348 enum OV_EINVAL = -131; ///
349 enum OV_ENOTVORBIS = -132; ///
350 enum OV_EBADHEADER = -133; ///
351 enum OV_EVERSION = -134; ///
352 enum OV_ENOTAUDIO = -135; ///
353 enum OV_EBADPACKET = -136; ///
354 enum OV_EBADLINK = -137; ///
355 enum OV_ENOSEEK = -138; ///
359 /* ******************************************************************
360 function: miscellaneous math and prototypes
361 ****************************************************************** */
363 version(LOW_ACCURACY__) {
364 private ubyte X (uint n) pure nothrow @safe @nogc { return cast(ubyte)(((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9)); }
365 private alias LOOKUP_T = ubyte;
366 } else {
367 private int X (uint n) pure nothrow @safe @nogc { return n; }
368 private alias LOOKUP_T = int;
371 version(LOW_ACCURACY__) {
372 /* 32 bit multiply, more portable but less accurate */
375 * Note: Precision is biased towards the first argument therefore ordering
376 * is important. Shift values were chosen for the best sound quality after
377 * many listening tests.
381 * For MULT32 and MULT31: The second argument is always a lookup table
382 * value already preshifted from 31 to 8 bits. We therefore take the
383 * opportunity to save on text space and use ubyte for those
384 * tables in this case.
387 /*STIN*/ ogg_int32_t MULT32 (ogg_int32_t x, ogg_int32_t y) nothrow @trusted @nogc {
388 pragma(inline, true);
389 return (x >> 9) * y; /* y preshifted >>23 */
392 /*STIN*/ ogg_int32_t MULT31 (ogg_int32_t x, ogg_int32_t y) nothrow @trusted @nogc {
393 pragma(inline, true);
394 return (x >> 8) * y; /* y preshifted >>23 */
397 /*STIN*/ ogg_int32_t MULT31_SHIFT15 (ogg_int32_t x, ogg_int32_t y) nothrow @trusted @nogc {
398 pragma(inline, true);
399 return (x >> 6) * y; /* y preshifted >>9 */
401 } else {
402 /* 64 bit multiply */
404 version(LittleEndian) {
405 align (1) union magic_u {
406 align(1):
407 align(1) struct {
408 align(1):
409 ogg_int32_t lo;
410 ogg_int32_t hi;
411 }/* halves;*/
412 ogg_int64_t whole;
414 } else {
415 align(1) union magic_u {
416 align(1):
417 align(1) struct {
418 align(1):
419 ogg_int32_t hi;
420 ogg_int32_t lo;
421 }/* halves;*/
422 ogg_int64_t whole;
426 /*STIN*/ ogg_int32_t MULT32 (ogg_int32_t x, ogg_int32_t y) nothrow @trusted @nogc {
427 pragma(inline, true);
428 magic_u magic;
429 magic.whole = cast(ogg_int64_t)x * y;
430 return magic/*.halves*/.hi;
433 /*STIN*/ ogg_int32_t MULT31 (ogg_int32_t x, ogg_int32_t y) nothrow @trusted @nogc {
434 pragma(inline, true);
435 return MULT32(x, y)<<1;
438 /*STIN*/ ogg_int32_t MULT31_SHIFT15 (ogg_int32_t x, ogg_int32_t y) nothrow @trusted @nogc {
439 pragma(inline, true);
440 magic_u magic;
441 magic.whole = cast(ogg_int64_t)x * y;
442 return (cast(ogg_uint32_t)(magic/*.halves*/.lo)>>15) | ((magic/*.halves*/.hi)<<17);
447 * This should be used as a memory barrier, forcing all cached values in
448 * registers to wr writen back to memory. Might or might not be beneficial
449 * depending on the architecture and compiler.
451 //#define MB()
453 /*STIN*/ void XPROD32(ogg_int32_t a, ogg_int32_t b,
454 ogg_int32_t t, ogg_int32_t v,
455 ogg_int32_t *x, ogg_int32_t *y) nothrow @trusted @nogc
457 pragma(inline, true);
458 *x = MULT32(a, t) + MULT32(b, v);
459 *y = MULT32(b, t) - MULT32(a, v);
462 /*STIN*/ void XPROD31(ogg_int32_t a, ogg_int32_t b,
463 ogg_int32_t t, ogg_int32_t v,
464 ogg_int32_t *x, ogg_int32_t *y) nothrow @trusted @nogc
466 pragma(inline, true);
467 *x = MULT31(a, t) + MULT31(b, v);
468 *y = MULT31(b, t) - MULT31(a, v);
471 /*STIN*/ void XNPROD31(ogg_int32_t a, ogg_int32_t b,
472 ogg_int32_t t, ogg_int32_t v,
473 ogg_int32_t *x, ogg_int32_t *y) nothrow @trusted @nogc
475 pragma(inline, true);
476 *x = MULT31(a, t) - MULT31(b, v);
477 *y = MULT31(b, t) + MULT31(a, v);
481 /*STIN*/ ogg_int32_t CLIP_TO_15(ogg_int32_t x) nothrow @trusted @nogc {
482 pragma(inline, true);
483 int ret=x;
484 ret-= ((x<=32767)-1)&(x-32767);
485 ret-= ((x>=-32768)-1)&(x+32768);
486 return(ret);
489 /*STIN*/ ogg_int32_t VFLOAT_MULT(ogg_int32_t a, ogg_int32_t ap,
490 ogg_int32_t b, ogg_int32_t bp,
491 ogg_int32_t *p) nothrow @trusted @nogc {
492 pragma(inline, true);
493 if(a && b){
494 version(LOW_ACCURACY__) {
495 *p=ap+bp+31;
496 return (a>>15)*(b>>16);
497 } else {
498 *p=ap+bp+32;
499 return MULT32(a, b);
501 } else
502 return 0;
505 private int ilog_ (uint v) nothrow @trusted @nogc {
506 int ret = 0;
507 while (v) {
508 ++ret;
509 v >>= 1;
511 return ret;
515 /*STIN*/ ogg_int32_t VFLOAT_MULTI(ogg_int32_t a, ogg_int32_t ap,
516 ogg_int32_t i,
517 ogg_int32_t *p) nothrow @trusted @nogc {
518 pragma(inline, true);
519 import std.math : abs;
520 int ip=ilog_(abs(i))-31;
521 return VFLOAT_MULT(a, ap, i<<-ip, ip, p);
524 /*STIN*/ ogg_int32_t VFLOAT_ADD(ogg_int32_t a, ogg_int32_t ap,
525 ogg_int32_t b, ogg_int32_t bp,
526 ogg_int32_t *p) nothrow @trusted @nogc {
528 if(!a){
529 *p=bp;
530 return b;
531 }else if(!b){
532 *p=ap;
533 return a;
536 /* yes, this can leak a bit. */
537 if(ap>bp){
538 int shift=ap-bp+1;
539 *p=ap+1;
540 a>>=1;
541 if(shift<32){
542 b=(b+(1<<(shift-1)))>>shift;
543 }else{
544 b=0;
546 }else{
547 int shift=bp-ap+1;
548 *p=bp+1;
549 b>>=1;
550 if(shift<32){
551 a=(a+(1<<(shift-1)))>>shift;
552 }else{
553 a=0;
557 a+=b;
558 if((a&0xc0000000)==0xc0000000 ||
559 (a&0xc0000000)==0){
560 a<<=1;
561 (*p)--;
563 return(a);
567 /* ******************************************************************
568 function: window lookup tables
569 ****************************************************************** */
570 private static immutable LOOKUP_T[32] vwin64 = [
571 X(0x001f0003), X(0x01168c98), X(0x030333c8), X(0x05dfe3a4),
572 X(0x09a49562), X(0x0e45df18), X(0x13b47ef2), X(0x19dcf676),
573 X(0x20a74d83), X(0x27f7137c), X(0x2fabb05a), X(0x37a1105a),
574 X(0x3fb0ab28), X(0x47b2dcd1), X(0x4f807bc6), X(0x56f48e70),
575 X(0x5dedfc79), X(0x64511653), X(0x6a08cfff), X(0x6f079328),
576 X(0x734796f4), X(0x76cab7f2), X(0x7999d6e8), X(0x7bc3cf9f),
577 X(0x7d5c20c1), X(0x7e7961df), X(0x7f33a567), X(0x7fa2e1d0),
578 X(0x7fdd78a5), X(0x7ff6ec6d), X(0x7ffed0e9), X(0x7ffffc3f),
581 private static immutable LOOKUP_T[64] vwin128 = [
582 X(0x0007c04d), X(0x0045bb89), X(0x00c18b87), X(0x017ae294),
583 X(0x02714a4e), X(0x03a4217a), X(0x05129952), X(0x06bbb24f),
584 X(0x089e38a1), X(0x0ab8c073), X(0x0d09a228), X(0x0f8ef6bd),
585 X(0x12469488), X(0x152e0c7a), X(0x1842a81c), X(0x1b81686d),
586 X(0x1ee705d9), X(0x226ff15d), X(0x26185705), X(0x29dc21cc),
587 X(0x2db700fe), X(0x31a46f08), X(0x359fb9c1), X(0x39a40c0c),
588 X(0x3dac78b6), X(0x41b40674), X(0x45b5bcb0), X(0x49acb109),
589 X(0x4d94152b), X(0x516744bd), X(0x5521d320), X(0x58bf98a5),
590 X(0x5c3cbef4), X(0x5f95cc5d), X(0x62c7add7), X(0x65cfbf64),
591 X(0x68abd2ba), X(0x6b5a3405), X(0x6dd9acab), X(0x7029840d),
592 X(0x72497e38), X(0x7439d8ac), X(0x75fb4532), X(0x778ee30a),
593 X(0x78f6367e), X(0x7a331f1a), X(0x7b47cccd), X(0x7c36b416),
594 X(0x7d028192), X(0x7dae0d18), X(0x7e3c4caa), X(0x7eb04763),
595 X(0x7f0d08a7), X(0x7f5593b7), X(0x7f8cd7d5), X(0x7fb5a513),
596 X(0x7fd2a1fc), X(0x7fe64212), X(0x7ff2bd4c), X(0x7ffa0890),
597 X(0x7ffdcf39), X(0x7fff6dac), X(0x7fffed01), X(0x7fffffc4),
600 private static immutable LOOKUP_T[128] vwin256 = [
601 X(0x0001f018), X(0x00117066), X(0x00306e9e), X(0x005ee5f1),
602 X(0x009ccf26), X(0x00ea208b), X(0x0146cdea), X(0x01b2c87f),
603 X(0x022dfedf), X(0x02b85ced), X(0x0351cbbd), X(0x03fa317f),
604 X(0x04b17167), X(0x05776b90), X(0x064bfcdc), X(0x072efedd),
605 X(0x082047b4), X(0x091fa9f1), X(0x0a2cf477), X(0x0b47f25d),
606 X(0x0c706ad2), X(0x0da620ff), X(0x0ee8d3ef), X(0x10383e75),
607 X(0x11941716), X(0x12fc0ff6), X(0x146fd6c8), X(0x15ef14c2),
608 X(0x17796e8e), X(0x190e844f), X(0x1aadf196), X(0x1c574d6e),
609 X(0x1e0a2a62), X(0x1fc61688), X(0x218a9b9c), X(0x23573f12),
610 X(0x252b823d), X(0x2706e269), X(0x28e8d913), X(0x2ad0dc0e),
611 X(0x2cbe5dc1), X(0x2eb0cd60), X(0x30a79733), X(0x32a224d5),
612 X(0x349fdd8b), X(0x36a02690), X(0x38a2636f), X(0x3aa5f65e),
613 X(0x3caa409e), X(0x3eaea2df), X(0x40b27da6), X(0x42b531b8),
614 X(0x44b62086), X(0x46b4ac99), X(0x48b03a05), X(0x4aa82ed5),
615 X(0x4c9bf37d), X(0x4e8af349), X(0x50749ccb), X(0x52586246),
616 X(0x5435ba1c), X(0x560c1f31), X(0x57db1152), X(0x59a21591),
617 X(0x5b60b6a3), X(0x5d168535), X(0x5ec31839), X(0x60660d36),
618 X(0x61ff0886), X(0x638db595), X(0x6511c717), X(0x668af734),
619 X(0x67f907b0), X(0x695bc207), X(0x6ab2f787), X(0x6bfe815a),
620 X(0x6d3e4090), X(0x6e721e16), X(0x6f9a0ab5), X(0x70b5fef8),
621 X(0x71c5fb16), X(0x72ca06cd), X(0x73c2313d), X(0x74ae90b2),
622 X(0x758f4275), X(0x76646a85), X(0x772e335c), X(0x77eccda0),
623 X(0x78a06fd7), X(0x79495613), X(0x79e7c19c), X(0x7a7bf894),
624 X(0x7b064596), X(0x7b86f757), X(0x7bfe6044), X(0x7c6cd615),
625 X(0x7cd2b16e), X(0x7d304d71), X(0x7d860756), X(0x7dd43e06),
626 X(0x7e1b51ad), X(0x7e5ba355), X(0x7e95947e), X(0x7ec986bb),
627 X(0x7ef7db4a), X(0x7f20f2b9), X(0x7f452c7f), X(0x7f64e6a7),
628 X(0x7f807d71), X(0x7f984aff), X(0x7faca700), X(0x7fbde662),
629 X(0x7fcc5b04), X(0x7fd85372), X(0x7fe21a99), X(0x7fe9f791),
630 X(0x7ff02d58), X(0x7ff4fa9e), X(0x7ff89990), X(0x7ffb3faa),
631 X(0x7ffd1d8b), X(0x7ffe5ecc), X(0x7fff29e0), X(0x7fff9ff3),
632 X(0x7fffdcd2), X(0x7ffff6d6), X(0x7ffffed0), X(0x7ffffffc),
635 private static immutable LOOKUP_T[256] vwin512 = [
636 X(0x00007c06), X(0x00045c32), X(0x000c1c62), X(0x0017bc4c),
637 X(0x00273b7a), X(0x003a9955), X(0x0051d51c), X(0x006cede7),
638 X(0x008be2a9), X(0x00aeb22a), X(0x00d55b0d), X(0x00ffdbcc),
639 X(0x012e32b6), X(0x01605df5), X(0x01965b85), X(0x01d02939),
640 X(0x020dc4ba), X(0x024f2b83), X(0x02945ae6), X(0x02dd5004),
641 X(0x032a07d3), X(0x037a7f19), X(0x03ceb26e), X(0x04269e37),
642 X(0x04823eab), X(0x04e18fcc), X(0x05448d6d), X(0x05ab3329),
643 X(0x06157c68), X(0x0683645e), X(0x06f4e607), X(0x0769fc25),
644 X(0x07e2a146), X(0x085ecfbc), X(0x08de819f), X(0x0961b0cc),
645 X(0x09e856e3), X(0x0a726d46), X(0x0affed1d), X(0x0b90cf4c),
646 X(0x0c250c79), X(0x0cbc9d0b), X(0x0d577926), X(0x0df598aa),
647 X(0x0e96f337), X(0x0f3b8026), X(0x0fe3368f), X(0x108e0d42),
648 X(0x113bfaca), X(0x11ecf56b), X(0x12a0f324), X(0x1357e9ac),
649 X(0x1411ce70), X(0x14ce9698), X(0x158e3702), X(0x1650a444),
650 X(0x1715d2aa), X(0x17ddb638), X(0x18a842aa), X(0x19756b72),
651 X(0x1a4523b9), X(0x1b175e62), X(0x1bec0e04), X(0x1cc324f0),
652 X(0x1d9c9532), X(0x1e78508a), X(0x1f564876), X(0x20366e2e),
653 X(0x2118b2a2), X(0x21fd0681), X(0x22e35a37), X(0x23cb9dee),
654 X(0x24b5c18e), X(0x25a1b4c0), X(0x268f66f1), X(0x277ec74e),
655 X(0x286fc4cc), X(0x29624e23), X(0x2a5651d7), X(0x2b4bbe34),
656 X(0x2c428150), X(0x2d3a8913), X(0x2e33c332), X(0x2f2e1d35),
657 X(0x30298478), X(0x3125e62d), X(0x32232f61), X(0x33214cfc),
658 X(0x34202bc2), X(0x351fb85a), X(0x361fdf4f), X(0x37208d10),
659 X(0x3821adf7), X(0x39232e49), X(0x3a24fa3c), X(0x3b26fdf6),
660 X(0x3c292593), X(0x3d2b5d29), X(0x3e2d90c8), X(0x3f2fac7f),
661 X(0x40319c5f), X(0x41334c81), X(0x4234a905), X(0x43359e16),
662 X(0x443617f3), X(0x453602eb), X(0x46354b65), X(0x4733dde1),
663 X(0x4831a6ff), X(0x492e937f), X(0x4a2a9045), X(0x4b258a5f),
664 X(0x4c1f6f06), X(0x4d182ba2), X(0x4e0fadce), X(0x4f05e35b),
665 X(0x4ffaba53), X(0x50ee20fd), X(0x51e005e1), X(0x52d057ca),
666 X(0x53bf05ca), X(0x54abff3b), X(0x559733c7), X(0x56809365),
667 X(0x57680e62), X(0x584d955d), X(0x59311952), X(0x5a128b96),
668 X(0x5af1dddd), X(0x5bcf023a), X(0x5ca9eb27), X(0x5d828b81),
669 X(0x5e58d68d), X(0x5f2cbffc), X(0x5ffe3be9), X(0x60cd3edf),
670 X(0x6199bdda), X(0x6263ae45), X(0x632b0602), X(0x63efbb66),
671 X(0x64b1c53f), X(0x65711ad0), X(0x662db3d7), X(0x66e7888d),
672 X(0x679e91a5), X(0x6852c84e), X(0x69042635), X(0x69b2a582),
673 X(0x6a5e40dd), X(0x6b06f36c), X(0x6bacb8d2), X(0x6c4f8d30),
674 X(0x6cef6d26), X(0x6d8c55d4), X(0x6e2644d4), X(0x6ebd3840),
675 X(0x6f512ead), X(0x6fe2272e), X(0x7070214f), X(0x70fb1d17),
676 X(0x71831b06), X(0x72081c16), X(0x728a21b5), X(0x73092dc8),
677 X(0x738542a6), X(0x73fe631b), X(0x74749261), X(0x74e7d421),
678 X(0x75582c72), X(0x75c59fd5), X(0x76303333), X(0x7697ebdd),
679 X(0x76fccf85), X(0x775ee443), X(0x77be308a), X(0x781abb2e),
680 X(0x78748b59), X(0x78cba88e), X(0x79201aa7), X(0x7971e9cd),
681 X(0x79c11e79), X(0x7a0dc170), X(0x7a57dbc2), X(0x7a9f76c1),
682 X(0x7ae49c07), X(0x7b27556b), X(0x7b67ad02), X(0x7ba5ad1b),
683 X(0x7be1603a), X(0x7c1ad118), X(0x7c520a9e), X(0x7c8717e1),
684 X(0x7cba0421), X(0x7ceadac3), X(0x7d19a74f), X(0x7d46756e),
685 X(0x7d7150e5), X(0x7d9a4592), X(0x7dc15f69), X(0x7de6aa71),
686 X(0x7e0a32c0), X(0x7e2c0479), X(0x7e4c2bc7), X(0x7e6ab4db),
687 X(0x7e87abe9), X(0x7ea31d24), X(0x7ebd14be), X(0x7ed59edd),
688 X(0x7eecc7a3), X(0x7f029b21), X(0x7f17255a), X(0x7f2a723f),
689 X(0x7f3c8daa), X(0x7f4d835d), X(0x7f5d5f00), X(0x7f6c2c1b),
690 X(0x7f79f617), X(0x7f86c83a), X(0x7f92ada2), X(0x7f9db146),
691 X(0x7fa7ddf3), X(0x7fb13e46), X(0x7fb9dcb0), X(0x7fc1c36c),
692 X(0x7fc8fc83), X(0x7fcf91c7), X(0x7fd58cd2), X(0x7fdaf702),
693 X(0x7fdfd979), X(0x7fe43d1c), X(0x7fe82a8b), X(0x7febaa29),
694 X(0x7feec412), X(0x7ff1801c), X(0x7ff3e5d6), X(0x7ff5fc86),
695 X(0x7ff7cb29), X(0x7ff9586f), X(0x7ffaaaba), X(0x7ffbc81e),
696 X(0x7ffcb660), X(0x7ffd7af3), X(0x7ffe1afa), X(0x7ffe9b42),
697 X(0x7fff0047), X(0x7fff4e2f), X(0x7fff88c9), X(0x7fffb390),
698 X(0x7fffd1a6), X(0x7fffe5d7), X(0x7ffff296), X(0x7ffff9fd),
699 X(0x7ffffdcd), X(0x7fffff6d), X(0x7fffffed), X(0x7fffffff),
702 private static immutable LOOKUP_T[512] vwin1024 = [
703 X(0x00001f02), X(0x0001170e), X(0x00030724), X(0x0005ef40),
704 X(0x0009cf59), X(0x000ea767), X(0x0014775e), X(0x001b3f2e),
705 X(0x0022fec8), X(0x002bb618), X(0x00356508), X(0x00400b81),
706 X(0x004ba968), X(0x00583ea0), X(0x0065cb0a), X(0x00744e84),
707 X(0x0083c8ea), X(0x00943a14), X(0x00a5a1da), X(0x00b80010),
708 X(0x00cb5488), X(0x00df9f10), X(0x00f4df76), X(0x010b1584),
709 X(0x01224101), X(0x013a61b2), X(0x01537759), X(0x016d81b6),
710 X(0x01888087), X(0x01a47385), X(0x01c15a69), X(0x01df34e6),
711 X(0x01fe02b1), X(0x021dc377), X(0x023e76e7), X(0x02601ca9),
712 X(0x0282b466), X(0x02a63dc1), X(0x02cab85d), X(0x02f023d6),
713 X(0x03167fcb), X(0x033dcbd3), X(0x03660783), X(0x038f3270),
714 X(0x03b94c29), X(0x03e4543a), X(0x04104a2e), X(0x043d2d8b),
715 X(0x046afdd5), X(0x0499ba8c), X(0x04c9632d), X(0x04f9f734),
716 X(0x052b7615), X(0x055ddf46), X(0x05913237), X(0x05c56e53),
717 X(0x05fa9306), X(0x06309fb6), X(0x066793c5), X(0x069f6e93),
718 X(0x06d82f7c), X(0x0711d5d9), X(0x074c60fe), X(0x0787d03d),
719 X(0x07c422e4), X(0x0801583e), X(0x083f6f91), X(0x087e681f),
720 X(0x08be4129), X(0x08fef9ea), X(0x0940919a), X(0x0983076d),
721 X(0x09c65a92), X(0x0a0a8a38), X(0x0a4f9585), X(0x0a957b9f),
722 X(0x0adc3ba7), X(0x0b23d4b9), X(0x0b6c45ee), X(0x0bb58e5a),
723 X(0x0bffad0f), X(0x0c4aa11a), X(0x0c966982), X(0x0ce3054d),
724 X(0x0d30737b), X(0x0d7eb308), X(0x0dcdc2eb), X(0x0e1da21a),
725 X(0x0e6e4f83), X(0x0ebfca11), X(0x0f1210ad), X(0x0f652238),
726 X(0x0fb8fd91), X(0x100da192), X(0x10630d11), X(0x10b93ee0),
727 X(0x111035cb), X(0x1167f09a), X(0x11c06e13), X(0x1219acf5),
728 X(0x1273abfb), X(0x12ce69db), X(0x1329e54a), X(0x13861cf3),
729 X(0x13e30f80), X(0x1440bb97), X(0x149f1fd8), X(0x14fe3ade),
730 X(0x155e0b40), X(0x15be8f92), X(0x161fc662), X(0x1681ae38),
731 X(0x16e4459b), X(0x17478b0b), X(0x17ab7d03), X(0x181019fb),
732 X(0x18756067), X(0x18db4eb3), X(0x1941e34a), X(0x19a91c92),
733 X(0x1a10f8ea), X(0x1a7976af), X(0x1ae29439), X(0x1b4c4fda),
734 X(0x1bb6a7e2), X(0x1c219a9a), X(0x1c8d2649), X(0x1cf9492e),
735 X(0x1d660188), X(0x1dd34d8e), X(0x1e412b74), X(0x1eaf996a),
736 X(0x1f1e959b), X(0x1f8e1e2f), X(0x1ffe3146), X(0x206ecd01),
737 X(0x20dfef78), X(0x215196c2), X(0x21c3c0f0), X(0x22366c10),
738 X(0x22a9962a), X(0x231d3d45), X(0x23915f60), X(0x2405fa7a),
739 X(0x247b0c8c), X(0x24f09389), X(0x25668d65), X(0x25dcf80c),
740 X(0x2653d167), X(0x26cb175e), X(0x2742c7d0), X(0x27bae09e),
741 X(0x28335fa2), X(0x28ac42b3), X(0x292587a5), X(0x299f2c48),
742 X(0x2a192e69), X(0x2a938bd1), X(0x2b0e4247), X(0x2b894f8d),
743 X(0x2c04b164), X(0x2c806588), X(0x2cfc69b2), X(0x2d78bb9a),
744 X(0x2df558f4), X(0x2e723f6f), X(0x2eef6cbb), X(0x2f6cde83),
745 X(0x2fea9270), X(0x30688627), X(0x30e6b74e), X(0x31652385),
746 X(0x31e3c86b), X(0x3262a39e), X(0x32e1b2b8), X(0x3360f352),
747 X(0x33e06303), X(0x345fff5e), X(0x34dfc5f8), X(0x355fb462),
748 X(0x35dfc82a), X(0x365ffee0), X(0x36e0560f), X(0x3760cb43),
749 X(0x37e15c05), X(0x386205df), X(0x38e2c657), X(0x39639af5),
750 X(0x39e4813e), X(0x3a6576b6), X(0x3ae678e3), X(0x3b678547),
751 X(0x3be89965), X(0x3c69b2c1), X(0x3ceacedc), X(0x3d6beb37),
752 X(0x3ded0557), X(0x3e6e1abb), X(0x3eef28e6), X(0x3f702d5a),
753 X(0x3ff1259a), X(0x40720f29), X(0x40f2e789), X(0x4173ac3f),
754 X(0x41f45ad0), X(0x4274f0c2), X(0x42f56b9a), X(0x4375c8e0),
755 X(0x43f6061d), X(0x447620db), X(0x44f616a5), X(0x4575e509),
756 X(0x45f58994), X(0x467501d6), X(0x46f44b62), X(0x477363cb),
757 X(0x47f248a6), X(0x4870f78e), X(0x48ef6e1a), X(0x496da9e8),
758 X(0x49eba897), X(0x4a6967c8), X(0x4ae6e521), X(0x4b641e47),
759 X(0x4be110e5), X(0x4c5dbaa7), X(0x4cda193f), X(0x4d562a5f),
760 X(0x4dd1ebbd), X(0x4e4d5b15), X(0x4ec87623), X(0x4f433aa9),
761 X(0x4fbda66c), X(0x5037b734), X(0x50b16acf), X(0x512abf0e),
762 X(0x51a3b1c5), X(0x521c40ce), X(0x52946a06), X(0x530c2b50),
763 X(0x53838292), X(0x53fa6db8), X(0x5470eab3), X(0x54e6f776),
764 X(0x555c91fc), X(0x55d1b844), X(0x56466851), X(0x56baa02f),
765 X(0x572e5deb), X(0x57a19f98), X(0x58146352), X(0x5886a737),
766 X(0x58f8696d), X(0x5969a81c), X(0x59da6177), X(0x5a4a93b4),
767 X(0x5aba3d0f), X(0x5b295bcb), X(0x5b97ee30), X(0x5c05f28d),
768 X(0x5c736738), X(0x5ce04a8d), X(0x5d4c9aed), X(0x5db856c1),
769 X(0x5e237c78), X(0x5e8e0a89), X(0x5ef7ff6f), X(0x5f6159b0),
770 X(0x5fca17d4), X(0x6032386e), X(0x6099ba15), X(0x61009b69),
771 X(0x6166db11), X(0x61cc77b9), X(0x62317017), X(0x6295c2e7),
772 X(0x62f96eec), X(0x635c72f1), X(0x63becdc8), X(0x64207e4b),
773 X(0x6481835a), X(0x64e1dbde), X(0x654186c8), X(0x65a0830e),
774 X(0x65fecfb1), X(0x665c6bb7), X(0x66b95630), X(0x67158e30),
775 X(0x677112d7), X(0x67cbe34b), X(0x6825feb9), X(0x687f6456),
776 X(0x68d81361), X(0x69300b1e), X(0x69874ada), X(0x69ddd1ea),
777 X(0x6a339fab), X(0x6a88b382), X(0x6add0cdb), X(0x6b30ab2a),
778 X(0x6b838dec), X(0x6bd5b4a6), X(0x6c271ee2), X(0x6c77cc36),
779 X(0x6cc7bc3d), X(0x6d16ee9b), X(0x6d6562fb), X(0x6db31911),
780 X(0x6e001099), X(0x6e4c4955), X(0x6e97c311), X(0x6ee27d9f),
781 X(0x6f2c78d9), X(0x6f75b4a2), X(0x6fbe30e4), X(0x7005ed91),
782 X(0x704ceaa1), X(0x70932816), X(0x70d8a5f8), X(0x711d6457),
783 X(0x7161634b), X(0x71a4a2f3), X(0x71e72375), X(0x7228e500),
784 X(0x7269e7c8), X(0x72aa2c0a), X(0x72e9b209), X(0x73287a12),
785 X(0x73668476), X(0x73a3d18f), X(0x73e061bc), X(0x741c3566),
786 X(0x74574cfa), X(0x7491a8ee), X(0x74cb49be), X(0x75042fec),
787 X(0x753c5c03), X(0x7573ce92), X(0x75aa882f), X(0x75e08979),
788 X(0x7615d313), X(0x764a65a7), X(0x767e41e5), X(0x76b16884),
789 X(0x76e3da40), X(0x771597dc), X(0x7746a221), X(0x7776f9dd),
790 X(0x77a69fe6), X(0x77d59514), X(0x7803da49), X(0x7831706a),
791 X(0x785e5861), X(0x788a9320), X(0x78b6219c), X(0x78e104cf),
792 X(0x790b3dbb), X(0x7934cd64), X(0x795db4d5), X(0x7985f51d),
793 X(0x79ad8f50), X(0x79d48486), X(0x79fad5de), X(0x7a208478),
794 X(0x7a45917b), X(0x7a69fe12), X(0x7a8dcb6c), X(0x7ab0fabb),
795 X(0x7ad38d36), X(0x7af5841a), X(0x7b16e0a3), X(0x7b37a416),
796 X(0x7b57cfb8), X(0x7b7764d4), X(0x7b9664b6), X(0x7bb4d0b0),
797 X(0x7bd2aa14), X(0x7beff23b), X(0x7c0caa7f), X(0x7c28d43c),
798 X(0x7c4470d2), X(0x7c5f81a5), X(0x7c7a081a), X(0x7c940598),
799 X(0x7cad7b8b), X(0x7cc66b5e), X(0x7cded680), X(0x7cf6be64),
800 X(0x7d0e247b), X(0x7d250a3c), X(0x7d3b711c), X(0x7d515a95),
801 X(0x7d66c822), X(0x7d7bbb3c), X(0x7d903563), X(0x7da43814),
802 X(0x7db7c4d0), X(0x7dcadd16), X(0x7ddd826a), X(0x7defb64d),
803 X(0x7e017a44), X(0x7e12cfd3), X(0x7e23b87f), X(0x7e3435cc),
804 X(0x7e444943), X(0x7e53f467), X(0x7e6338c0), X(0x7e7217d5),
805 X(0x7e80932b), X(0x7e8eac49), X(0x7e9c64b7), X(0x7ea9bdf8),
806 X(0x7eb6b994), X(0x7ec35910), X(0x7ecf9def), X(0x7edb89b6),
807 X(0x7ee71de9), X(0x7ef25c09), X(0x7efd4598), X(0x7f07dc16),
808 X(0x7f122103), X(0x7f1c15dc), X(0x7f25bc1f), X(0x7f2f1547),
809 X(0x7f3822cd), X(0x7f40e62b), X(0x7f4960d6), X(0x7f519443),
810 X(0x7f5981e7), X(0x7f612b31), X(0x7f689191), X(0x7f6fb674),
811 X(0x7f769b45), X(0x7f7d416c), X(0x7f83aa51), X(0x7f89d757),
812 X(0x7f8fc9df), X(0x7f958348), X(0x7f9b04ef), X(0x7fa0502e),
813 X(0x7fa56659), X(0x7faa48c7), X(0x7faef8c7), X(0x7fb377a7),
814 X(0x7fb7c6b3), X(0x7fbbe732), X(0x7fbfda67), X(0x7fc3a196),
815 X(0x7fc73dfa), X(0x7fcab0ce), X(0x7fcdfb4a), X(0x7fd11ea0),
816 X(0x7fd41c00), X(0x7fd6f496), X(0x7fd9a989), X(0x7fdc3bff),
817 X(0x7fdead17), X(0x7fe0fdee), X(0x7fe32f9d), X(0x7fe54337),
818 X(0x7fe739ce), X(0x7fe9146c), X(0x7fead41b), X(0x7fec79dd),
819 X(0x7fee06b2), X(0x7fef7b94), X(0x7ff0d97b), X(0x7ff22158),
820 X(0x7ff35417), X(0x7ff472a3), X(0x7ff57de0), X(0x7ff676ac),
821 X(0x7ff75de3), X(0x7ff8345a), X(0x7ff8fae4), X(0x7ff9b24b),
822 X(0x7ffa5b58), X(0x7ffaf6cd), X(0x7ffb8568), X(0x7ffc07e2),
823 X(0x7ffc7eed), X(0x7ffceb38), X(0x7ffd4d6d), X(0x7ffda631),
824 X(0x7ffdf621), X(0x7ffe3dd8), X(0x7ffe7dea), X(0x7ffeb6e7),
825 X(0x7ffee959), X(0x7fff15c4), X(0x7fff3ca9), X(0x7fff5e80),
826 X(0x7fff7bc0), X(0x7fff94d6), X(0x7fffaa2d), X(0x7fffbc29),
827 X(0x7fffcb29), X(0x7fffd786), X(0x7fffe195), X(0x7fffe9a3),
828 X(0x7fffeffa), X(0x7ffff4dd), X(0x7ffff889), X(0x7ffffb37),
829 X(0x7ffffd1a), X(0x7ffffe5d), X(0x7fffff29), X(0x7fffffa0),
830 X(0x7fffffdd), X(0x7ffffff7), X(0x7fffffff), X(0x7fffffff),
833 private static immutable LOOKUP_T[1024] vwin2048 = [
834 X(0x000007c0), X(0x000045c4), X(0x0000c1ca), X(0x00017bd3),
835 X(0x000273de), X(0x0003a9eb), X(0x00051df9), X(0x0006d007),
836 X(0x0008c014), X(0x000aee1e), X(0x000d5a25), X(0x00100428),
837 X(0x0012ec23), X(0x00161216), X(0x001975fe), X(0x001d17da),
838 X(0x0020f7a8), X(0x00251564), X(0x0029710c), X(0x002e0a9e),
839 X(0x0032e217), X(0x0037f773), X(0x003d4ab0), X(0x0042dbca),
840 X(0x0048aabe), X(0x004eb788), X(0x00550224), X(0x005b8a8f),
841 X(0x006250c5), X(0x006954c1), X(0x0070967e), X(0x007815f9),
842 X(0x007fd32c), X(0x0087ce13), X(0x009006a9), X(0x00987ce9),
843 X(0x00a130cc), X(0x00aa224f), X(0x00b3516b), X(0x00bcbe1a),
844 X(0x00c66856), X(0x00d0501a), X(0x00da755f), X(0x00e4d81f),
845 X(0x00ef7853), X(0x00fa55f4), X(0x010570fc), X(0x0110c963),
846 X(0x011c5f22), X(0x01283232), X(0x0134428c), X(0x01409027),
847 X(0x014d1afb), X(0x0159e302), X(0x0166e831), X(0x01742a82),
848 X(0x0181a9ec), X(0x018f6665), X(0x019d5fe5), X(0x01ab9663),
849 X(0x01ba09d6), X(0x01c8ba34), X(0x01d7a775), X(0x01e6d18d),
850 X(0x01f63873), X(0x0205dc1e), X(0x0215bc82), X(0x0225d997),
851 X(0x02363350), X(0x0246c9a3), X(0x02579c86), X(0x0268abed),
852 X(0x0279f7cc), X(0x028b801a), X(0x029d44c9), X(0x02af45ce),
853 X(0x02c1831d), X(0x02d3fcaa), X(0x02e6b269), X(0x02f9a44c),
854 X(0x030cd248), X(0x03203c4f), X(0x0333e255), X(0x0347c44b),
855 X(0x035be225), X(0x03703bd5), X(0x0384d14d), X(0x0399a280),
856 X(0x03aeaf5e), X(0x03c3f7d9), X(0x03d97be4), X(0x03ef3b6e),
857 X(0x0405366a), X(0x041b6cc8), X(0x0431de78), X(0x04488b6c),
858 X(0x045f7393), X(0x047696dd), X(0x048df53b), X(0x04a58e9b),
859 X(0x04bd62ee), X(0x04d57223), X(0x04edbc28), X(0x050640ed),
860 X(0x051f0060), X(0x0537fa70), X(0x05512f0a), X(0x056a9e1e),
861 X(0x05844798), X(0x059e2b67), X(0x05b84978), X(0x05d2a1b8),
862 X(0x05ed3414), X(0x06080079), X(0x062306d3), X(0x063e470f),
863 X(0x0659c119), X(0x067574dd), X(0x06916247), X(0x06ad8941),
864 X(0x06c9e9b8), X(0x06e68397), X(0x070356c8), X(0x07206336),
865 X(0x073da8cb), X(0x075b2772), X(0x0778df15), X(0x0796cf9c),
866 X(0x07b4f8f3), X(0x07d35b01), X(0x07f1f5b1), X(0x0810c8eb),
867 X(0x082fd497), X(0x084f189e), X(0x086e94e9), X(0x088e495e),
868 X(0x08ae35e6), X(0x08ce5a68), X(0x08eeb6cc), X(0x090f4af8),
869 X(0x093016d3), X(0x09511a44), X(0x09725530), X(0x0993c77f),
870 X(0x09b57115), X(0x09d751d8), X(0x09f969ae), X(0x0a1bb87c),
871 X(0x0a3e3e26), X(0x0a60fa91), X(0x0a83eda2), X(0x0aa7173c),
872 X(0x0aca7743), X(0x0aee0d9b), X(0x0b11da28), X(0x0b35dccc),
873 X(0x0b5a156a), X(0x0b7e83e5), X(0x0ba3281f), X(0x0bc801fa),
874 X(0x0bed1159), X(0x0c12561c), X(0x0c37d025), X(0x0c5d7f55),
875 X(0x0c83638d), X(0x0ca97cae), X(0x0ccfca97), X(0x0cf64d2a),
876 X(0x0d1d0444), X(0x0d43efc7), X(0x0d6b0f92), X(0x0d926383),
877 X(0x0db9eb79), X(0x0de1a752), X(0x0e0996ee), X(0x0e31ba29),
878 X(0x0e5a10e2), X(0x0e829af6), X(0x0eab5841), X(0x0ed448a2),
879 X(0x0efd6bf4), X(0x0f26c214), X(0x0f504ade), X(0x0f7a062e),
880 X(0x0fa3f3df), X(0x0fce13cd), X(0x0ff865d2), X(0x1022e9ca),
881 X(0x104d9f8e), X(0x107886f9), X(0x10a39fe5), X(0x10ceea2c),
882 X(0x10fa65a6), X(0x1126122d), X(0x1151ef9a), X(0x117dfdc5),
883 X(0x11aa3c87), X(0x11d6abb6), X(0x12034b2c), X(0x12301ac0),
884 X(0x125d1a48), X(0x128a499b), X(0x12b7a891), X(0x12e536ff),
885 X(0x1312f4bb), X(0x1340e19c), X(0x136efd75), X(0x139d481e),
886 X(0x13cbc16a), X(0x13fa692f), X(0x14293f40), X(0x14584371),
887 X(0x14877597), X(0x14b6d585), X(0x14e6630d), X(0x15161e04),
888 X(0x1546063b), X(0x15761b85), X(0x15a65db3), X(0x15d6cc99),
889 X(0x16076806), X(0x16382fcd), X(0x166923bf), X(0x169a43ab),
890 X(0x16cb8f62), X(0x16fd06b5), X(0x172ea973), X(0x1760776b),
891 X(0x1792706e), X(0x17c49449), X(0x17f6e2cb), X(0x18295bc3),
892 X(0x185bfeff), X(0x188ecc4c), X(0x18c1c379), X(0x18f4e452),
893 X(0x19282ea4), X(0x195ba23c), X(0x198f3ee6), X(0x19c3046e),
894 X(0x19f6f2a1), X(0x1a2b094a), X(0x1a5f4833), X(0x1a93af28),
895 X(0x1ac83df3), X(0x1afcf460), X(0x1b31d237), X(0x1b66d744),
896 X(0x1b9c034e), X(0x1bd15621), X(0x1c06cf84), X(0x1c3c6f40),
897 X(0x1c72351e), X(0x1ca820e6), X(0x1cde3260), X(0x1d146953),
898 X(0x1d4ac587), X(0x1d8146c3), X(0x1db7eccd), X(0x1deeb76c),
899 X(0x1e25a667), X(0x1e5cb982), X(0x1e93f085), X(0x1ecb4b33),
900 X(0x1f02c953), X(0x1f3a6aaa), X(0x1f722efb), X(0x1faa160b),
901 X(0x1fe21f9e), X(0x201a4b79), X(0x2052995d), X(0x208b0910),
902 X(0x20c39a53), X(0x20fc4cea), X(0x21352097), X(0x216e151c),
903 X(0x21a72a3a), X(0x21e05fb5), X(0x2219b54d), X(0x22532ac3),
904 X(0x228cbfd8), X(0x22c6744d), X(0x230047e2), X(0x233a3a58),
905 X(0x23744b6d), X(0x23ae7ae3), X(0x23e8c878), X(0x242333ec),
906 X(0x245dbcfd), X(0x24986369), X(0x24d326f1), X(0x250e0750),
907 X(0x25490446), X(0x25841d90), X(0x25bf52ec), X(0x25faa417),
908 X(0x263610cd), X(0x267198cc), X(0x26ad3bcf), X(0x26e8f994),
909 X(0x2724d1d6), X(0x2760c451), X(0x279cd0c0), X(0x27d8f6e0),
910 X(0x2815366a), X(0x28518f1b), X(0x288e00ac), X(0x28ca8ad8),
911 X(0x29072d5a), X(0x2943e7eb), X(0x2980ba45), X(0x29bda422),
912 X(0x29faa53c), X(0x2a37bd4a), X(0x2a74ec07), X(0x2ab2312b),
913 X(0x2aef8c6f), X(0x2b2cfd8b), X(0x2b6a8437), X(0x2ba8202c),
914 X(0x2be5d120), X(0x2c2396cc), X(0x2c6170e7), X(0x2c9f5f29),
915 X(0x2cdd6147), X(0x2d1b76fa), X(0x2d599ff7), X(0x2d97dbf5),
916 X(0x2dd62aab), X(0x2e148bcf), X(0x2e52ff16), X(0x2e918436),
917 X(0x2ed01ae5), X(0x2f0ec2d9), X(0x2f4d7bc6), X(0x2f8c4562),
918 X(0x2fcb1f62), X(0x300a097a), X(0x3049035f), X(0x30880cc6),
919 X(0x30c72563), X(0x31064cea), X(0x3145830f), X(0x3184c786),
920 X(0x31c41a03), X(0x32037a39), X(0x3242e7dc), X(0x3282629f),
921 X(0x32c1ea36), X(0x33017e53), X(0x33411ea9), X(0x3380caec),
922 X(0x33c082ce), X(0x34004602), X(0x34401439), X(0x347fed27),
923 X(0x34bfd07e), X(0x34ffbdf0), X(0x353fb52e), X(0x357fb5ec),
924 X(0x35bfbfda), X(0x35ffd2aa), X(0x363fee0f), X(0x368011b9),
925 X(0x36c03d5a), X(0x370070a4), X(0x3740ab48), X(0x3780ecf7),
926 X(0x37c13562), X(0x3801843a), X(0x3841d931), X(0x388233f7),
927 X(0x38c2943d), X(0x3902f9b4), X(0x3943640d), X(0x3983d2f8),
928 X(0x39c44626), X(0x3a04bd48), X(0x3a45380e), X(0x3a85b62a),
929 X(0x3ac6374a), X(0x3b06bb20), X(0x3b47415c), X(0x3b87c9ae),
930 X(0x3bc853c7), X(0x3c08df57), X(0x3c496c0f), X(0x3c89f99f),
931 X(0x3cca87b6), X(0x3d0b1605), X(0x3d4ba43d), X(0x3d8c320e),
932 X(0x3dccbf27), X(0x3e0d4b3a), X(0x3e4dd5f6), X(0x3e8e5f0c),
933 X(0x3ecee62b), X(0x3f0f6b05), X(0x3f4fed49), X(0x3f906ca8),
934 X(0x3fd0e8d2), X(0x40116177), X(0x4051d648), X(0x409246f6),
935 X(0x40d2b330), X(0x41131aa7), X(0x41537d0c), X(0x4193da10),
936 X(0x41d43162), X(0x421482b4), X(0x4254cdb7), X(0x4295121b),
937 X(0x42d54f91), X(0x431585ca), X(0x4355b477), X(0x4395db49),
938 X(0x43d5f9f1), X(0x44161021), X(0x44561d8a), X(0x449621dd),
939 X(0x44d61ccc), X(0x45160e08), X(0x4555f544), X(0x4595d230),
940 X(0x45d5a47f), X(0x46156be3), X(0x4655280e), X(0x4694d8b2),
941 X(0x46d47d82), X(0x4714162f), X(0x4753a26d), X(0x479321ef),
942 X(0x47d29466), X(0x4811f987), X(0x48515104), X(0x48909a91),
943 X(0x48cfd5e1), X(0x490f02a7), X(0x494e2098), X(0x498d2f66),
944 X(0x49cc2ec7), X(0x4a0b1e6f), X(0x4a49fe11), X(0x4a88cd62),
945 X(0x4ac78c18), X(0x4b0639e6), X(0x4b44d683), X(0x4b8361a2),
946 X(0x4bc1dafa), X(0x4c004241), X(0x4c3e972c), X(0x4c7cd970),
947 X(0x4cbb08c5), X(0x4cf924e1), X(0x4d372d7a), X(0x4d752247),
948 X(0x4db30300), X(0x4df0cf5a), X(0x4e2e870f), X(0x4e6c29d6),
949 X(0x4ea9b766), X(0x4ee72f78), X(0x4f2491c4), X(0x4f61de02),
950 X(0x4f9f13ec), X(0x4fdc333b), X(0x50193ba8), X(0x50562ced),
951 X(0x509306c3), X(0x50cfc8e5), X(0x510c730d), X(0x514904f6),
952 X(0x51857e5a), X(0x51c1def5), X(0x51fe2682), X(0x523a54bc),
953 X(0x52766961), X(0x52b2642c), X(0x52ee44d9), X(0x532a0b26),
954 X(0x5365b6d0), X(0x53a14793), X(0x53dcbd2f), X(0x54181760),
955 X(0x545355e5), X(0x548e787d), X(0x54c97ee6), X(0x550468e1),
956 X(0x553f362c), X(0x5579e687), X(0x55b479b3), X(0x55eeef70),
957 X(0x5629477f), X(0x566381a1), X(0x569d9d97), X(0x56d79b24),
958 X(0x57117a0a), X(0x574b3a0a), X(0x5784dae9), X(0x57be5c69),
959 X(0x57f7be4d), X(0x5831005a), X(0x586a2254), X(0x58a32400),
960 X(0x58dc0522), X(0x5914c57f), X(0x594d64de), X(0x5985e305),
961 X(0x59be3fba), X(0x59f67ac3), X(0x5a2e93e9), X(0x5a668af2),
962 X(0x5a9e5fa6), X(0x5ad611ce), X(0x5b0da133), X(0x5b450d9d),
963 X(0x5b7c56d7), X(0x5bb37ca9), X(0x5bea7ede), X(0x5c215d41),
964 X(0x5c58179d), X(0x5c8eadbe), X(0x5cc51f6f), X(0x5cfb6c7c),
965 X(0x5d3194b2), X(0x5d6797de), X(0x5d9d75cf), X(0x5dd32e51),
966 X(0x5e08c132), X(0x5e3e2e43), X(0x5e737551), X(0x5ea8962d),
967 X(0x5edd90a7), X(0x5f12648e), X(0x5f4711b4), X(0x5f7b97ea),
968 X(0x5faff702), X(0x5fe42ece), X(0x60183f20), X(0x604c27cc),
969 X(0x607fe8a6), X(0x60b38180), X(0x60e6f22f), X(0x611a3a89),
970 X(0x614d5a62), X(0x61805190), X(0x61b31fe9), X(0x61e5c545),
971 X(0x62184179), X(0x624a945d), X(0x627cbdca), X(0x62aebd98),
972 X(0x62e0939f), X(0x63123fba), X(0x6343c1c1), X(0x6375198f),
973 X(0x63a646ff), X(0x63d749ec), X(0x64082232), X(0x6438cfad),
974 X(0x64695238), X(0x6499a9b3), X(0x64c9d5f9), X(0x64f9d6ea),
975 X(0x6529ac63), X(0x65595643), X(0x6588d46a), X(0x65b826b8),
976 X(0x65e74d0e), X(0x6616474b), X(0x66451552), X(0x6673b704),
977 X(0x66a22c44), X(0x66d074f4), X(0x66fe90f8), X(0x672c8033),
978 X(0x675a428a), X(0x6787d7e1), X(0x67b5401f), X(0x67e27b27),
979 X(0x680f88e1), X(0x683c6934), X(0x68691c05), X(0x6895a13e),
980 X(0x68c1f8c7), X(0x68ee2287), X(0x691a1e68), X(0x6945ec54),
981 X(0x69718c35), X(0x699cfdf5), X(0x69c8417f), X(0x69f356c0),
982 X(0x6a1e3da3), X(0x6a48f615), X(0x6a738002), X(0x6a9ddb5a),
983 X(0x6ac80808), X(0x6af205fd), X(0x6b1bd526), X(0x6b457575),
984 X(0x6b6ee6d8), X(0x6b982940), X(0x6bc13c9f), X(0x6bea20e5),
985 X(0x6c12d605), X(0x6c3b5bf1), X(0x6c63b29c), X(0x6c8bd9fb),
986 X(0x6cb3d200), X(0x6cdb9aa0), X(0x6d0333d0), X(0x6d2a9d86),
987 X(0x6d51d7b7), X(0x6d78e25a), X(0x6d9fbd67), X(0x6dc668d3),
988 X(0x6dece498), X(0x6e1330ad), X(0x6e394d0c), X(0x6e5f39ae),
989 X(0x6e84f68d), X(0x6eaa83a2), X(0x6ecfe0ea), X(0x6ef50e5e),
990 X(0x6f1a0bfc), X(0x6f3ed9bf), X(0x6f6377a4), X(0x6f87e5a8),
991 X(0x6fac23c9), X(0x6fd03206), X(0x6ff4105c), X(0x7017becc),
992 X(0x703b3d54), X(0x705e8bf5), X(0x7081aaaf), X(0x70a49984),
993 X(0x70c75874), X(0x70e9e783), X(0x710c46b2), X(0x712e7605),
994 X(0x7150757f), X(0x71724523), X(0x7193e4f6), X(0x71b554fd),
995 X(0x71d6953e), X(0x71f7a5bd), X(0x72188681), X(0x72393792),
996 X(0x7259b8f5), X(0x727a0ab2), X(0x729a2cd2), X(0x72ba1f5d),
997 X(0x72d9e25c), X(0x72f975d8), X(0x7318d9db), X(0x73380e6f),
998 X(0x735713a0), X(0x7375e978), X(0x73949003), X(0x73b3074c),
999 X(0x73d14f61), X(0x73ef684f), X(0x740d5222), X(0x742b0ce9),
1000 X(0x744898b1), X(0x7465f589), X(0x74832381), X(0x74a022a8),
1001 X(0x74bcf30e), X(0x74d994c3), X(0x74f607d8), X(0x75124c5f),
1002 X(0x752e6268), X(0x754a4a05), X(0x7566034b), X(0x75818e4a),
1003 X(0x759ceb16), X(0x75b819c4), X(0x75d31a66), X(0x75eded12),
1004 X(0x760891dc), X(0x762308da), X(0x763d5221), X(0x76576dc8),
1005 X(0x76715be4), X(0x768b1c8c), X(0x76a4afd9), X(0x76be15e0),
1006 X(0x76d74ebb), X(0x76f05a82), X(0x7709394d), X(0x7721eb35),
1007 X(0x773a7054), X(0x7752c8c4), X(0x776af49f), X(0x7782f400),
1008 X(0x779ac701), X(0x77b26dbd), X(0x77c9e851), X(0x77e136d8),
1009 X(0x77f8596f), X(0x780f5032), X(0x78261b3f), X(0x783cbab2),
1010 X(0x78532eaa), X(0x78697745), X(0x787f94a0), X(0x789586db),
1011 X(0x78ab4e15), X(0x78c0ea6d), X(0x78d65c03), X(0x78eba2f7),
1012 X(0x7900bf68), X(0x7915b179), X(0x792a7949), X(0x793f16fb),
1013 X(0x79538aaf), X(0x7967d488), X(0x797bf4a8), X(0x798feb31),
1014 X(0x79a3b846), X(0x79b75c0a), X(0x79cad6a1), X(0x79de282e),
1015 X(0x79f150d5), X(0x7a0450bb), X(0x7a172803), X(0x7a29d6d3),
1016 X(0x7a3c5d50), X(0x7a4ebb9f), X(0x7a60f1e6), X(0x7a73004a),
1017 X(0x7a84e6f2), X(0x7a96a604), X(0x7aa83da7), X(0x7ab9ae01),
1018 X(0x7acaf73a), X(0x7adc1979), X(0x7aed14e6), X(0x7afde9a8),
1019 X(0x7b0e97e8), X(0x7b1f1fcd), X(0x7b2f8182), X(0x7b3fbd2d),
1020 X(0x7b4fd2f9), X(0x7b5fc30f), X(0x7b6f8d98), X(0x7b7f32bd),
1021 X(0x7b8eb2a9), X(0x7b9e0d85), X(0x7bad437d), X(0x7bbc54b9),
1022 X(0x7bcb4166), X(0x7bda09ae), X(0x7be8adbc), X(0x7bf72dbc),
1023 X(0x7c0589d8), X(0x7c13c23d), X(0x7c21d716), X(0x7c2fc88f),
1024 X(0x7c3d96d5), X(0x7c4b4214), X(0x7c58ca78), X(0x7c66302d),
1025 X(0x7c737362), X(0x7c809443), X(0x7c8d92fc), X(0x7c9a6fbc),
1026 X(0x7ca72aaf), X(0x7cb3c404), X(0x7cc03be8), X(0x7ccc9288),
1027 X(0x7cd8c814), X(0x7ce4dcb9), X(0x7cf0d0a5), X(0x7cfca406),
1028 X(0x7d08570c), X(0x7d13e9e5), X(0x7d1f5cbf), X(0x7d2aafca),
1029 X(0x7d35e335), X(0x7d40f72e), X(0x7d4bebe4), X(0x7d56c188),
1030 X(0x7d617848), X(0x7d6c1054), X(0x7d7689db), X(0x7d80e50e),
1031 X(0x7d8b221b), X(0x7d954133), X(0x7d9f4286), X(0x7da92643),
1032 X(0x7db2ec9b), X(0x7dbc95bd), X(0x7dc621da), X(0x7dcf9123),
1033 X(0x7dd8e3c6), X(0x7de219f6), X(0x7deb33e2), X(0x7df431ba),
1034 X(0x7dfd13af), X(0x7e05d9f2), X(0x7e0e84b4), X(0x7e171424),
1035 X(0x7e1f8874), X(0x7e27e1d4), X(0x7e302074), X(0x7e384487),
1036 X(0x7e404e3c), X(0x7e483dc4), X(0x7e501350), X(0x7e57cf11),
1037 X(0x7e5f7138), X(0x7e66f9f4), X(0x7e6e6979), X(0x7e75bff5),
1038 X(0x7e7cfd9a), X(0x7e842298), X(0x7e8b2f22), X(0x7e922366),
1039 X(0x7e98ff97), X(0x7e9fc3e4), X(0x7ea6707f), X(0x7ead0598),
1040 X(0x7eb38360), X(0x7eb9ea07), X(0x7ec039bf), X(0x7ec672b7),
1041 X(0x7ecc9521), X(0x7ed2a12c), X(0x7ed8970a), X(0x7ede76ea),
1042 X(0x7ee440fd), X(0x7ee9f573), X(0x7eef947d), X(0x7ef51e4b),
1043 X(0x7efa930d), X(0x7efff2f2), X(0x7f053e2b), X(0x7f0a74e8),
1044 X(0x7f0f9758), X(0x7f14a5ac), X(0x7f19a013), X(0x7f1e86bc),
1045 X(0x7f2359d8), X(0x7f281995), X(0x7f2cc623), X(0x7f315fb1),
1046 X(0x7f35e66e), X(0x7f3a5a8a), X(0x7f3ebc33), X(0x7f430b98),
1047 X(0x7f4748e7), X(0x7f4b7450), X(0x7f4f8e01), X(0x7f539629),
1048 X(0x7f578cf5), X(0x7f5b7293), X(0x7f5f4732), X(0x7f630b00),
1049 X(0x7f66be2b), X(0x7f6a60df), X(0x7f6df34b), X(0x7f71759b),
1050 X(0x7f74e7fe), X(0x7f784aa0), X(0x7f7b9daf), X(0x7f7ee156),
1051 X(0x7f8215c3), X(0x7f853b22), X(0x7f88519f), X(0x7f8b5967),
1052 X(0x7f8e52a6), X(0x7f913d87), X(0x7f941a36), X(0x7f96e8df),
1053 X(0x7f99a9ad), X(0x7f9c5ccb), X(0x7f9f0265), X(0x7fa19aa5),
1054 X(0x7fa425b5), X(0x7fa6a3c1), X(0x7fa914f3), X(0x7fab7974),
1055 X(0x7fadd16f), X(0x7fb01d0d), X(0x7fb25c78), X(0x7fb48fd9),
1056 X(0x7fb6b75a), X(0x7fb8d323), X(0x7fbae35d), X(0x7fbce831),
1057 X(0x7fbee1c7), X(0x7fc0d047), X(0x7fc2b3d9), X(0x7fc48ca5),
1058 X(0x7fc65ad3), X(0x7fc81e88), X(0x7fc9d7ee), X(0x7fcb872a),
1059 X(0x7fcd2c63), X(0x7fcec7bf), X(0x7fd05966), X(0x7fd1e17c),
1060 X(0x7fd36027), X(0x7fd4d58d), X(0x7fd641d3), X(0x7fd7a51e),
1061 X(0x7fd8ff94), X(0x7fda5157), X(0x7fdb9a8e), X(0x7fdcdb5b),
1062 X(0x7fde13e2), X(0x7fdf4448), X(0x7fe06caf), X(0x7fe18d3b),
1063 X(0x7fe2a60e), X(0x7fe3b74b), X(0x7fe4c114), X(0x7fe5c38b),
1064 X(0x7fe6bed2), X(0x7fe7b30a), X(0x7fe8a055), X(0x7fe986d4),
1065 X(0x7fea66a7), X(0x7feb3ff0), X(0x7fec12cd), X(0x7fecdf5f),
1066 X(0x7feda5c5), X(0x7fee6620), X(0x7fef208d), X(0x7fefd52c),
1067 X(0x7ff0841c), X(0x7ff12d7a), X(0x7ff1d164), X(0x7ff26ff9),
1068 X(0x7ff30955), X(0x7ff39d96), X(0x7ff42cd9), X(0x7ff4b739),
1069 X(0x7ff53cd4), X(0x7ff5bdc5), X(0x7ff63a28), X(0x7ff6b217),
1070 X(0x7ff725af), X(0x7ff7950a), X(0x7ff80043), X(0x7ff86773),
1071 X(0x7ff8cab4), X(0x7ff92a21), X(0x7ff985d1), X(0x7ff9dddf),
1072 X(0x7ffa3262), X(0x7ffa8374), X(0x7ffad12c), X(0x7ffb1ba1),
1073 X(0x7ffb62ec), X(0x7ffba723), X(0x7ffbe85c), X(0x7ffc26b0),
1074 X(0x7ffc6233), X(0x7ffc9afb), X(0x7ffcd11e), X(0x7ffd04b1),
1075 X(0x7ffd35c9), X(0x7ffd647b), X(0x7ffd90da), X(0x7ffdbafa),
1076 X(0x7ffde2f0), X(0x7ffe08ce), X(0x7ffe2ca7), X(0x7ffe4e8e),
1077 X(0x7ffe6e95), X(0x7ffe8cce), X(0x7ffea94a), X(0x7ffec41b),
1078 X(0x7ffedd52), X(0x7ffef4ff), X(0x7fff0b33), X(0x7fff1ffd),
1079 X(0x7fff336e), X(0x7fff4593), X(0x7fff567d), X(0x7fff663a),
1080 X(0x7fff74d8), X(0x7fff8265), X(0x7fff8eee), X(0x7fff9a81),
1081 X(0x7fffa52b), X(0x7fffaef8), X(0x7fffb7f5), X(0x7fffc02d),
1082 X(0x7fffc7ab), X(0x7fffce7c), X(0x7fffd4a9), X(0x7fffda3e),
1083 X(0x7fffdf44), X(0x7fffe3c6), X(0x7fffe7cc), X(0x7fffeb60),
1084 X(0x7fffee8a), X(0x7ffff153), X(0x7ffff3c4), X(0x7ffff5e3),
1085 X(0x7ffff7b8), X(0x7ffff94b), X(0x7ffffaa1), X(0x7ffffbc1),
1086 X(0x7ffffcb2), X(0x7ffffd78), X(0x7ffffe19), X(0x7ffffe9a),
1087 X(0x7ffffeff), X(0x7fffff4e), X(0x7fffff89), X(0x7fffffb3),
1088 X(0x7fffffd2), X(0x7fffffe6), X(0x7ffffff3), X(0x7ffffffa),
1089 X(0x7ffffffe), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
1092 private static immutable LOOKUP_T[2048] vwin4096 = [
1093 X(0x000001f0), X(0x00001171), X(0x00003072), X(0x00005ef5),
1094 X(0x00009cf8), X(0x0000ea7c), X(0x00014780), X(0x0001b405),
1095 X(0x0002300b), X(0x0002bb91), X(0x00035698), X(0x0004011e),
1096 X(0x0004bb25), X(0x000584ac), X(0x00065db3), X(0x0007463a),
1097 X(0x00083e41), X(0x000945c7), X(0x000a5ccc), X(0x000b8350),
1098 X(0x000cb954), X(0x000dfed7), X(0x000f53d8), X(0x0010b857),
1099 X(0x00122c55), X(0x0013afd1), X(0x001542ca), X(0x0016e541),
1100 X(0x00189735), X(0x001a58a7), X(0x001c2995), X(0x001e09ff),
1101 X(0x001ff9e6), X(0x0021f948), X(0x00240826), X(0x00262680),
1102 X(0x00285454), X(0x002a91a3), X(0x002cde6c), X(0x002f3aaf),
1103 X(0x0031a66b), X(0x003421a0), X(0x0036ac4f), X(0x00394675),
1104 X(0x003bf014), X(0x003ea92a), X(0x004171b7), X(0x004449bb),
1105 X(0x00473135), X(0x004a2824), X(0x004d2e8a), X(0x00504463),
1106 X(0x005369b2), X(0x00569e74), X(0x0059e2aa), X(0x005d3652),
1107 X(0x0060996d), X(0x00640bf9), X(0x00678df7), X(0x006b1f66),
1108 X(0x006ec045), X(0x00727093), X(0x00763051), X(0x0079ff7d),
1109 X(0x007dde16), X(0x0081cc1d), X(0x0085c991), X(0x0089d671),
1110 X(0x008df2bc), X(0x00921e71), X(0x00965991), X(0x009aa41a),
1111 X(0x009efe0c), X(0x00a36766), X(0x00a7e028), X(0x00ac6850),
1112 X(0x00b0ffde), X(0x00b5a6d1), X(0x00ba5d28), X(0x00bf22e4),
1113 X(0x00c3f802), X(0x00c8dc83), X(0x00cdd065), X(0x00d2d3a8),
1114 X(0x00d7e64a), X(0x00dd084c), X(0x00e239ac), X(0x00e77a69),
1115 X(0x00ecca83), X(0x00f229f9), X(0x00f798ca), X(0x00fd16f5),
1116 X(0x0102a479), X(0x01084155), X(0x010ded89), X(0x0113a913),
1117 X(0x011973f3), X(0x011f4e27), X(0x012537af), X(0x012b308a),
1118 X(0x013138b7), X(0x01375035), X(0x013d7702), X(0x0143ad1f),
1119 X(0x0149f289), X(0x01504741), X(0x0156ab44), X(0x015d1e92),
1120 X(0x0163a12a), X(0x016a330b), X(0x0170d433), X(0x017784a3),
1121 X(0x017e4458), X(0x01851351), X(0x018bf18e), X(0x0192df0d),
1122 X(0x0199dbcd), X(0x01a0e7cd), X(0x01a8030c), X(0x01af2d89),
1123 X(0x01b66743), X(0x01bdb038), X(0x01c50867), X(0x01cc6fd0),
1124 X(0x01d3e670), X(0x01db6c47), X(0x01e30153), X(0x01eaa593),
1125 X(0x01f25907), X(0x01fa1bac), X(0x0201ed81), X(0x0209ce86),
1126 X(0x0211beb8), X(0x0219be17), X(0x0221cca2), X(0x0229ea56),
1127 X(0x02321733), X(0x023a5337), X(0x02429e60), X(0x024af8af),
1128 X(0x02536220), X(0x025bdab3), X(0x02646267), X(0x026cf93a),
1129 X(0x02759f2a), X(0x027e5436), X(0x0287185d), X(0x028feb9d),
1130 X(0x0298cdf4), X(0x02a1bf62), X(0x02aabfe5), X(0x02b3cf7b),
1131 X(0x02bcee23), X(0x02c61bdb), X(0x02cf58a2), X(0x02d8a475),
1132 X(0x02e1ff55), X(0x02eb693e), X(0x02f4e230), X(0x02fe6a29),
1133 X(0x03080127), X(0x0311a729), X(0x031b5c2d), X(0x03252031),
1134 X(0x032ef334), X(0x0338d534), X(0x0342c630), X(0x034cc625),
1135 X(0x0356d512), X(0x0360f2f6), X(0x036b1fce), X(0x03755b99),
1136 X(0x037fa655), X(0x038a0001), X(0x0394689a), X(0x039ee020),
1137 X(0x03a9668f), X(0x03b3fbe6), X(0x03bea024), X(0x03c95347),
1138 X(0x03d4154d), X(0x03dee633), X(0x03e9c5f9), X(0x03f4b49b),
1139 X(0x03ffb219), X(0x040abe71), X(0x0415d9a0), X(0x042103a5),
1140 X(0x042c3c7d), X(0x04378428), X(0x0442daa2), X(0x044e3fea),
1141 X(0x0459b3fd), X(0x046536db), X(0x0470c880), X(0x047c68eb),
1142 X(0x0488181a), X(0x0493d60b), X(0x049fa2bc), X(0x04ab7e2a),
1143 X(0x04b76854), X(0x04c36137), X(0x04cf68d1), X(0x04db7f21),
1144 X(0x04e7a424), X(0x04f3d7d8), X(0x05001a3b), X(0x050c6b4a),
1145 X(0x0518cb04), X(0x05253966), X(0x0531b66e), X(0x053e421a),
1146 X(0x054adc68), X(0x05578555), X(0x05643cdf), X(0x05710304),
1147 X(0x057dd7c1), X(0x058abb15), X(0x0597acfd), X(0x05a4ad76),
1148 X(0x05b1bc7f), X(0x05beda14), X(0x05cc0635), X(0x05d940dd),
1149 X(0x05e68a0b), X(0x05f3e1bd), X(0x060147f0), X(0x060ebca1),
1150 X(0x061c3fcf), X(0x0629d176), X(0x06377194), X(0x06452027),
1151 X(0x0652dd2c), X(0x0660a8a2), X(0x066e8284), X(0x067c6ad1),
1152 X(0x068a6186), X(0x069866a1), X(0x06a67a1e), X(0x06b49bfc),
1153 X(0x06c2cc38), X(0x06d10acf), X(0x06df57bf), X(0x06edb304),
1154 X(0x06fc1c9d), X(0x070a9487), X(0x07191abe), X(0x0727af40),
1155 X(0x0736520b), X(0x0745031c), X(0x0753c270), X(0x07629004),
1156 X(0x07716bd6), X(0x078055e2), X(0x078f4e26), X(0x079e549f),
1157 X(0x07ad694b), X(0x07bc8c26), X(0x07cbbd2e), X(0x07dafc5f),
1158 X(0x07ea49b7), X(0x07f9a533), X(0x08090ed1), X(0x0818868c),
1159 X(0x08280c62), X(0x0837a051), X(0x08474255), X(0x0856f26b),
1160 X(0x0866b091), X(0x08767cc3), X(0x088656fe), X(0x08963f3f),
1161 X(0x08a63584), X(0x08b639c8), X(0x08c64c0a), X(0x08d66c45),
1162 X(0x08e69a77), X(0x08f6d69d), X(0x090720b3), X(0x091778b7),
1163 X(0x0927dea5), X(0x0938527a), X(0x0948d433), X(0x095963cc),
1164 X(0x096a0143), X(0x097aac94), X(0x098b65bb), X(0x099c2cb6),
1165 X(0x09ad0182), X(0x09bde41a), X(0x09ced47d), X(0x09dfd2a5),
1166 X(0x09f0de90), X(0x0a01f83b), X(0x0a131fa3), X(0x0a2454c3),
1167 X(0x0a359798), X(0x0a46e820), X(0x0a584656), X(0x0a69b237),
1168 X(0x0a7b2bc0), X(0x0a8cb2ec), X(0x0a9e47ba), X(0x0aafea24),
1169 X(0x0ac19a29), X(0x0ad357c3), X(0x0ae522ef), X(0x0af6fbab),
1170 X(0x0b08e1f1), X(0x0b1ad5c0), X(0x0b2cd712), X(0x0b3ee5e5),
1171 X(0x0b510234), X(0x0b632bfd), X(0x0b75633b), X(0x0b87a7eb),
1172 X(0x0b99fa08), X(0x0bac5990), X(0x0bbec67e), X(0x0bd140cf),
1173 X(0x0be3c87e), X(0x0bf65d89), X(0x0c08ffeb), X(0x0c1bafa1),
1174 X(0x0c2e6ca6), X(0x0c4136f6), X(0x0c540e8f), X(0x0c66f36c),
1175 X(0x0c79e588), X(0x0c8ce4e1), X(0x0c9ff172), X(0x0cb30b37),
1176 X(0x0cc6322c), X(0x0cd9664d), X(0x0ceca797), X(0x0cfff605),
1177 X(0x0d135193), X(0x0d26ba3d), X(0x0d3a2fff), X(0x0d4db2d5),
1178 X(0x0d6142ba), X(0x0d74dfac), X(0x0d8889a5), X(0x0d9c40a1),
1179 X(0x0db0049d), X(0x0dc3d593), X(0x0dd7b380), X(0x0deb9e60),
1180 X(0x0dff962f), X(0x0e139ae7), X(0x0e27ac85), X(0x0e3bcb05),
1181 X(0x0e4ff662), X(0x0e642e98), X(0x0e7873a2), X(0x0e8cc57d),
1182 X(0x0ea12423), X(0x0eb58f91), X(0x0eca07c2), X(0x0ede8cb1),
1183 X(0x0ef31e5b), X(0x0f07bcba), X(0x0f1c67cb), X(0x0f311f88),
1184 X(0x0f45e3ee), X(0x0f5ab4f7), X(0x0f6f92a0), X(0x0f847ce3),
1185 X(0x0f9973bc), X(0x0fae7726), X(0x0fc3871e), X(0x0fd8a39d),
1186 X(0x0fedcca1), X(0x10030223), X(0x1018441f), X(0x102d9291),
1187 X(0x1042ed74), X(0x105854c3), X(0x106dc879), X(0x10834892),
1188 X(0x1098d508), X(0x10ae6dd8), X(0x10c412fc), X(0x10d9c46f),
1189 X(0x10ef822d), X(0x11054c30), X(0x111b2274), X(0x113104f5),
1190 X(0x1146f3ac), X(0x115cee95), X(0x1172f5ab), X(0x118908e9),
1191 X(0x119f284a), X(0x11b553ca), X(0x11cb8b62), X(0x11e1cf0f),
1192 X(0x11f81ecb), X(0x120e7a90), X(0x1224e25a), X(0x123b5624),
1193 X(0x1251d5e9), X(0x126861a3), X(0x127ef94e), X(0x12959ce3),
1194 X(0x12ac4c5f), X(0x12c307bb), X(0x12d9cef2), X(0x12f0a200),
1195 X(0x130780df), X(0x131e6b8a), X(0x133561fa), X(0x134c642c),
1196 X(0x1363721a), X(0x137a8bbe), X(0x1391b113), X(0x13a8e214),
1197 X(0x13c01eba), X(0x13d76702), X(0x13eebae5), X(0x14061a5e),
1198 X(0x141d8567), X(0x1434fbfb), X(0x144c7e14), X(0x14640bae),
1199 X(0x147ba4c1), X(0x14934949), X(0x14aaf941), X(0x14c2b4a2),
1200 X(0x14da7b67), X(0x14f24d8a), X(0x150a2b06), X(0x152213d5),
1201 X(0x153a07f1), X(0x15520755), X(0x156a11fb), X(0x158227dd),
1202 X(0x159a48f5), X(0x15b2753d), X(0x15caacb1), X(0x15e2ef49),
1203 X(0x15fb3d01), X(0x161395d2), X(0x162bf9b6), X(0x164468a8),
1204 X(0x165ce2a1), X(0x1675679c), X(0x168df793), X(0x16a69280),
1205 X(0x16bf385c), X(0x16d7e922), X(0x16f0a4cc), X(0x17096b54),
1206 X(0x17223cb4), X(0x173b18e5), X(0x1753ffe2), X(0x176cf1a5),
1207 X(0x1785ee27), X(0x179ef562), X(0x17b80750), X(0x17d123eb),
1208 X(0x17ea4b2d), X(0x18037d10), X(0x181cb98d), X(0x1836009e),
1209 X(0x184f523c), X(0x1868ae63), X(0x1882150a), X(0x189b862c),
1210 X(0x18b501c4), X(0x18ce87c9), X(0x18e81836), X(0x1901b305),
1211 X(0x191b582f), X(0x193507ad), X(0x194ec17a), X(0x1968858f),
1212 X(0x198253e5), X(0x199c2c75), X(0x19b60f3a), X(0x19cffc2d),
1213 X(0x19e9f347), X(0x1a03f482), X(0x1a1dffd7), X(0x1a381540),
1214 X(0x1a5234b5), X(0x1a6c5e31), X(0x1a8691ac), X(0x1aa0cf21),
1215 X(0x1abb1687), X(0x1ad567da), X(0x1aefc311), X(0x1b0a2826),
1216 X(0x1b249712), X(0x1b3f0fd0), X(0x1b599257), X(0x1b741ea1),
1217 X(0x1b8eb4a7), X(0x1ba95462), X(0x1bc3fdcd), X(0x1bdeb0de),
1218 X(0x1bf96d91), X(0x1c1433dd), X(0x1c2f03bc), X(0x1c49dd27),
1219 X(0x1c64c017), X(0x1c7fac85), X(0x1c9aa269), X(0x1cb5a1be),
1220 X(0x1cd0aa7c), X(0x1cebbc9c), X(0x1d06d816), X(0x1d21fce4),
1221 X(0x1d3d2aff), X(0x1d586260), X(0x1d73a2fe), X(0x1d8eecd4),
1222 X(0x1daa3fda), X(0x1dc59c09), X(0x1de1015a), X(0x1dfc6fc5),
1223 X(0x1e17e743), X(0x1e3367cd), X(0x1e4ef15b), X(0x1e6a83e7),
1224 X(0x1e861f6a), X(0x1ea1c3da), X(0x1ebd7133), X(0x1ed9276b),
1225 X(0x1ef4e67c), X(0x1f10ae5e), X(0x1f2c7f0a), X(0x1f485879),
1226 X(0x1f643aa2), X(0x1f80257f), X(0x1f9c1908), X(0x1fb81536),
1227 X(0x1fd41a00), X(0x1ff02761), X(0x200c3d4f), X(0x20285bc3),
1228 X(0x204482b7), X(0x2060b221), X(0x207ce9fb), X(0x20992a3e),
1229 X(0x20b572e0), X(0x20d1c3dc), X(0x20ee1d28), X(0x210a7ebe),
1230 X(0x2126e895), X(0x21435aa6), X(0x215fd4ea), X(0x217c5757),
1231 X(0x2198e1e8), X(0x21b57493), X(0x21d20f51), X(0x21eeb21b),
1232 X(0x220b5ce7), X(0x22280fb0), X(0x2244ca6c), X(0x22618d13),
1233 X(0x227e579f), X(0x229b2a06), X(0x22b80442), X(0x22d4e649),
1234 X(0x22f1d015), X(0x230ec19d), X(0x232bbad9), X(0x2348bbc1),
1235 X(0x2365c44c), X(0x2382d474), X(0x239fec30), X(0x23bd0b78),
1236 X(0x23da3244), X(0x23f7608b), X(0x24149646), X(0x2431d36c),
1237 X(0x244f17f5), X(0x246c63da), X(0x2489b711), X(0x24a71193),
1238 X(0x24c47358), X(0x24e1dc57), X(0x24ff4c88), X(0x251cc3e2),
1239 X(0x253a425e), X(0x2557c7f4), X(0x2575549a), X(0x2592e848),
1240 X(0x25b082f7), X(0x25ce249e), X(0x25ebcd34), X(0x26097cb2),
1241 X(0x2627330e), X(0x2644f040), X(0x2662b441), X(0x26807f07),
1242 X(0x269e5089), X(0x26bc28c1), X(0x26da07a4), X(0x26f7ed2b),
1243 X(0x2715d94d), X(0x2733cc02), X(0x2751c540), X(0x276fc500),
1244 X(0x278dcb39), X(0x27abd7e2), X(0x27c9eaf3), X(0x27e80463),
1245 X(0x28062429), X(0x28244a3e), X(0x28427697), X(0x2860a92d),
1246 X(0x287ee1f7), X(0x289d20eb), X(0x28bb6603), X(0x28d9b134),
1247 X(0x28f80275), X(0x291659c0), X(0x2934b709), X(0x29531a49),
1248 X(0x29718378), X(0x298ff28b), X(0x29ae677b), X(0x29cce23e),
1249 X(0x29eb62cb), X(0x2a09e91b), X(0x2a287523), X(0x2a4706dc),
1250 X(0x2a659e3c), X(0x2a843b39), X(0x2aa2ddcd), X(0x2ac185ec),
1251 X(0x2ae0338f), X(0x2afee6ad), X(0x2b1d9f3c), X(0x2b3c5d33),
1252 X(0x2b5b208b), X(0x2b79e939), X(0x2b98b734), X(0x2bb78a74),
1253 X(0x2bd662ef), X(0x2bf5409d), X(0x2c142374), X(0x2c330b6b),
1254 X(0x2c51f87a), X(0x2c70ea97), X(0x2c8fe1b9), X(0x2caeddd6),
1255 X(0x2ccddee7), X(0x2cece4e1), X(0x2d0befbb), X(0x2d2aff6d),
1256 X(0x2d4a13ec), X(0x2d692d31), X(0x2d884b32), X(0x2da76de4),
1257 X(0x2dc69540), X(0x2de5c13d), X(0x2e04f1d0), X(0x2e2426f0),
1258 X(0x2e436095), X(0x2e629eb4), X(0x2e81e146), X(0x2ea1283f),
1259 X(0x2ec07398), X(0x2edfc347), X(0x2eff1742), X(0x2f1e6f80),
1260 X(0x2f3dcbf8), X(0x2f5d2ca0), X(0x2f7c916f), X(0x2f9bfa5c),
1261 X(0x2fbb675d), X(0x2fdad869), X(0x2ffa4d76), X(0x3019c67b),
1262 X(0x3039436f), X(0x3058c448), X(0x307848fc), X(0x3097d183),
1263 X(0x30b75dd3), X(0x30d6ede2), X(0x30f681a6), X(0x31161917),
1264 X(0x3135b42b), X(0x315552d8), X(0x3174f514), X(0x31949ad7),
1265 X(0x31b44417), X(0x31d3f0ca), X(0x31f3a0e6), X(0x32135462),
1266 X(0x32330b35), X(0x3252c555), X(0x327282b7), X(0x32924354),
1267 X(0x32b20720), X(0x32d1ce13), X(0x32f19823), X(0x33116546),
1268 X(0x33313573), X(0x3351089f), X(0x3370dec2), X(0x3390b7d1),
1269 X(0x33b093c3), X(0x33d0728f), X(0x33f05429), X(0x3410388a),
1270 X(0x34301fa7), X(0x34500977), X(0x346ff5ef), X(0x348fe506),
1271 X(0x34afd6b3), X(0x34cfcaeb), X(0x34efc1a5), X(0x350fbad7),
1272 X(0x352fb678), X(0x354fb47d), X(0x356fb4dd), X(0x358fb78e),
1273 X(0x35afbc86), X(0x35cfc3bc), X(0x35efcd25), X(0x360fd8b8),
1274 X(0x362fe66c), X(0x364ff636), X(0x3670080c), X(0x36901be5),
1275 X(0x36b031b7), X(0x36d04978), X(0x36f0631e), X(0x37107ea0),
1276 X(0x37309bf3), X(0x3750bb0e), X(0x3770dbe6), X(0x3790fe73),
1277 X(0x37b122aa), X(0x37d14881), X(0x37f16fee), X(0x381198e8),
1278 X(0x3831c365), X(0x3851ef5a), X(0x38721cbe), X(0x38924b87),
1279 X(0x38b27bac), X(0x38d2ad21), X(0x38f2dfde), X(0x391313d8),
1280 X(0x39334906), X(0x39537f5d), X(0x3973b6d4), X(0x3993ef60),
1281 X(0x39b428f9), X(0x39d46393), X(0x39f49f25), X(0x3a14dba6),
1282 X(0x3a35190a), X(0x3a555748), X(0x3a759657), X(0x3a95d62c),
1283 X(0x3ab616be), X(0x3ad65801), X(0x3af699ed), X(0x3b16dc78),
1284 X(0x3b371f97), X(0x3b576341), X(0x3b77a76c), X(0x3b97ec0d),
1285 X(0x3bb8311b), X(0x3bd8768b), X(0x3bf8bc55), X(0x3c19026d),
1286 X(0x3c3948ca), X(0x3c598f62), X(0x3c79d62b), X(0x3c9a1d1b),
1287 X(0x3cba6428), X(0x3cdaab48), X(0x3cfaf271), X(0x3d1b3999),
1288 X(0x3d3b80b6), X(0x3d5bc7be), X(0x3d7c0ea8), X(0x3d9c5569),
1289 X(0x3dbc9bf7), X(0x3ddce248), X(0x3dfd2852), X(0x3e1d6e0c),
1290 X(0x3e3db36c), X(0x3e5df866), X(0x3e7e3cf2), X(0x3e9e8106),
1291 X(0x3ebec497), X(0x3edf079b), X(0x3eff4a09), X(0x3f1f8bd7),
1292 X(0x3f3fccfa), X(0x3f600d69), X(0x3f804d1a), X(0x3fa08c02),
1293 X(0x3fc0ca19), X(0x3fe10753), X(0x400143a7), X(0x40217f0a),
1294 X(0x4041b974), X(0x4061f2da), X(0x40822b32), X(0x40a26272),
1295 X(0x40c29891), X(0x40e2cd83), X(0x41030140), X(0x412333bd),
1296 X(0x414364f1), X(0x416394d2), X(0x4183c355), X(0x41a3f070),
1297 X(0x41c41c1b), X(0x41e4464a), X(0x42046ef4), X(0x42249610),
1298 X(0x4244bb92), X(0x4264df72), X(0x428501a5), X(0x42a52222),
1299 X(0x42c540de), X(0x42e55dd0), X(0x430578ed), X(0x4325922d),
1300 X(0x4345a985), X(0x4365beeb), X(0x4385d255), X(0x43a5e3ba),
1301 X(0x43c5f30f), X(0x43e6004b), X(0x44060b65), X(0x44261451),
1302 X(0x44461b07), X(0x44661f7c), X(0x448621a7), X(0x44a6217d),
1303 X(0x44c61ef6), X(0x44e61a07), X(0x450612a6), X(0x452608ca),
1304 X(0x4545fc69), X(0x4565ed79), X(0x4585dbf1), X(0x45a5c7c6),
1305 X(0x45c5b0ef), X(0x45e59761), X(0x46057b15), X(0x46255bfe),
1306 X(0x46453a15), X(0x4665154f), X(0x4684eda2), X(0x46a4c305),
1307 X(0x46c4956e), X(0x46e464d3), X(0x4704312b), X(0x4723fa6c),
1308 X(0x4743c08d), X(0x47638382), X(0x47834344), X(0x47a2ffc9),
1309 X(0x47c2b906), X(0x47e26ef2), X(0x48022183), X(0x4821d0b1),
1310 X(0x48417c71), X(0x486124b9), X(0x4880c981), X(0x48a06abe),
1311 X(0x48c00867), X(0x48dfa272), X(0x48ff38d6), X(0x491ecb8a),
1312 X(0x493e5a84), X(0x495de5b9), X(0x497d6d22), X(0x499cf0b4),
1313 X(0x49bc7066), X(0x49dbec2e), X(0x49fb6402), X(0x4a1ad7db),
1314 X(0x4a3a47ad), X(0x4a59b370), X(0x4a791b1a), X(0x4a987ea1),
1315 X(0x4ab7ddfd), X(0x4ad73924), X(0x4af6900c), X(0x4b15e2ad),
1316 X(0x4b3530fc), X(0x4b547af1), X(0x4b73c082), X(0x4b9301a6),
1317 X(0x4bb23e53), X(0x4bd17681), X(0x4bf0aa25), X(0x4c0fd937),
1318 X(0x4c2f03ae), X(0x4c4e297f), X(0x4c6d4aa3), X(0x4c8c670f),
1319 X(0x4cab7eba), X(0x4cca919c), X(0x4ce99fab), X(0x4d08a8de),
1320 X(0x4d27ad2c), X(0x4d46ac8b), X(0x4d65a6f3), X(0x4d849c5a),
1321 X(0x4da38cb7), X(0x4dc27802), X(0x4de15e31), X(0x4e003f3a),
1322 X(0x4e1f1b16), X(0x4e3df1ba), X(0x4e5cc31e), X(0x4e7b8f3a),
1323 X(0x4e9a5603), X(0x4eb91771), X(0x4ed7d37b), X(0x4ef68a18),
1324 X(0x4f153b3f), X(0x4f33e6e7), X(0x4f528d08), X(0x4f712d97),
1325 X(0x4f8fc88e), X(0x4fae5de1), X(0x4fcced8a), X(0x4feb777f),
1326 X(0x5009fbb6), X(0x50287a28), X(0x5046f2cc), X(0x50656598),
1327 X(0x5083d284), X(0x50a23988), X(0x50c09a9a), X(0x50def5b1),
1328 X(0x50fd4ac7), X(0x511b99d0), X(0x5139e2c5), X(0x5158259e),
1329 X(0x51766251), X(0x519498d6), X(0x51b2c925), X(0x51d0f334),
1330 X(0x51ef16fb), X(0x520d3473), X(0x522b4b91), X(0x52495c4e),
1331 X(0x526766a2), X(0x52856a83), X(0x52a367e9), X(0x52c15ecd),
1332 X(0x52df4f24), X(0x52fd38e8), X(0x531b1c10), X(0x5338f892),
1333 X(0x5356ce68), X(0x53749d89), X(0x539265eb), X(0x53b02788),
1334 X(0x53cde257), X(0x53eb964f), X(0x54094369), X(0x5426e99c),
1335 X(0x544488df), X(0x5462212c), X(0x547fb279), X(0x549d3cbe),
1336 X(0x54babff4), X(0x54d83c12), X(0x54f5b110), X(0x55131ee7),
1337 X(0x5530858d), X(0x554de4fc), X(0x556b3d2a), X(0x55888e11),
1338 X(0x55a5d7a8), X(0x55c319e7), X(0x55e054c7), X(0x55fd883f),
1339 X(0x561ab447), X(0x5637d8d8), X(0x5654f5ea), X(0x56720b75),
1340 X(0x568f1971), X(0x56ac1fd7), X(0x56c91e9e), X(0x56e615c0),
1341 X(0x57030534), X(0x571fecf2), X(0x573cccf3), X(0x5759a530),
1342 X(0x577675a0), X(0x57933e3c), X(0x57affefd), X(0x57ccb7db),
1343 X(0x57e968ce), X(0x580611cf), X(0x5822b2d6), X(0x583f4bdd),
1344 X(0x585bdcdb), X(0x587865c9), X(0x5894e69f), X(0x58b15f57),
1345 X(0x58cdcfe9), X(0x58ea384e), X(0x5906987d), X(0x5922f071),
1346 X(0x593f4022), X(0x595b8788), X(0x5977c69c), X(0x5993fd57),
1347 X(0x59b02bb2), X(0x59cc51a6), X(0x59e86f2c), X(0x5a04843c),
1348 X(0x5a2090d0), X(0x5a3c94e0), X(0x5a589065), X(0x5a748359),
1349 X(0x5a906db4), X(0x5aac4f70), X(0x5ac82884), X(0x5ae3f8ec),
1350 X(0x5affc09f), X(0x5b1b7f97), X(0x5b3735cd), X(0x5b52e33a),
1351 X(0x5b6e87d8), X(0x5b8a239f), X(0x5ba5b689), X(0x5bc1408f),
1352 X(0x5bdcc1aa), X(0x5bf839d5), X(0x5c13a907), X(0x5c2f0f3b),
1353 X(0x5c4a6c6a), X(0x5c65c08d), X(0x5c810b9e), X(0x5c9c4d97),
1354 X(0x5cb78670), X(0x5cd2b623), X(0x5ceddcaa), X(0x5d08f9ff),
1355 X(0x5d240e1b), X(0x5d3f18f8), X(0x5d5a1a8f), X(0x5d7512da),
1356 X(0x5d9001d3), X(0x5daae773), X(0x5dc5c3b5), X(0x5de09692),
1357 X(0x5dfb6004), X(0x5e162004), X(0x5e30d68d), X(0x5e4b8399),
1358 X(0x5e662721), X(0x5e80c11f), X(0x5e9b518e), X(0x5eb5d867),
1359 X(0x5ed055a4), X(0x5eeac940), X(0x5f053334), X(0x5f1f937b),
1360 X(0x5f39ea0f), X(0x5f5436ea), X(0x5f6e7a06), X(0x5f88b35d),
1361 X(0x5fa2e2e9), X(0x5fbd08a6), X(0x5fd7248d), X(0x5ff13698),
1362 X(0x600b3ec2), X(0x60253d05), X(0x603f315b), X(0x60591bc0),
1363 X(0x6072fc2d), X(0x608cd29e), X(0x60a69f0b), X(0x60c06171),
1364 X(0x60da19ca), X(0x60f3c80f), X(0x610d6c3d), X(0x6127064d),
1365 X(0x6140963a), X(0x615a1bff), X(0x61739797), X(0x618d08fc),
1366 X(0x61a67029), X(0x61bfcd1a), X(0x61d91fc8), X(0x61f2682f),
1367 X(0x620ba64a), X(0x6224da13), X(0x623e0386), X(0x6257229d),
1368 X(0x62703754), X(0x628941a6), X(0x62a2418e), X(0x62bb3706),
1369 X(0x62d4220a), X(0x62ed0296), X(0x6305d8a3), X(0x631ea42f),
1370 X(0x63376533), X(0x63501bab), X(0x6368c793), X(0x638168e5),
1371 X(0x6399ff9e), X(0x63b28bb8), X(0x63cb0d2f), X(0x63e383ff),
1372 X(0x63fbf022), X(0x64145195), X(0x642ca853), X(0x6444f457),
1373 X(0x645d359e), X(0x64756c22), X(0x648d97e0), X(0x64a5b8d3),
1374 X(0x64bdcef6), X(0x64d5da47), X(0x64eddabf), X(0x6505d05c),
1375 X(0x651dbb19), X(0x65359af2), X(0x654d6fe3), X(0x656539e7),
1376 X(0x657cf8fb), X(0x6594ad1b), X(0x65ac5643), X(0x65c3f46e),
1377 X(0x65db8799), X(0x65f30fc0), X(0x660a8ce0), X(0x6621fef3),
1378 X(0x663965f7), X(0x6650c1e7), X(0x666812c1), X(0x667f5880),
1379 X(0x66969320), X(0x66adc29e), X(0x66c4e6f7), X(0x66dc0026),
1380 X(0x66f30e28), X(0x670a10fa), X(0x67210898), X(0x6737f4ff),
1381 X(0x674ed62b), X(0x6765ac19), X(0x677c76c5), X(0x6793362c),
1382 X(0x67a9ea4b), X(0x67c0931f), X(0x67d730a3), X(0x67edc2d6),
1383 X(0x680449b3), X(0x681ac538), X(0x68313562), X(0x68479a2d),
1384 X(0x685df396), X(0x6874419b), X(0x688a8438), X(0x68a0bb6a),
1385 X(0x68b6e72e), X(0x68cd0782), X(0x68e31c63), X(0x68f925cd),
1386 X(0x690f23be), X(0x69251633), X(0x693afd29), X(0x6950d89e),
1387 X(0x6966a88f), X(0x697c6cf8), X(0x699225d9), X(0x69a7d32d),
1388 X(0x69bd74f3), X(0x69d30b27), X(0x69e895c8), X(0x69fe14d2),
1389 X(0x6a138844), X(0x6a28f01b), X(0x6a3e4c54), X(0x6a539ced),
1390 X(0x6a68e1e4), X(0x6a7e1b37), X(0x6a9348e3), X(0x6aa86ae6),
1391 X(0x6abd813d), X(0x6ad28be7), X(0x6ae78ae2), X(0x6afc7e2b),
1392 X(0x6b1165c0), X(0x6b26419f), X(0x6b3b11c7), X(0x6b4fd634),
1393 X(0x6b648ee6), X(0x6b793bda), X(0x6b8ddd0e), X(0x6ba27281),
1394 X(0x6bb6fc31), X(0x6bcb7a1b), X(0x6bdfec3e), X(0x6bf45299),
1395 X(0x6c08ad29), X(0x6c1cfbed), X(0x6c313ee4), X(0x6c45760a),
1396 X(0x6c59a160), X(0x6c6dc0e4), X(0x6c81d493), X(0x6c95dc6d),
1397 X(0x6ca9d86f), X(0x6cbdc899), X(0x6cd1acea), X(0x6ce5855f),
1398 X(0x6cf951f7), X(0x6d0d12b1), X(0x6d20c78c), X(0x6d347087),
1399 X(0x6d480da0), X(0x6d5b9ed6), X(0x6d6f2427), X(0x6d829d94),
1400 X(0x6d960b1a), X(0x6da96cb9), X(0x6dbcc270), X(0x6dd00c3c),
1401 X(0x6de34a1f), X(0x6df67c16), X(0x6e09a221), X(0x6e1cbc3f),
1402 X(0x6e2fca6e), X(0x6e42ccaf), X(0x6e55c300), X(0x6e68ad60),
1403 X(0x6e7b8bd0), X(0x6e8e5e4d), X(0x6ea124d8), X(0x6eb3df70),
1404 X(0x6ec68e13), X(0x6ed930c3), X(0x6eebc77d), X(0x6efe5242),
1405 X(0x6f10d111), X(0x6f2343e9), X(0x6f35aacb), X(0x6f4805b5),
1406 X(0x6f5a54a8), X(0x6f6c97a2), X(0x6f7ecea4), X(0x6f90f9ae),
1407 X(0x6fa318be), X(0x6fb52bd6), X(0x6fc732f4), X(0x6fd92e19),
1408 X(0x6feb1d44), X(0x6ffd0076), X(0x700ed7ad), X(0x7020a2eb),
1409 X(0x7032622f), X(0x7044157a), X(0x7055bcca), X(0x70675821),
1410 X(0x7078e77e), X(0x708a6ae2), X(0x709be24c), X(0x70ad4dbd),
1411 X(0x70bead36), X(0x70d000b5), X(0x70e1483d), X(0x70f283cc),
1412 X(0x7103b363), X(0x7114d704), X(0x7125eead), X(0x7136fa60),
1413 X(0x7147fa1c), X(0x7158ede4), X(0x7169d5b6), X(0x717ab193),
1414 X(0x718b817d), X(0x719c4573), X(0x71acfd76), X(0x71bda988),
1415 X(0x71ce49a8), X(0x71deddd7), X(0x71ef6617), X(0x71ffe267),
1416 X(0x721052ca), X(0x7220b73e), X(0x72310fc6), X(0x72415c62),
1417 X(0x72519d14), X(0x7261d1db), X(0x7271faba), X(0x728217b1),
1418 X(0x729228c0), X(0x72a22dea), X(0x72b22730), X(0x72c21491),
1419 X(0x72d1f611), X(0x72e1cbaf), X(0x72f1956c), X(0x7301534c),
1420 X(0x7311054d), X(0x7320ab72), X(0x733045bc), X(0x733fd42d),
1421 X(0x734f56c5), X(0x735ecd86), X(0x736e3872), X(0x737d9789),
1422 X(0x738ceacf), X(0x739c3243), X(0x73ab6de7), X(0x73ba9dbe),
1423 X(0x73c9c1c8), X(0x73d8da08), X(0x73e7e67f), X(0x73f6e72e),
1424 X(0x7405dc17), X(0x7414c53c), X(0x7423a29f), X(0x74327442),
1425 X(0x74413a26), X(0x744ff44d), X(0x745ea2b9), X(0x746d456c),
1426 X(0x747bdc68), X(0x748a67ae), X(0x7498e741), X(0x74a75b23),
1427 X(0x74b5c356), X(0x74c41fdb), X(0x74d270b6), X(0x74e0b5e7),
1428 X(0x74eeef71), X(0x74fd1d57), X(0x750b3f9a), X(0x7519563c),
1429 X(0x75276140), X(0x753560a8), X(0x75435477), X(0x75513cae),
1430 X(0x755f1951), X(0x756cea60), X(0x757aafdf), X(0x758869d1),
1431 X(0x75961837), X(0x75a3bb14), X(0x75b1526a), X(0x75bede3c),
1432 X(0x75cc5e8d), X(0x75d9d35f), X(0x75e73cb5), X(0x75f49a91),
1433 X(0x7601ecf6), X(0x760f33e6), X(0x761c6f65), X(0x76299f74),
1434 X(0x7636c417), X(0x7643dd51), X(0x7650eb24), X(0x765ded93),
1435 X(0x766ae4a0), X(0x7677d050), X(0x7684b0a4), X(0x7691859f),
1436 X(0x769e4f45), X(0x76ab0d98), X(0x76b7c09c), X(0x76c46852),
1437 X(0x76d104bf), X(0x76dd95e6), X(0x76ea1bc9), X(0x76f6966b),
1438 X(0x770305d0), X(0x770f69fb), X(0x771bc2ef), X(0x772810af),
1439 X(0x7734533e), X(0x77408aa0), X(0x774cb6d7), X(0x7758d7e8),
1440 X(0x7764edd5), X(0x7770f8a2), X(0x777cf852), X(0x7788ece8),
1441 X(0x7794d668), X(0x77a0b4d5), X(0x77ac8833), X(0x77b85085),
1442 X(0x77c40dce), X(0x77cfc013), X(0x77db6756), X(0x77e7039b),
1443 X(0x77f294e6), X(0x77fe1b3b), X(0x7809969c), X(0x7815070e),
1444 X(0x78206c93), X(0x782bc731), X(0x783716ea), X(0x78425bc3),
1445 X(0x784d95be), X(0x7858c4e1), X(0x7863e92d), X(0x786f02a8),
1446 X(0x787a1156), X(0x78851539), X(0x78900e56), X(0x789afcb1),
1447 X(0x78a5e04d), X(0x78b0b92f), X(0x78bb875b), X(0x78c64ad4),
1448 X(0x78d1039e), X(0x78dbb1be), X(0x78e65537), X(0x78f0ee0e),
1449 X(0x78fb7c46), X(0x7905ffe4), X(0x791078ec), X(0x791ae762),
1450 X(0x79254b4a), X(0x792fa4a7), X(0x7939f380), X(0x794437d7),
1451 X(0x794e71b0), X(0x7958a111), X(0x7962c5fd), X(0x796ce078),
1452 X(0x7976f087), X(0x7980f62f), X(0x798af173), X(0x7994e258),
1453 X(0x799ec8e2), X(0x79a8a515), X(0x79b276f7), X(0x79bc3e8b),
1454 X(0x79c5fbd6), X(0x79cfaedc), X(0x79d957a2), X(0x79e2f62c),
1455 X(0x79ec8a7f), X(0x79f6149f), X(0x79ff9492), X(0x7a090a5a),
1456 X(0x7a1275fe), X(0x7a1bd781), X(0x7a252ee9), X(0x7a2e7c39),
1457 X(0x7a37bf77), X(0x7a40f8a7), X(0x7a4a27ce), X(0x7a534cf0),
1458 X(0x7a5c6813), X(0x7a65793b), X(0x7a6e806d), X(0x7a777dad),
1459 X(0x7a807100), X(0x7a895a6b), X(0x7a9239f4), X(0x7a9b0f9e),
1460 X(0x7aa3db6f), X(0x7aac9d6b), X(0x7ab55597), X(0x7abe03f9),
1461 X(0x7ac6a895), X(0x7acf4370), X(0x7ad7d48f), X(0x7ae05bf6),
1462 X(0x7ae8d9ac), X(0x7af14db5), X(0x7af9b815), X(0x7b0218d2),
1463 X(0x7b0a6ff2), X(0x7b12bd78), X(0x7b1b016a), X(0x7b233bce),
1464 X(0x7b2b6ca7), X(0x7b3393fc), X(0x7b3bb1d1), X(0x7b43c62c),
1465 X(0x7b4bd111), X(0x7b53d286), X(0x7b5bca90), X(0x7b63b935),
1466 X(0x7b6b9e78), X(0x7b737a61), X(0x7b7b4cf3), X(0x7b831634),
1467 X(0x7b8ad629), X(0x7b928cd8), X(0x7b9a3a45), X(0x7ba1de77),
1468 X(0x7ba97972), X(0x7bb10b3c), X(0x7bb893d9), X(0x7bc01350),
1469 X(0x7bc789a6), X(0x7bcef6e0), X(0x7bd65b03), X(0x7bddb616),
1470 X(0x7be5081c), X(0x7bec511c), X(0x7bf3911b), X(0x7bfac81f),
1471 X(0x7c01f62c), X(0x7c091b49), X(0x7c10377b), X(0x7c174ac7),
1472 X(0x7c1e5532), X(0x7c2556c4), X(0x7c2c4f80), X(0x7c333f6c),
1473 X(0x7c3a268e), X(0x7c4104ec), X(0x7c47da8a), X(0x7c4ea76f),
1474 X(0x7c556ba1), X(0x7c5c2724), X(0x7c62d9fe), X(0x7c698435),
1475 X(0x7c7025cf), X(0x7c76bed0), X(0x7c7d4f40), X(0x7c83d723),
1476 X(0x7c8a567f), X(0x7c90cd5a), X(0x7c973bb9), X(0x7c9da1a2),
1477 X(0x7ca3ff1b), X(0x7caa542a), X(0x7cb0a0d3), X(0x7cb6e51e),
1478 X(0x7cbd210f), X(0x7cc354ac), X(0x7cc97ffc), X(0x7ccfa304),
1479 X(0x7cd5bdc9), X(0x7cdbd051), X(0x7ce1daa3), X(0x7ce7dcc3),
1480 X(0x7cedd6b8), X(0x7cf3c888), X(0x7cf9b238), X(0x7cff93cf),
1481 X(0x7d056d51), X(0x7d0b3ec5), X(0x7d110830), X(0x7d16c99a),
1482 X(0x7d1c8306), X(0x7d22347c), X(0x7d27de00), X(0x7d2d7f9a),
1483 X(0x7d33194f), X(0x7d38ab24), X(0x7d3e351f), X(0x7d43b748),
1484 X(0x7d4931a2), X(0x7d4ea435), X(0x7d540f06), X(0x7d59721b),
1485 X(0x7d5ecd7b), X(0x7d64212a), X(0x7d696d2f), X(0x7d6eb190),
1486 X(0x7d73ee53), X(0x7d79237e), X(0x7d7e5117), X(0x7d837723),
1487 X(0x7d8895a9), X(0x7d8dacae), X(0x7d92bc3a), X(0x7d97c451),
1488 X(0x7d9cc4f9), X(0x7da1be39), X(0x7da6b017), X(0x7dab9a99),
1489 X(0x7db07dc4), X(0x7db5599e), X(0x7dba2e2f), X(0x7dbefb7b),
1490 X(0x7dc3c189), X(0x7dc8805e), X(0x7dcd3802), X(0x7dd1e879),
1491 X(0x7dd691ca), X(0x7ddb33fb), X(0x7ddfcf12), X(0x7de46315),
1492 X(0x7de8f00a), X(0x7ded75f8), X(0x7df1f4e3), X(0x7df66cd3),
1493 X(0x7dfaddcd), X(0x7dff47d7), X(0x7e03aaf8), X(0x7e080735),
1494 X(0x7e0c5c95), X(0x7e10ab1e), X(0x7e14f2d5), X(0x7e1933c1),
1495 X(0x7e1d6de8), X(0x7e21a150), X(0x7e25cdff), X(0x7e29f3fc),
1496 X(0x7e2e134c), X(0x7e322bf5), X(0x7e363dfd), X(0x7e3a496b),
1497 X(0x7e3e4e45), X(0x7e424c90), X(0x7e464454), X(0x7e4a3595),
1498 X(0x7e4e205a), X(0x7e5204aa), X(0x7e55e289), X(0x7e59b9ff),
1499 X(0x7e5d8b12), X(0x7e6155c7), X(0x7e651a24), X(0x7e68d831),
1500 X(0x7e6c8ff2), X(0x7e70416e), X(0x7e73ecac), X(0x7e7791b0),
1501 X(0x7e7b3082), X(0x7e7ec927), X(0x7e825ba6), X(0x7e85e804),
1502 X(0x7e896e48), X(0x7e8cee77), X(0x7e906899), X(0x7e93dcb2),
1503 X(0x7e974aca), X(0x7e9ab2e5), X(0x7e9e150b), X(0x7ea17141),
1504 X(0x7ea4c78e), X(0x7ea817f7), X(0x7eab6283), X(0x7eaea737),
1505 X(0x7eb1e61a), X(0x7eb51f33), X(0x7eb85285), X(0x7ebb8019),
1506 X(0x7ebea7f4), X(0x7ec1ca1d), X(0x7ec4e698), X(0x7ec7fd6d),
1507 X(0x7ecb0ea1), X(0x7ece1a3a), X(0x7ed1203f), X(0x7ed420b6),
1508 X(0x7ed71ba4), X(0x7eda110f), X(0x7edd00ff), X(0x7edfeb78),
1509 X(0x7ee2d081), X(0x7ee5b01f), X(0x7ee88a5a), X(0x7eeb5f36),
1510 X(0x7eee2eba), X(0x7ef0f8ed), X(0x7ef3bdd3), X(0x7ef67d73),
1511 X(0x7ef937d3), X(0x7efbecf9), X(0x7efe9ceb), X(0x7f0147ae),
1512 X(0x7f03ed4a), X(0x7f068dc4), X(0x7f092922), X(0x7f0bbf69),
1513 X(0x7f0e50a1), X(0x7f10dcce), X(0x7f1363f7), X(0x7f15e622),
1514 X(0x7f186355), X(0x7f1adb95), X(0x7f1d4ee9), X(0x7f1fbd57),
1515 X(0x7f2226e4), X(0x7f248b96), X(0x7f26eb74), X(0x7f294683),
1516 X(0x7f2b9cc9), X(0x7f2dee4d), X(0x7f303b13), X(0x7f328322),
1517 X(0x7f34c680), X(0x7f370533), X(0x7f393f40), X(0x7f3b74ad),
1518 X(0x7f3da581), X(0x7f3fd1c1), X(0x7f41f972), X(0x7f441c9c),
1519 X(0x7f463b43), X(0x7f48556d), X(0x7f4a6b21), X(0x7f4c7c64),
1520 X(0x7f4e893c), X(0x7f5091ae), X(0x7f5295c1), X(0x7f54957a),
1521 X(0x7f5690e0), X(0x7f5887f7), X(0x7f5a7ac5), X(0x7f5c6951),
1522 X(0x7f5e53a0), X(0x7f6039b8), X(0x7f621b9e), X(0x7f63f958),
1523 X(0x7f65d2ed), X(0x7f67a861), X(0x7f6979ba), X(0x7f6b46ff),
1524 X(0x7f6d1034), X(0x7f6ed560), X(0x7f709687), X(0x7f7253b1),
1525 X(0x7f740ce1), X(0x7f75c21f), X(0x7f777370), X(0x7f7920d8),
1526 X(0x7f7aca5f), X(0x7f7c7008), X(0x7f7e11db), X(0x7f7fafdd),
1527 X(0x7f814a13), X(0x7f82e082), X(0x7f847331), X(0x7f860224),
1528 X(0x7f878d62), X(0x7f8914f0), X(0x7f8a98d4), X(0x7f8c1912),
1529 X(0x7f8d95b0), X(0x7f8f0eb5), X(0x7f908425), X(0x7f91f605),
1530 X(0x7f93645c), X(0x7f94cf2f), X(0x7f963683), X(0x7f979a5d),
1531 X(0x7f98fac4), X(0x7f9a57bb), X(0x7f9bb14a), X(0x7f9d0775),
1532 X(0x7f9e5a41), X(0x7f9fa9b4), X(0x7fa0f5d3), X(0x7fa23ea4),
1533 X(0x7fa3842b), X(0x7fa4c66f), X(0x7fa60575), X(0x7fa74141),
1534 X(0x7fa879d9), X(0x7fa9af42), X(0x7faae182), X(0x7fac109e),
1535 X(0x7fad3c9a), X(0x7fae657d), X(0x7faf8b4c), X(0x7fb0ae0b),
1536 X(0x7fb1cdc0), X(0x7fb2ea70), X(0x7fb40420), X(0x7fb51ad5),
1537 X(0x7fb62e95), X(0x7fb73f64), X(0x7fb84d48), X(0x7fb95846),
1538 X(0x7fba6062), X(0x7fbb65a2), X(0x7fbc680c), X(0x7fbd67a3),
1539 X(0x7fbe646d), X(0x7fbf5e70), X(0x7fc055af), X(0x7fc14a31),
1540 X(0x7fc23bf9), X(0x7fc32b0d), X(0x7fc41773), X(0x7fc5012e),
1541 X(0x7fc5e844), X(0x7fc6ccba), X(0x7fc7ae94), X(0x7fc88dd8),
1542 X(0x7fc96a8a), X(0x7fca44af), X(0x7fcb1c4c), X(0x7fcbf167),
1543 X(0x7fccc403), X(0x7fcd9425), X(0x7fce61d3), X(0x7fcf2d11),
1544 X(0x7fcff5e3), X(0x7fd0bc4f), X(0x7fd1805a), X(0x7fd24207),
1545 X(0x7fd3015c), X(0x7fd3be5d), X(0x7fd47910), X(0x7fd53178),
1546 X(0x7fd5e79b), X(0x7fd69b7c), X(0x7fd74d21), X(0x7fd7fc8e),
1547 X(0x7fd8a9c8), X(0x7fd954d4), X(0x7fd9fdb5), X(0x7fdaa471),
1548 X(0x7fdb490b), X(0x7fdbeb89), X(0x7fdc8bef), X(0x7fdd2a42),
1549 X(0x7fddc685), X(0x7fde60be), X(0x7fdef8f0), X(0x7fdf8f20),
1550 X(0x7fe02353), X(0x7fe0b58d), X(0x7fe145d3), X(0x7fe1d428),
1551 X(0x7fe26091), X(0x7fe2eb12), X(0x7fe373b0), X(0x7fe3fa6f),
1552 X(0x7fe47f53), X(0x7fe50260), X(0x7fe5839b), X(0x7fe60308),
1553 X(0x7fe680ab), X(0x7fe6fc88), X(0x7fe776a4), X(0x7fe7ef02),
1554 X(0x7fe865a7), X(0x7fe8da97), X(0x7fe94dd6), X(0x7fe9bf68),
1555 X(0x7fea2f51), X(0x7fea9d95), X(0x7feb0a39), X(0x7feb7540),
1556 X(0x7febdeae), X(0x7fec4687), X(0x7fecaccf), X(0x7fed118b),
1557 X(0x7fed74be), X(0x7fedd66c), X(0x7fee3698), X(0x7fee9548),
1558 X(0x7feef27e), X(0x7fef4e3f), X(0x7fefa88e), X(0x7ff0016f),
1559 X(0x7ff058e7), X(0x7ff0aef8), X(0x7ff103a6), X(0x7ff156f6),
1560 X(0x7ff1a8eb), X(0x7ff1f988), X(0x7ff248d2), X(0x7ff296cc),
1561 X(0x7ff2e37a), X(0x7ff32edf), X(0x7ff378ff), X(0x7ff3c1de),
1562 X(0x7ff4097e), X(0x7ff44fe5), X(0x7ff49515), X(0x7ff4d911),
1563 X(0x7ff51bde), X(0x7ff55d7f), X(0x7ff59df7), X(0x7ff5dd4a),
1564 X(0x7ff61b7b), X(0x7ff6588d), X(0x7ff69485), X(0x7ff6cf65),
1565 X(0x7ff70930), X(0x7ff741eb), X(0x7ff77998), X(0x7ff7b03b),
1566 X(0x7ff7e5d7), X(0x7ff81a6f), X(0x7ff84e06), X(0x7ff880a1),
1567 X(0x7ff8b241), X(0x7ff8e2ea), X(0x7ff912a0), X(0x7ff94165),
1568 X(0x7ff96f3d), X(0x7ff99c2b), X(0x7ff9c831), X(0x7ff9f354),
1569 X(0x7ffa1d95), X(0x7ffa46f9), X(0x7ffa6f81), X(0x7ffa9731),
1570 X(0x7ffabe0d), X(0x7ffae416), X(0x7ffb0951), X(0x7ffb2dbf),
1571 X(0x7ffb5164), X(0x7ffb7442), X(0x7ffb965d), X(0x7ffbb7b8),
1572 X(0x7ffbd854), X(0x7ffbf836), X(0x7ffc175f), X(0x7ffc35d3),
1573 X(0x7ffc5394), X(0x7ffc70a5), X(0x7ffc8d09), X(0x7ffca8c2),
1574 X(0x7ffcc3d4), X(0x7ffcde3f), X(0x7ffcf809), X(0x7ffd1132),
1575 X(0x7ffd29be), X(0x7ffd41ae), X(0x7ffd5907), X(0x7ffd6fc9),
1576 X(0x7ffd85f9), X(0x7ffd9b97), X(0x7ffdb0a7), X(0x7ffdc52b),
1577 X(0x7ffdd926), X(0x7ffdec99), X(0x7ffdff88), X(0x7ffe11f4),
1578 X(0x7ffe23e0), X(0x7ffe354f), X(0x7ffe4642), X(0x7ffe56bc),
1579 X(0x7ffe66bf), X(0x7ffe764e), X(0x7ffe856a), X(0x7ffe9416),
1580 X(0x7ffea254), X(0x7ffeb026), X(0x7ffebd8e), X(0x7ffeca8f),
1581 X(0x7ffed72a), X(0x7ffee362), X(0x7ffeef38), X(0x7ffefaaf),
1582 X(0x7fff05c9), X(0x7fff1087), X(0x7fff1aec), X(0x7fff24f9),
1583 X(0x7fff2eb1), X(0x7fff3816), X(0x7fff4128), X(0x7fff49eb),
1584 X(0x7fff5260), X(0x7fff5a88), X(0x7fff6266), X(0x7fff69fc),
1585 X(0x7fff714b), X(0x7fff7854), X(0x7fff7f1a), X(0x7fff859f),
1586 X(0x7fff8be3), X(0x7fff91ea), X(0x7fff97b3), X(0x7fff9d41),
1587 X(0x7fffa296), X(0x7fffa7b3), X(0x7fffac99), X(0x7fffb14b),
1588 X(0x7fffb5c9), X(0x7fffba15), X(0x7fffbe31), X(0x7fffc21d),
1589 X(0x7fffc5dc), X(0x7fffc96f), X(0x7fffccd8), X(0x7fffd016),
1590 X(0x7fffd32d), X(0x7fffd61c), X(0x7fffd8e7), X(0x7fffdb8d),
1591 X(0x7fffde0f), X(0x7fffe071), X(0x7fffe2b1), X(0x7fffe4d2),
1592 X(0x7fffe6d5), X(0x7fffe8bb), X(0x7fffea85), X(0x7fffec34),
1593 X(0x7fffedc9), X(0x7fffef45), X(0x7ffff0aa), X(0x7ffff1f7),
1594 X(0x7ffff330), X(0x7ffff453), X(0x7ffff562), X(0x7ffff65f),
1595 X(0x7ffff749), X(0x7ffff823), X(0x7ffff8ec), X(0x7ffff9a6),
1596 X(0x7ffffa51), X(0x7ffffaee), X(0x7ffffb7e), X(0x7ffffc02),
1597 X(0x7ffffc7a), X(0x7ffffce7), X(0x7ffffd4a), X(0x7ffffda3),
1598 X(0x7ffffdf4), X(0x7ffffe3c), X(0x7ffffe7c), X(0x7ffffeb6),
1599 X(0x7ffffee8), X(0x7fffff15), X(0x7fffff3c), X(0x7fffff5e),
1600 X(0x7fffff7b), X(0x7fffff95), X(0x7fffffaa), X(0x7fffffbc),
1601 X(0x7fffffcb), X(0x7fffffd7), X(0x7fffffe2), X(0x7fffffea),
1602 X(0x7ffffff0), X(0x7ffffff5), X(0x7ffffff9), X(0x7ffffffb),
1603 X(0x7ffffffd), X(0x7ffffffe), X(0x7fffffff), X(0x7fffffff),
1604 X(0x7fffffff), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
1607 private static immutable LOOKUP_T[4096] vwin8192 = [
1608 X(0x0000007c), X(0x0000045c), X(0x00000c1d), X(0x000017bd),
1609 X(0x0000273e), X(0x00003a9f), X(0x000051e0), X(0x00006d02),
1610 X(0x00008c03), X(0x0000aee5), X(0x0000d5a7), X(0x00010049),
1611 X(0x00012ecb), X(0x0001612d), X(0x00019770), X(0x0001d193),
1612 X(0x00020f96), X(0x00025178), X(0x0002973c), X(0x0002e0df),
1613 X(0x00032e62), X(0x00037fc5), X(0x0003d509), X(0x00042e2c),
1614 X(0x00048b30), X(0x0004ec13), X(0x000550d7), X(0x0005b97a),
1615 X(0x000625fe), X(0x00069661), X(0x00070aa4), X(0x000782c8),
1616 X(0x0007fecb), X(0x00087eae), X(0x00090271), X(0x00098a14),
1617 X(0x000a1597), X(0x000aa4f9), X(0x000b383b), X(0x000bcf5d),
1618 X(0x000c6a5f), X(0x000d0941), X(0x000dac02), X(0x000e52a3),
1619 X(0x000efd23), X(0x000fab84), X(0x00105dc3), X(0x001113e3),
1620 X(0x0011cde2), X(0x00128bc0), X(0x00134d7e), X(0x0014131b),
1621 X(0x0014dc98), X(0x0015a9f4), X(0x00167b30), X(0x0017504a),
1622 X(0x00182945), X(0x0019061e), X(0x0019e6d7), X(0x001acb6f),
1623 X(0x001bb3e6), X(0x001ca03c), X(0x001d9071), X(0x001e8485),
1624 X(0x001f7c79), X(0x0020784b), X(0x002177fc), X(0x00227b8c),
1625 X(0x002382fb), X(0x00248e49), X(0x00259d76), X(0x0026b081),
1626 X(0x0027c76b), X(0x0028e234), X(0x002a00dc), X(0x002b2361),
1627 X(0x002c49c6), X(0x002d7409), X(0x002ea22a), X(0x002fd42a),
1628 X(0x00310a08), X(0x003243c5), X(0x00338160), X(0x0034c2d9),
1629 X(0x00360830), X(0x00375165), X(0x00389e78), X(0x0039ef6a),
1630 X(0x003b4439), X(0x003c9ce6), X(0x003df971), X(0x003f59da),
1631 X(0x0040be20), X(0x00422645), X(0x00439247), X(0x00450226),
1632 X(0x004675e3), X(0x0047ed7e), X(0x004968f5), X(0x004ae84b),
1633 X(0x004c6b7d), X(0x004df28d), X(0x004f7d7a), X(0x00510c44),
1634 X(0x00529eeb), X(0x00543570), X(0x0055cfd1), X(0x00576e0f),
1635 X(0x00591029), X(0x005ab621), X(0x005c5ff5), X(0x005e0da6),
1636 X(0x005fbf33), X(0x0061749d), X(0x00632de4), X(0x0064eb06),
1637 X(0x0066ac05), X(0x006870e0), X(0x006a3998), X(0x006c062b),
1638 X(0x006dd69b), X(0x006faae6), X(0x0071830d), X(0x00735f10),
1639 X(0x00753eef), X(0x007722a9), X(0x00790a3f), X(0x007af5b1),
1640 X(0x007ce4fe), X(0x007ed826), X(0x0080cf29), X(0x0082ca08),
1641 X(0x0084c8c2), X(0x0086cb57), X(0x0088d1c7), X(0x008adc11),
1642 X(0x008cea37), X(0x008efc37), X(0x00911212), X(0x00932bc7),
1643 X(0x00954957), X(0x00976ac2), X(0x00999006), X(0x009bb925),
1644 X(0x009de61e), X(0x00a016f1), X(0x00a24b9e), X(0x00a48425),
1645 X(0x00a6c086), X(0x00a900c0), X(0x00ab44d4), X(0x00ad8cc2),
1646 X(0x00afd889), X(0x00b22829), X(0x00b47ba2), X(0x00b6d2f5),
1647 X(0x00b92e21), X(0x00bb8d26), X(0x00bdf004), X(0x00c056ba),
1648 X(0x00c2c149), X(0x00c52fb1), X(0x00c7a1f1), X(0x00ca180a),
1649 X(0x00cc91fb), X(0x00cf0fc5), X(0x00d19166), X(0x00d416df),
1650 X(0x00d6a031), X(0x00d92d5a), X(0x00dbbe5b), X(0x00de5333),
1651 X(0x00e0ebe3), X(0x00e3886b), X(0x00e628c9), X(0x00e8ccff),
1652 X(0x00eb750c), X(0x00ee20f0), X(0x00f0d0ab), X(0x00f3843d),
1653 X(0x00f63ba5), X(0x00f8f6e4), X(0x00fbb5fa), X(0x00fe78e5),
1654 X(0x01013fa7), X(0x01040a3f), X(0x0106d8ae), X(0x0109aaf2),
1655 X(0x010c810c), X(0x010f5afb), X(0x011238c0), X(0x01151a5b),
1656 X(0x0117ffcb), X(0x011ae910), X(0x011dd62a), X(0x0120c719),
1657 X(0x0123bbdd), X(0x0126b476), X(0x0129b0e4), X(0x012cb126),
1658 X(0x012fb53c), X(0x0132bd27), X(0x0135c8e6), X(0x0138d879),
1659 X(0x013bebdf), X(0x013f031a), X(0x01421e28), X(0x01453d0a),
1660 X(0x01485fbf), X(0x014b8648), X(0x014eb0a4), X(0x0151ded2),
1661 X(0x015510d4), X(0x015846a8), X(0x015b8050), X(0x015ebdc9),
1662 X(0x0161ff15), X(0x01654434), X(0x01688d24), X(0x016bd9e6),
1663 X(0x016f2a7b), X(0x01727ee1), X(0x0175d718), X(0x01793321),
1664 X(0x017c92fc), X(0x017ff6a7), X(0x01835e24), X(0x0186c972),
1665 X(0x018a3890), X(0x018dab7f), X(0x0191223f), X(0x01949ccf),
1666 X(0x01981b2f), X(0x019b9d5f), X(0x019f235f), X(0x01a2ad2f),
1667 X(0x01a63acf), X(0x01a9cc3e), X(0x01ad617c), X(0x01b0fa8a),
1668 X(0x01b49767), X(0x01b83813), X(0x01bbdc8d), X(0x01bf84d6),
1669 X(0x01c330ee), X(0x01c6e0d4), X(0x01ca9488), X(0x01ce4c0b),
1670 X(0x01d2075b), X(0x01d5c679), X(0x01d98964), X(0x01dd501d),
1671 X(0x01e11aa3), X(0x01e4e8f6), X(0x01e8bb17), X(0x01ec9104),
1672 X(0x01f06abd), X(0x01f44844), X(0x01f82996), X(0x01fc0eb5),
1673 X(0x01fff7a0), X(0x0203e456), X(0x0207d4d9), X(0x020bc926),
1674 X(0x020fc140), X(0x0213bd24), X(0x0217bcd4), X(0x021bc04e),
1675 X(0x021fc793), X(0x0223d2a3), X(0x0227e17d), X(0x022bf421),
1676 X(0x02300a90), X(0x023424c8), X(0x023842ca), X(0x023c6495),
1677 X(0x02408a2a), X(0x0244b389), X(0x0248e0b0), X(0x024d11a0),
1678 X(0x02514659), X(0x02557eda), X(0x0259bb24), X(0x025dfb35),
1679 X(0x02623f0f), X(0x026686b1), X(0x026ad21a), X(0x026f214b),
1680 X(0x02737443), X(0x0277cb02), X(0x027c2588), X(0x028083d5),
1681 X(0x0284e5e9), X(0x02894bc2), X(0x028db562), X(0x029222c8),
1682 X(0x029693f4), X(0x029b08e6), X(0x029f819d), X(0x02a3fe19),
1683 X(0x02a87e5b), X(0x02ad0261), X(0x02b18a2c), X(0x02b615bb),
1684 X(0x02baa50f), X(0x02bf3827), X(0x02c3cf03), X(0x02c869a3),
1685 X(0x02cd0807), X(0x02d1aa2d), X(0x02d65017), X(0x02daf9c4),
1686 X(0x02dfa734), X(0x02e45866), X(0x02e90d5b), X(0x02edc612),
1687 X(0x02f2828b), X(0x02f742c6), X(0x02fc06c3), X(0x0300ce80),
1688 X(0x030599ff), X(0x030a6940), X(0x030f3c40), X(0x03141302),
1689 X(0x0318ed84), X(0x031dcbc6), X(0x0322adc8), X(0x0327938a),
1690 X(0x032c7d0c), X(0x03316a4c), X(0x03365b4d), X(0x033b500c),
1691 X(0x03404889), X(0x034544c6), X(0x034a44c0), X(0x034f4879),
1692 X(0x03544ff0), X(0x03595b24), X(0x035e6a16), X(0x03637cc5),
1693 X(0x03689331), X(0x036dad5a), X(0x0372cb40), X(0x0377ece2),
1694 X(0x037d1240), X(0x03823b5a), X(0x03876830), X(0x038c98c1),
1695 X(0x0391cd0e), X(0x03970516), X(0x039c40d8), X(0x03a18055),
1696 X(0x03a6c38d), X(0x03ac0a7f), X(0x03b1552b), X(0x03b6a390),
1697 X(0x03bbf5af), X(0x03c14b88), X(0x03c6a519), X(0x03cc0263),
1698 X(0x03d16366), X(0x03d6c821), X(0x03dc3094), X(0x03e19cc0),
1699 X(0x03e70ca2), X(0x03ec803d), X(0x03f1f78e), X(0x03f77296),
1700 X(0x03fcf155), X(0x040273cb), X(0x0407f9f7), X(0x040d83d9),
1701 X(0x04131170), X(0x0418a2bd), X(0x041e37c0), X(0x0423d077),
1702 X(0x04296ce4), X(0x042f0d04), X(0x0434b0da), X(0x043a5863),
1703 X(0x044003a0), X(0x0445b290), X(0x044b6534), X(0x04511b8b),
1704 X(0x0456d595), X(0x045c9352), X(0x046254c1), X(0x046819e1),
1705 X(0x046de2b4), X(0x0473af39), X(0x04797f6e), X(0x047f5355),
1706 X(0x04852aec), X(0x048b0635), X(0x0490e52d), X(0x0496c7d6),
1707 X(0x049cae2e), X(0x04a29836), X(0x04a885ed), X(0x04ae7753),
1708 X(0x04b46c68), X(0x04ba652b), X(0x04c0619d), X(0x04c661bc),
1709 X(0x04cc658a), X(0x04d26d04), X(0x04d8782c), X(0x04de8701),
1710 X(0x04e49983), X(0x04eaafb0), X(0x04f0c98a), X(0x04f6e710),
1711 X(0x04fd0842), X(0x05032d1e), X(0x050955a6), X(0x050f81d8),
1712 X(0x0515b1b5), X(0x051be53d), X(0x05221c6e), X(0x05285748),
1713 X(0x052e95cd), X(0x0534d7fa), X(0x053b1dd0), X(0x0541674e),
1714 X(0x0547b475), X(0x054e0544), X(0x055459bb), X(0x055ab1d9),
1715 X(0x05610d9e), X(0x05676d0a), X(0x056dd01c), X(0x057436d5),
1716 X(0x057aa134), X(0x05810f38), X(0x058780e2), X(0x058df631),
1717 X(0x05946f25), X(0x059aebbe), X(0x05a16bfa), X(0x05a7efdb),
1718 X(0x05ae775f), X(0x05b50287), X(0x05bb9152), X(0x05c223c0),
1719 X(0x05c8b9d0), X(0x05cf5382), X(0x05d5f0d6), X(0x05dc91cc),
1720 X(0x05e33663), X(0x05e9de9c), X(0x05f08a75), X(0x05f739ee),
1721 X(0x05fded07), X(0x0604a3c0), X(0x060b5e19), X(0x06121c11),
1722 X(0x0618dda8), X(0x061fa2dd), X(0x06266bb1), X(0x062d3822),
1723 X(0x06340831), X(0x063adbde), X(0x0641b328), X(0x06488e0e),
1724 X(0x064f6c91), X(0x06564eaf), X(0x065d346a), X(0x06641dc0),
1725 X(0x066b0ab1), X(0x0671fb3d), X(0x0678ef64), X(0x067fe724),
1726 X(0x0686e27f), X(0x068de173), X(0x0694e400), X(0x069bea27),
1727 X(0x06a2f3e6), X(0x06aa013d), X(0x06b1122c), X(0x06b826b3),
1728 X(0x06bf3ed1), X(0x06c65a86), X(0x06cd79d1), X(0x06d49cb3),
1729 X(0x06dbc32b), X(0x06e2ed38), X(0x06ea1adb), X(0x06f14c13),
1730 X(0x06f880df), X(0x06ffb940), X(0x0706f535), X(0x070e34bd),
1731 X(0x071577d9), X(0x071cbe88), X(0x072408c9), X(0x072b569d),
1732 X(0x0732a802), X(0x0739fcf9), X(0x07415582), X(0x0748b19b),
1733 X(0x07501145), X(0x0757747f), X(0x075edb49), X(0x076645a3),
1734 X(0x076db38c), X(0x07752503), X(0x077c9a09), X(0x0784129e),
1735 X(0x078b8ec0), X(0x07930e70), X(0x079a91ac), X(0x07a21876),
1736 X(0x07a9a2cc), X(0x07b130ad), X(0x07b8c21b), X(0x07c05714),
1737 X(0x07c7ef98), X(0x07cf8ba6), X(0x07d72b3f), X(0x07dece62),
1738 X(0x07e6750e), X(0x07ee1f43), X(0x07f5cd01), X(0x07fd7e48),
1739 X(0x08053316), X(0x080ceb6d), X(0x0814a74a), X(0x081c66af),
1740 X(0x0824299a), X(0x082bf00c), X(0x0833ba03), X(0x083b8780),
1741 X(0x08435882), X(0x084b2d09), X(0x08530514), X(0x085ae0a3),
1742 X(0x0862bfb6), X(0x086aa24c), X(0x08728865), X(0x087a7201),
1743 X(0x08825f1e), X(0x088a4fbe), X(0x089243de), X(0x089a3b80),
1744 X(0x08a236a2), X(0x08aa3545), X(0x08b23767), X(0x08ba3d09),
1745 X(0x08c2462a), X(0x08ca52c9), X(0x08d262e7), X(0x08da7682),
1746 X(0x08e28d9c), X(0x08eaa832), X(0x08f2c645), X(0x08fae7d4),
1747 X(0x09030cdf), X(0x090b3566), X(0x09136168), X(0x091b90e5),
1748 X(0x0923c3dc), X(0x092bfa4d), X(0x09343437), X(0x093c719b),
1749 X(0x0944b277), X(0x094cf6cc), X(0x09553e99), X(0x095d89dd),
1750 X(0x0965d899), X(0x096e2acb), X(0x09768073), X(0x097ed991),
1751 X(0x09873625), X(0x098f962e), X(0x0997f9ac), X(0x09a0609e),
1752 X(0x09a8cb04), X(0x09b138dd), X(0x09b9aa29), X(0x09c21ee8),
1753 X(0x09ca9719), X(0x09d312bc), X(0x09db91d0), X(0x09e41456),
1754 X(0x09ec9a4b), X(0x09f523b1), X(0x09fdb087), X(0x0a0640cc),
1755 X(0x0a0ed47f), X(0x0a176ba2), X(0x0a200632), X(0x0a28a42f),
1756 X(0x0a31459a), X(0x0a39ea72), X(0x0a4292b5), X(0x0a4b3e65),
1757 X(0x0a53ed80), X(0x0a5ca006), X(0x0a6555f7), X(0x0a6e0f51),
1758 X(0x0a76cc16), X(0x0a7f8c44), X(0x0a884fda), X(0x0a9116d9),
1759 X(0x0a99e140), X(0x0aa2af0e), X(0x0aab8043), X(0x0ab454df),
1760 X(0x0abd2ce1), X(0x0ac60849), X(0x0acee716), X(0x0ad7c948),
1761 X(0x0ae0aedf), X(0x0ae997d9), X(0x0af28437), X(0x0afb73f7),
1762 X(0x0b04671b), X(0x0b0d5da0), X(0x0b165788), X(0x0b1f54d0),
1763 X(0x0b285579), X(0x0b315983), X(0x0b3a60ec), X(0x0b436bb5),
1764 X(0x0b4c79dd), X(0x0b558b63), X(0x0b5ea048), X(0x0b67b88a),
1765 X(0x0b70d429), X(0x0b79f324), X(0x0b83157c), X(0x0b8c3b30),
1766 X(0x0b95643f), X(0x0b9e90a8), X(0x0ba7c06c), X(0x0bb0f38a),
1767 X(0x0bba2a01), X(0x0bc363d1), X(0x0bcca0f9), X(0x0bd5e17a),
1768 X(0x0bdf2552), X(0x0be86c81), X(0x0bf1b706), X(0x0bfb04e2),
1769 X(0x0c045613), X(0x0c0daa99), X(0x0c170274), X(0x0c205da3),
1770 X(0x0c29bc25), X(0x0c331dfb), X(0x0c3c8323), X(0x0c45eb9e),
1771 X(0x0c4f576a), X(0x0c58c688), X(0x0c6238f6), X(0x0c6baeb5),
1772 X(0x0c7527c3), X(0x0c7ea421), X(0x0c8823cd), X(0x0c91a6c8),
1773 X(0x0c9b2d10), X(0x0ca4b6a6), X(0x0cae4389), X(0x0cb7d3b8),
1774 X(0x0cc16732), X(0x0ccafdf8), X(0x0cd49809), X(0x0cde3564),
1775 X(0x0ce7d609), X(0x0cf179f7), X(0x0cfb212e), X(0x0d04cbad),
1776 X(0x0d0e7974), X(0x0d182a83), X(0x0d21ded8), X(0x0d2b9673),
1777 X(0x0d355154), X(0x0d3f0f7b), X(0x0d48d0e6), X(0x0d529595),
1778 X(0x0d5c5d88), X(0x0d6628be), X(0x0d6ff737), X(0x0d79c8f2),
1779 X(0x0d839dee), X(0x0d8d762c), X(0x0d9751aa), X(0x0da13068),
1780 X(0x0dab1266), X(0x0db4f7a3), X(0x0dbee01e), X(0x0dc8cbd8),
1781 X(0x0dd2bace), X(0x0ddcad02), X(0x0de6a272), X(0x0df09b1e),
1782 X(0x0dfa9705), X(0x0e049627), X(0x0e0e9883), X(0x0e189e19),
1783 X(0x0e22a6e8), X(0x0e2cb2f0), X(0x0e36c230), X(0x0e40d4a8),
1784 X(0x0e4aea56), X(0x0e55033b), X(0x0e5f1f56), X(0x0e693ea7),
1785 X(0x0e73612c), X(0x0e7d86e5), X(0x0e87afd3), X(0x0e91dbf3),
1786 X(0x0e9c0b47), X(0x0ea63dcc), X(0x0eb07383), X(0x0ebaac6b),
1787 X(0x0ec4e883), X(0x0ecf27cc), X(0x0ed96a44), X(0x0ee3afea),
1788 X(0x0eedf8bf), X(0x0ef844c2), X(0x0f0293f2), X(0x0f0ce64e),
1789 X(0x0f173bd6), X(0x0f21948a), X(0x0f2bf069), X(0x0f364f72),
1790 X(0x0f40b1a5), X(0x0f4b1701), X(0x0f557f86), X(0x0f5feb32),
1791 X(0x0f6a5a07), X(0x0f74cc02), X(0x0f7f4124), X(0x0f89b96b),
1792 X(0x0f9434d8), X(0x0f9eb369), X(0x0fa9351e), X(0x0fb3b9f7),
1793 X(0x0fbe41f3), X(0x0fc8cd11), X(0x0fd35b51), X(0x0fddecb2),
1794 X(0x0fe88134), X(0x0ff318d6), X(0x0ffdb397), X(0x10085177),
1795 X(0x1012f275), X(0x101d9691), X(0x10283dca), X(0x1032e81f),
1796 X(0x103d9591), X(0x1048461e), X(0x1052f9c5), X(0x105db087),
1797 X(0x10686a62), X(0x10732756), X(0x107de763), X(0x1088aa87),
1798 X(0x109370c2), X(0x109e3a14), X(0x10a9067c), X(0x10b3d5f9),
1799 X(0x10bea88b), X(0x10c97e31), X(0x10d456eb), X(0x10df32b8),
1800 X(0x10ea1197), X(0x10f4f387), X(0x10ffd889), X(0x110ac09b),
1801 X(0x1115abbe), X(0x112099ef), X(0x112b8b2f), X(0x11367f7d),
1802 X(0x114176d9), X(0x114c7141), X(0x11576eb6), X(0x11626f36),
1803 X(0x116d72c1), X(0x11787957), X(0x118382f6), X(0x118e8f9e),
1804 X(0x11999f4f), X(0x11a4b208), X(0x11afc7c7), X(0x11bae08e),
1805 X(0x11c5fc5a), X(0x11d11b2c), X(0x11dc3d02), X(0x11e761dd),
1806 X(0x11f289ba), X(0x11fdb49b), X(0x1208e27e), X(0x12141362),
1807 X(0x121f4748), X(0x122a7e2d), X(0x1235b812), X(0x1240f4f6),
1808 X(0x124c34d9), X(0x125777b9), X(0x1262bd96), X(0x126e0670),
1809 X(0x12795245), X(0x1284a115), X(0x128ff2e0), X(0x129b47a5),
1810 X(0x12a69f63), X(0x12b1fa19), X(0x12bd57c7), X(0x12c8b86c),
1811 X(0x12d41c08), X(0x12df829a), X(0x12eaec21), X(0x12f6589d),
1812 X(0x1301c80c), X(0x130d3a6f), X(0x1318afc4), X(0x1324280b),
1813 X(0x132fa344), X(0x133b216d), X(0x1346a286), X(0x1352268e),
1814 X(0x135dad85), X(0x1369376a), X(0x1374c43c), X(0x138053fb),
1815 X(0x138be6a5), X(0x13977c3b), X(0x13a314bc), X(0x13aeb026),
1816 X(0x13ba4e79), X(0x13c5efb5), X(0x13d193d9), X(0x13dd3ae4),
1817 X(0x13e8e4d6), X(0x13f491ad), X(0x1400416a), X(0x140bf40b),
1818 X(0x1417a98f), X(0x142361f7), X(0x142f1d41), X(0x143adb6d),
1819 X(0x14469c7a), X(0x14526067), X(0x145e2734), X(0x1469f0df),
1820 X(0x1475bd69), X(0x14818cd0), X(0x148d5f15), X(0x14993435),
1821 X(0x14a50c31), X(0x14b0e708), X(0x14bcc4b8), X(0x14c8a542),
1822 X(0x14d488a5), X(0x14e06edf), X(0x14ec57f1), X(0x14f843d9),
1823 X(0x15043297), X(0x1510242b), X(0x151c1892), X(0x15280fcd),
1824 X(0x153409dc), X(0x154006bc), X(0x154c066e), X(0x155808f1),
1825 X(0x15640e44), X(0x15701666), X(0x157c2157), X(0x15882f16),
1826 X(0x15943fa2), X(0x15a052fb), X(0x15ac691f), X(0x15b8820f),
1827 X(0x15c49dc8), X(0x15d0bc4c), X(0x15dcdd98), X(0x15e901ad),
1828 X(0x15f52888), X(0x1601522b), X(0x160d7e93), X(0x1619adc1),
1829 X(0x1625dfb3), X(0x16321469), X(0x163e4be2), X(0x164a861d),
1830 X(0x1656c31a), X(0x166302d8), X(0x166f4555), X(0x167b8a92),
1831 X(0x1687d28e), X(0x16941d47), X(0x16a06abe), X(0x16acbaf0),
1832 X(0x16b90ddf), X(0x16c56388), X(0x16d1bbeb), X(0x16de1708),
1833 X(0x16ea74dd), X(0x16f6d56a), X(0x170338ae), X(0x170f9ea8),
1834 X(0x171c0758), X(0x172872bd), X(0x1734e0d6), X(0x174151a2),
1835 X(0x174dc520), X(0x175a3b51), X(0x1766b432), X(0x17732fc4),
1836 X(0x177fae05), X(0x178c2ef4), X(0x1798b292), X(0x17a538dd),
1837 X(0x17b1c1d4), X(0x17be4d77), X(0x17cadbc5), X(0x17d76cbc),
1838 X(0x17e4005e), X(0x17f096a7), X(0x17fd2f98), X(0x1809cb31),
1839 X(0x1816696f), X(0x18230a53), X(0x182faddc), X(0x183c5408),
1840 X(0x1848fcd8), X(0x1855a849), X(0x1862565d), X(0x186f0711),
1841 X(0x187bba64), X(0x18887057), X(0x189528e9), X(0x18a1e418),
1842 X(0x18aea1e3), X(0x18bb624b), X(0x18c8254e), X(0x18d4eaeb),
1843 X(0x18e1b321), X(0x18ee7df1), X(0x18fb4b58), X(0x19081b57),
1844 X(0x1914edec), X(0x1921c317), X(0x192e9ad6), X(0x193b7529),
1845 X(0x19485210), X(0x19553189), X(0x19621393), X(0x196ef82e),
1846 X(0x197bdf59), X(0x1988c913), X(0x1995b55c), X(0x19a2a432),
1847 X(0x19af9595), X(0x19bc8983), X(0x19c97ffd), X(0x19d67900),
1848 X(0x19e3748e), X(0x19f072a3), X(0x19fd7341), X(0x1a0a7665),
1849 X(0x1a177c10), X(0x1a248440), X(0x1a318ef4), X(0x1a3e9c2c),
1850 X(0x1a4babe7), X(0x1a58be24), X(0x1a65d2e2), X(0x1a72ea20),
1851 X(0x1a8003de), X(0x1a8d201a), X(0x1a9a3ed5), X(0x1aa7600c),
1852 X(0x1ab483bf), X(0x1ac1a9ee), X(0x1aced297), X(0x1adbfdba),
1853 X(0x1ae92b56), X(0x1af65b69), X(0x1b038df4), X(0x1b10c2f5),
1854 X(0x1b1dfa6b), X(0x1b2b3456), X(0x1b3870b5), X(0x1b45af87),
1855 X(0x1b52f0ca), X(0x1b60347f), X(0x1b6d7aa4), X(0x1b7ac339),
1856 X(0x1b880e3c), X(0x1b955bad), X(0x1ba2ab8b), X(0x1baffdd5),
1857 X(0x1bbd528a), X(0x1bcaa9a9), X(0x1bd80332), X(0x1be55f24),
1858 X(0x1bf2bd7d), X(0x1c001e3d), X(0x1c0d8164), X(0x1c1ae6ef),
1859 X(0x1c284edf), X(0x1c35b932), X(0x1c4325e7), X(0x1c5094fe),
1860 X(0x1c5e0677), X(0x1c6b7a4f), X(0x1c78f086), X(0x1c86691b),
1861 X(0x1c93e40d), X(0x1ca1615c), X(0x1caee107), X(0x1cbc630c),
1862 X(0x1cc9e76b), X(0x1cd76e23), X(0x1ce4f733), X(0x1cf2829a),
1863 X(0x1d001057), X(0x1d0da06a), X(0x1d1b32d1), X(0x1d28c78c),
1864 X(0x1d365e9a), X(0x1d43f7f9), X(0x1d5193a9), X(0x1d5f31aa),
1865 X(0x1d6cd1f9), X(0x1d7a7497), X(0x1d881982), X(0x1d95c0ba),
1866 X(0x1da36a3d), X(0x1db1160a), X(0x1dbec422), X(0x1dcc7482),
1867 X(0x1dda272b), X(0x1de7dc1a), X(0x1df59350), X(0x1e034ccb),
1868 X(0x1e11088a), X(0x1e1ec68c), X(0x1e2c86d1), X(0x1e3a4958),
1869 X(0x1e480e20), X(0x1e55d527), X(0x1e639e6d), X(0x1e7169f1),
1870 X(0x1e7f37b2), X(0x1e8d07b0), X(0x1e9ad9e8), X(0x1ea8ae5b),
1871 X(0x1eb68507), X(0x1ec45dec), X(0x1ed23908), X(0x1ee0165b),
1872 X(0x1eedf5e4), X(0x1efbd7a1), X(0x1f09bb92), X(0x1f17a1b6),
1873 X(0x1f258a0d), X(0x1f337494), X(0x1f41614b), X(0x1f4f5032),
1874 X(0x1f5d4147), X(0x1f6b3489), X(0x1f7929f7), X(0x1f872192),
1875 X(0x1f951b56), X(0x1fa31744), X(0x1fb1155b), X(0x1fbf159a),
1876 X(0x1fcd17ff), X(0x1fdb1c8b), X(0x1fe9233b), X(0x1ff72c0f),
1877 X(0x20053706), X(0x20134420), X(0x2021535a), X(0x202f64b4),
1878 X(0x203d782e), X(0x204b8dc6), X(0x2059a57c), X(0x2067bf4e),
1879 X(0x2075db3b), X(0x2083f943), X(0x20921964), X(0x20a03b9e),
1880 X(0x20ae5fef), X(0x20bc8657), X(0x20caaed5), X(0x20d8d967),
1881 X(0x20e7060e), X(0x20f534c7), X(0x21036592), X(0x2111986e),
1882 X(0x211fcd59), X(0x212e0454), X(0x213c3d5d), X(0x214a7873),
1883 X(0x2158b594), X(0x2166f4c1), X(0x217535f8), X(0x21837938),
1884 X(0x2191be81), X(0x21a005d0), X(0x21ae4f26), X(0x21bc9a81),
1885 X(0x21cae7e0), X(0x21d93743), X(0x21e788a8), X(0x21f5dc0e),
1886 X(0x22043174), X(0x221288da), X(0x2220e23e), X(0x222f3da0),
1887 X(0x223d9afe), X(0x224bfa58), X(0x225a5bac), X(0x2268bef9),
1888 X(0x2277243f), X(0x22858b7d), X(0x2293f4b0), X(0x22a25fda),
1889 X(0x22b0ccf8), X(0x22bf3c09), X(0x22cdad0d), X(0x22dc2002),
1890 X(0x22ea94e8), X(0x22f90bbe), X(0x23078482), X(0x2315ff33),
1891 X(0x23247bd1), X(0x2332fa5b), X(0x23417acf), X(0x234ffd2c),
1892 X(0x235e8173), X(0x236d07a0), X(0x237b8fb4), X(0x238a19ae),
1893 X(0x2398a58c), X(0x23a7334d), X(0x23b5c2f1), X(0x23c45477),
1894 X(0x23d2e7dd), X(0x23e17d22), X(0x23f01446), X(0x23fead47),
1895 X(0x240d4825), X(0x241be4dd), X(0x242a8371), X(0x243923dd),
1896 X(0x2447c622), X(0x24566a3e), X(0x24651031), X(0x2473b7f8),
1897 X(0x24826194), X(0x24910d03), X(0x249fba44), X(0x24ae6957),
1898 X(0x24bd1a39), X(0x24cbccea), X(0x24da816a), X(0x24e937b7),
1899 X(0x24f7efcf), X(0x2506a9b3), X(0x25156560), X(0x252422d6),
1900 X(0x2532e215), X(0x2541a31a), X(0x255065e4), X(0x255f2a74),
1901 X(0x256df0c7), X(0x257cb8dd), X(0x258b82b4), X(0x259a4e4c),
1902 X(0x25a91ba4), X(0x25b7eaba), X(0x25c6bb8e), X(0x25d58e1e),
1903 X(0x25e46269), X(0x25f3386e), X(0x2602102d), X(0x2610e9a4),
1904 X(0x261fc4d3), X(0x262ea1b7), X(0x263d8050), X(0x264c609e),
1905 X(0x265b429e), X(0x266a2650), X(0x26790bb3), X(0x2687f2c6),
1906 X(0x2696db88), X(0x26a5c5f7), X(0x26b4b213), X(0x26c39fda),
1907 X(0x26d28f4c), X(0x26e18067), X(0x26f0732b), X(0x26ff6796),
1908 X(0x270e5da7), X(0x271d555d), X(0x272c4eb7), X(0x273b49b5),
1909 X(0x274a4654), X(0x27594495), X(0x27684475), X(0x277745f4),
1910 X(0x27864910), X(0x27954dc9), X(0x27a4541e), X(0x27b35c0d),
1911 X(0x27c26596), X(0x27d170b7), X(0x27e07d6f), X(0x27ef8bbd),
1912 X(0x27fe9ba0), X(0x280dad18), X(0x281cc022), X(0x282bd4be),
1913 X(0x283aeaeb), X(0x284a02a7), X(0x28591bf2), X(0x286836cb),
1914 X(0x28775330), X(0x28867120), X(0x2895909b), X(0x28a4b19e),
1915 X(0x28b3d42a), X(0x28c2f83d), X(0x28d21dd5), X(0x28e144f3),
1916 X(0x28f06d94), X(0x28ff97b8), X(0x290ec35d), X(0x291df082),
1917 X(0x292d1f27), X(0x293c4f4a), X(0x294b80eb), X(0x295ab407),
1918 X(0x2969e89e), X(0x29791eaf), X(0x29885639), X(0x29978f3b),
1919 X(0x29a6c9b3), X(0x29b605a0), X(0x29c54302), X(0x29d481d7),
1920 X(0x29e3c21e), X(0x29f303d6), X(0x2a0246fd), X(0x2a118b94),
1921 X(0x2a20d198), X(0x2a301909), X(0x2a3f61e6), X(0x2a4eac2c),
1922 X(0x2a5df7dc), X(0x2a6d44f4), X(0x2a7c9374), X(0x2a8be359),
1923 X(0x2a9b34a2), X(0x2aaa8750), X(0x2ab9db60), X(0x2ac930d1),
1924 X(0x2ad887a3), X(0x2ae7dfd3), X(0x2af73962), X(0x2b06944e),
1925 X(0x2b15f096), X(0x2b254e38), X(0x2b34ad34), X(0x2b440d89),
1926 X(0x2b536f34), X(0x2b62d236), X(0x2b72368d), X(0x2b819c38),
1927 X(0x2b910336), X(0x2ba06b86), X(0x2bafd526), X(0x2bbf4015),
1928 X(0x2bceac53), X(0x2bde19de), X(0x2bed88b5), X(0x2bfcf8d7),
1929 X(0x2c0c6a43), X(0x2c1bdcf7), X(0x2c2b50f3), X(0x2c3ac635),
1930 X(0x2c4a3cbd), X(0x2c59b488), X(0x2c692d97), X(0x2c78a7e7),
1931 X(0x2c882378), X(0x2c97a049), X(0x2ca71e58), X(0x2cb69da4),
1932 X(0x2cc61e2c), X(0x2cd59ff0), X(0x2ce522ed), X(0x2cf4a723),
1933 X(0x2d042c90), X(0x2d13b334), X(0x2d233b0d), X(0x2d32c41a),
1934 X(0x2d424e5a), X(0x2d51d9cc), X(0x2d61666e), X(0x2d70f440),
1935 X(0x2d808340), X(0x2d90136e), X(0x2d9fa4c7), X(0x2daf374c),
1936 X(0x2dbecafa), X(0x2dce5fd1), X(0x2dddf5cf), X(0x2ded8cf4),
1937 X(0x2dfd253d), X(0x2e0cbeab), X(0x2e1c593b), X(0x2e2bf4ed),
1938 X(0x2e3b91c0), X(0x2e4b2fb1), X(0x2e5acec1), X(0x2e6a6eee),
1939 X(0x2e7a1037), X(0x2e89b29b), X(0x2e995618), X(0x2ea8faad),
1940 X(0x2eb8a05a), X(0x2ec8471c), X(0x2ed7eef4), X(0x2ee797df),
1941 X(0x2ef741dc), X(0x2f06eceb), X(0x2f16990a), X(0x2f264639),
1942 X(0x2f35f475), X(0x2f45a3bd), X(0x2f555412), X(0x2f650570),
1943 X(0x2f74b7d8), X(0x2f846b48), X(0x2f941fbe), X(0x2fa3d53a),
1944 X(0x2fb38bbb), X(0x2fc3433f), X(0x2fd2fbc5), X(0x2fe2b54c),
1945 X(0x2ff26fd3), X(0x30022b58), X(0x3011e7db), X(0x3021a55a),
1946 X(0x303163d4), X(0x30412348), X(0x3050e3b5), X(0x3060a519),
1947 X(0x30706773), X(0x30802ac3), X(0x308fef06), X(0x309fb43d),
1948 X(0x30af7a65), X(0x30bf417d), X(0x30cf0985), X(0x30ded27a),
1949 X(0x30ee9c5d), X(0x30fe672b), X(0x310e32e3), X(0x311dff85),
1950 X(0x312dcd0f), X(0x313d9b80), X(0x314d6ad7), X(0x315d3b12),
1951 X(0x316d0c30), X(0x317cde31), X(0x318cb113), X(0x319c84d4),
1952 X(0x31ac5974), X(0x31bc2ef1), X(0x31cc054b), X(0x31dbdc7f),
1953 X(0x31ebb48e), X(0x31fb8d74), X(0x320b6733), X(0x321b41c7),
1954 X(0x322b1d31), X(0x323af96e), X(0x324ad67e), X(0x325ab45f),
1955 X(0x326a9311), X(0x327a7291), X(0x328a52e0), X(0x329a33fb),
1956 X(0x32aa15e1), X(0x32b9f892), X(0x32c9dc0c), X(0x32d9c04d),
1957 X(0x32e9a555), X(0x32f98b22), X(0x330971b4), X(0x33195909),
1958 X(0x3329411f), X(0x333929f6), X(0x3349138c), X(0x3358fde1),
1959 X(0x3368e8f2), X(0x3378d4c0), X(0x3388c147), X(0x3398ae89),
1960 X(0x33a89c82), X(0x33b88b32), X(0x33c87a98), X(0x33d86ab2),
1961 X(0x33e85b80), X(0x33f84d00), X(0x34083f30), X(0x34183210),
1962 X(0x3428259f), X(0x343819db), X(0x34480ec3), X(0x34580455),
1963 X(0x3467fa92), X(0x3477f176), X(0x3487e902), X(0x3497e134),
1964 X(0x34a7da0a), X(0x34b7d384), X(0x34c7cda0), X(0x34d7c85e),
1965 X(0x34e7c3bb), X(0x34f7bfb7), X(0x3507bc50), X(0x3517b985),
1966 X(0x3527b756), X(0x3537b5c0), X(0x3547b4c3), X(0x3557b45d),
1967 X(0x3567b48d), X(0x3577b552), X(0x3587b6aa), X(0x3597b895),
1968 X(0x35a7bb12), X(0x35b7be1e), X(0x35c7c1b9), X(0x35d7c5e1),
1969 X(0x35e7ca96), X(0x35f7cfd6), X(0x3607d5a0), X(0x3617dbf3),
1970 X(0x3627e2cd), X(0x3637ea2d), X(0x3647f212), X(0x3657fa7b),
1971 X(0x36680366), X(0x36780cd2), X(0x368816bf), X(0x3698212b),
1972 X(0x36a82c14), X(0x36b83779), X(0x36c8435a), X(0x36d84fb4),
1973 X(0x36e85c88), X(0x36f869d2), X(0x37087793), X(0x371885c9),
1974 X(0x37289473), X(0x3738a38f), X(0x3748b31d), X(0x3758c31a),
1975 X(0x3768d387), X(0x3778e461), X(0x3788f5a7), X(0x37990759),
1976 X(0x37a91975), X(0x37b92bf9), X(0x37c93ee4), X(0x37d95236),
1977 X(0x37e965ed), X(0x37f97a08), X(0x38098e85), X(0x3819a363),
1978 X(0x3829b8a2), X(0x3839ce3f), X(0x3849e43a), X(0x3859fa91),
1979 X(0x386a1143), X(0x387a284f), X(0x388a3fb4), X(0x389a5770),
1980 X(0x38aa6f83), X(0x38ba87ea), X(0x38caa0a5), X(0x38dab9b2),
1981 X(0x38ead311), X(0x38faecbf), X(0x390b06bc), X(0x391b2107),
1982 X(0x392b3b9e), X(0x393b5680), X(0x394b71ac), X(0x395b8d20),
1983 X(0x396ba8dc), X(0x397bc4dd), X(0x398be124), X(0x399bfdae),
1984 X(0x39ac1a7a), X(0x39bc3788), X(0x39cc54d5), X(0x39dc7261),
1985 X(0x39ec902a), X(0x39fcae2f), X(0x3a0ccc70), X(0x3a1ceaea),
1986 X(0x3a2d099c), X(0x3a3d2885), X(0x3a4d47a5), X(0x3a5d66f9),
1987 X(0x3a6d8680), X(0x3a7da63a), X(0x3a8dc625), X(0x3a9de63f),
1988 X(0x3aae0688), X(0x3abe26fe), X(0x3ace47a0), X(0x3ade686d),
1989 X(0x3aee8963), X(0x3afeaa82), X(0x3b0ecbc7), X(0x3b1eed32),
1990 X(0x3b2f0ec2), X(0x3b3f3075), X(0x3b4f524a), X(0x3b5f7440),
1991 X(0x3b6f9656), X(0x3b7fb889), X(0x3b8fdada), X(0x3b9ffd46),
1992 X(0x3bb01fce), X(0x3bc0426e), X(0x3bd06526), X(0x3be087f6),
1993 X(0x3bf0aada), X(0x3c00cdd4), X(0x3c10f0e0), X(0x3c2113fe),
1994 X(0x3c31372d), X(0x3c415a6b), X(0x3c517db7), X(0x3c61a110),
1995 X(0x3c71c475), X(0x3c81e7e4), X(0x3c920b5c), X(0x3ca22edc),
1996 X(0x3cb25262), X(0x3cc275ee), X(0x3cd2997e), X(0x3ce2bd11),
1997 X(0x3cf2e0a6), X(0x3d03043b), X(0x3d1327cf), X(0x3d234b61),
1998 X(0x3d336ef0), X(0x3d43927a), X(0x3d53b5ff), X(0x3d63d97c),
1999 X(0x3d73fcf1), X(0x3d84205c), X(0x3d9443bd), X(0x3da46711),
2000 X(0x3db48a58), X(0x3dc4ad91), X(0x3dd4d0ba), X(0x3de4f3d1),
2001 X(0x3df516d7), X(0x3e0539c9), X(0x3e155ca6), X(0x3e257f6d),
2002 X(0x3e35a21d), X(0x3e45c4b4), X(0x3e55e731), X(0x3e660994),
2003 X(0x3e762bda), X(0x3e864e03), X(0x3e96700d), X(0x3ea691f7),
2004 X(0x3eb6b3bf), X(0x3ec6d565), X(0x3ed6f6e8), X(0x3ee71845),
2005 X(0x3ef7397c), X(0x3f075a8c), X(0x3f177b73), X(0x3f279c30),
2006 X(0x3f37bcc2), X(0x3f47dd27), X(0x3f57fd5f), X(0x3f681d68),
2007 X(0x3f783d40), X(0x3f885ce7), X(0x3f987c5c), X(0x3fa89b9c),
2008 X(0x3fb8baa7), X(0x3fc8d97c), X(0x3fd8f819), X(0x3fe9167e),
2009 X(0x3ff934a8), X(0x40095296), X(0x40197049), X(0x40298dbd),
2010 X(0x4039aaf2), X(0x4049c7e7), X(0x4059e49a), X(0x406a010a),
2011 X(0x407a1d36), X(0x408a391d), X(0x409a54bd), X(0x40aa7015),
2012 X(0x40ba8b25), X(0x40caa5ea), X(0x40dac063), X(0x40eada90),
2013 X(0x40faf46e), X(0x410b0dfe), X(0x411b273d), X(0x412b402a),
2014 X(0x413b58c4), X(0x414b710a), X(0x415b88fa), X(0x416ba093),
2015 X(0x417bb7d5), X(0x418bcebe), X(0x419be54c), X(0x41abfb7e),
2016 X(0x41bc1153), X(0x41cc26ca), X(0x41dc3be2), X(0x41ec5099),
2017 X(0x41fc64ef), X(0x420c78e1), X(0x421c8c6f), X(0x422c9f97),
2018 X(0x423cb258), X(0x424cc4b2), X(0x425cd6a2), X(0x426ce827),
2019 X(0x427cf941), X(0x428d09ee), X(0x429d1a2c), X(0x42ad29fb),
2020 X(0x42bd3959), X(0x42cd4846), X(0x42dd56bf), X(0x42ed64c3),
2021 X(0x42fd7252), X(0x430d7f6a), X(0x431d8c0a), X(0x432d9831),
2022 X(0x433da3dd), X(0x434daf0d), X(0x435db9c0), X(0x436dc3f5),
2023 X(0x437dcdab), X(0x438dd6df), X(0x439ddf92), X(0x43ade7c1),
2024 X(0x43bdef6c), X(0x43cdf691), X(0x43ddfd2f), X(0x43ee0345),
2025 X(0x43fe08d2), X(0x440e0dd4), X(0x441e124b), X(0x442e1634),
2026 X(0x443e198f), X(0x444e1c5a), X(0x445e1e95), X(0x446e203e),
2027 X(0x447e2153), X(0x448e21d5), X(0x449e21c0), X(0x44ae2115),
2028 X(0x44be1fd1), X(0x44ce1df4), X(0x44de1b7d), X(0x44ee186a),
2029 X(0x44fe14ba), X(0x450e106b), X(0x451e0b7e), X(0x452e05ef),
2030 X(0x453dffbf), X(0x454df8eb), X(0x455df173), X(0x456de956),
2031 X(0x457de092), X(0x458dd726), X(0x459dcd10), X(0x45adc251),
2032 X(0x45bdb6e5), X(0x45cdaacd), X(0x45dd9e06), X(0x45ed9091),
2033 X(0x45fd826a), X(0x460d7392), X(0x461d6407), X(0x462d53c8),
2034 X(0x463d42d4), X(0x464d3129), X(0x465d1ec6), X(0x466d0baa),
2035 X(0x467cf7d3), X(0x468ce342), X(0x469ccdf3), X(0x46acb7e7),
2036 X(0x46bca11c), X(0x46cc8990), X(0x46dc7143), X(0x46ec5833),
2037 X(0x46fc3e5f), X(0x470c23c6), X(0x471c0867), X(0x472bec40),
2038 X(0x473bcf50), X(0x474bb196), X(0x475b9311), X(0x476b73c0),
2039 X(0x477b53a1), X(0x478b32b4), X(0x479b10f6), X(0x47aaee67),
2040 X(0x47bacb06), X(0x47caa6d1), X(0x47da81c7), X(0x47ea5be7),
2041 X(0x47fa3530), X(0x480a0da1), X(0x4819e537), X(0x4829bbf3),
2042 X(0x483991d3), X(0x484966d6), X(0x48593afb), X(0x48690e3f),
2043 X(0x4878e0a3), X(0x4888b225), X(0x489882c4), X(0x48a8527e),
2044 X(0x48b82153), X(0x48c7ef41), X(0x48d7bc47), X(0x48e78863),
2045 X(0x48f75396), X(0x49071ddc), X(0x4916e736), X(0x4926afa2),
2046 X(0x4936771f), X(0x49463dac), X(0x49560347), X(0x4965c7ef),
2047 X(0x49758ba4), X(0x49854e63), X(0x4995102c), X(0x49a4d0fe),
2048 X(0x49b490d7), X(0x49c44fb6), X(0x49d40d9a), X(0x49e3ca82),
2049 X(0x49f3866c), X(0x4a034159), X(0x4a12fb45), X(0x4a22b430),
2050 X(0x4a326c19), X(0x4a4222ff), X(0x4a51d8e1), X(0x4a618dbd),
2051 X(0x4a714192), X(0x4a80f45f), X(0x4a90a623), X(0x4aa056dd),
2052 X(0x4ab0068b), X(0x4abfb52c), X(0x4acf62c0), X(0x4adf0f44),
2053 X(0x4aeebab9), X(0x4afe651c), X(0x4b0e0e6c), X(0x4b1db6a9),
2054 X(0x4b2d5dd1), X(0x4b3d03e2), X(0x4b4ca8dd), X(0x4b5c4cbf),
2055 X(0x4b6bef88), X(0x4b7b9136), X(0x4b8b31c8), X(0x4b9ad13d),
2056 X(0x4baa6f93), X(0x4bba0ccb), X(0x4bc9a8e2), X(0x4bd943d7),
2057 X(0x4be8dda9), X(0x4bf87658), X(0x4c080de1), X(0x4c17a444),
2058 X(0x4c27397f), X(0x4c36cd92), X(0x4c46607b), X(0x4c55f239),
2059 X(0x4c6582cb), X(0x4c75122f), X(0x4c84a065), X(0x4c942d6c),
2060 X(0x4ca3b942), X(0x4cb343e6), X(0x4cc2cd57), X(0x4cd25594),
2061 X(0x4ce1dc9c), X(0x4cf1626d), X(0x4d00e707), X(0x4d106a68),
2062 X(0x4d1fec8f), X(0x4d2f6d7a), X(0x4d3eed2a), X(0x4d4e6b9d),
2063 X(0x4d5de8d1), X(0x4d6d64c5), X(0x4d7cdf79), X(0x4d8c58eb),
2064 X(0x4d9bd11a), X(0x4dab4804), X(0x4dbabdaa), X(0x4dca3209),
2065 X(0x4dd9a520), X(0x4de916ef), X(0x4df88774), X(0x4e07f6ae),
2066 X(0x4e17649c), X(0x4e26d13c), X(0x4e363c8f), X(0x4e45a692),
2067 X(0x4e550f44), X(0x4e6476a4), X(0x4e73dcb2), X(0x4e83416c),
2068 X(0x4e92a4d1), X(0x4ea206df), X(0x4eb16796), X(0x4ec0c6f5),
2069 X(0x4ed024fa), X(0x4edf81a5), X(0x4eeedcf3), X(0x4efe36e5),
2070 X(0x4f0d8f79), X(0x4f1ce6ad), X(0x4f2c3c82), X(0x4f3b90f4),
2071 X(0x4f4ae405), X(0x4f5a35b1), X(0x4f6985fa), X(0x4f78d4dc),
2072 X(0x4f882257), X(0x4f976e6a), X(0x4fa6b914), X(0x4fb60254),
2073 X(0x4fc54a28), X(0x4fd49090), X(0x4fe3d58b), X(0x4ff31917),
2074 X(0x50025b33), X(0x50119bde), X(0x5020db17), X(0x503018dd),
2075 X(0x503f552f), X(0x504e900b), X(0x505dc971), X(0x506d0160),
2076 X(0x507c37d7), X(0x508b6cd3), X(0x509aa055), X(0x50a9d25b),
2077 X(0x50b902e4), X(0x50c831ef), X(0x50d75f7b), X(0x50e68b87),
2078 X(0x50f5b612), X(0x5104df1a), X(0x5114069f), X(0x51232ca0),
2079 X(0x5132511a), X(0x5141740f), X(0x5150957b), X(0x515fb55f),
2080 X(0x516ed3b8), X(0x517df087), X(0x518d0bca), X(0x519c257f),
2081 X(0x51ab3da7), X(0x51ba543f), X(0x51c96947), X(0x51d87cbd),
2082 X(0x51e78ea1), X(0x51f69ef1), X(0x5205adad), X(0x5214bad3),
2083 X(0x5223c662), X(0x5232d05a), X(0x5241d8b9), X(0x5250df7d),
2084 X(0x525fe4a7), X(0x526ee835), X(0x527dea26), X(0x528cea78),
2085 X(0x529be92c), X(0x52aae63f), X(0x52b9e1b0), X(0x52c8db80),
2086 X(0x52d7d3ac), X(0x52e6ca33), X(0x52f5bf15), X(0x5304b251),
2087 X(0x5313a3e5), X(0x532293d0), X(0x53318212), X(0x53406ea8),
2088 X(0x534f5993), X(0x535e42d2), X(0x536d2a62), X(0x537c1043),
2089 X(0x538af475), X(0x5399d6f6), X(0x53a8b7c4), X(0x53b796e0),
2090 X(0x53c67447), X(0x53d54ffa), X(0x53e429f6), X(0x53f3023b),
2091 X(0x5401d8c8), X(0x5410ad9c), X(0x541f80b5), X(0x542e5213),
2092 X(0x543d21b5), X(0x544bef9a), X(0x545abbc0), X(0x54698627),
2093 X(0x54784ece), X(0x548715b3), X(0x5495dad6), X(0x54a49e35),
2094 X(0x54b35fd0), X(0x54c21fa6), X(0x54d0ddb5), X(0x54df99fd),
2095 X(0x54ee547c), X(0x54fd0d32), X(0x550bc41d), X(0x551a793d),
2096 X(0x55292c91), X(0x5537de16), X(0x55468dce), X(0x55553bb6),
2097 X(0x5563e7cd), X(0x55729213), X(0x55813a87), X(0x558fe127),
2098 X(0x559e85f2), X(0x55ad28e9), X(0x55bbca08), X(0x55ca6950),
2099 X(0x55d906c0), X(0x55e7a257), X(0x55f63c13), X(0x5604d3f4),
2100 X(0x561369f8), X(0x5621fe1f), X(0x56309067), X(0x563f20d1),
2101 X(0x564daf5a), X(0x565c3c02), X(0x566ac6c7), X(0x56794faa),
2102 X(0x5687d6a8), X(0x56965bc1), X(0x56a4def4), X(0x56b36040),
2103 X(0x56c1dfa4), X(0x56d05d1f), X(0x56ded8af), X(0x56ed5255),
2104 X(0x56fbca0f), X(0x570a3fdc), X(0x5718b3bc), X(0x572725ac),
2105 X(0x573595ad), X(0x574403bd), X(0x57526fdb), X(0x5760da07),
2106 X(0x576f423f), X(0x577da883), X(0x578c0cd1), X(0x579a6f29),
2107 X(0x57a8cf8a), X(0x57b72df2), X(0x57c58a61), X(0x57d3e4d6),
2108 X(0x57e23d50), X(0x57f093cd), X(0x57fee84e), X(0x580d3ad1),
2109 X(0x581b8b54), X(0x5829d9d8), X(0x5838265c), X(0x584670dd),
2110 X(0x5854b95c), X(0x5862ffd8), X(0x5871444f), X(0x587f86c1),
2111 X(0x588dc72c), X(0x589c0591), X(0x58aa41ed), X(0x58b87c40),
2112 X(0x58c6b489), X(0x58d4eac7), X(0x58e31ef9), X(0x58f1511f),
2113 X(0x58ff8137), X(0x590daf40), X(0x591bdb3a), X(0x592a0524),
2114 X(0x59382cfc), X(0x594652c2), X(0x59547675), X(0x59629815),
2115 X(0x5970b79f), X(0x597ed513), X(0x598cf071), X(0x599b09b7),
2116 X(0x59a920e5), X(0x59b735f9), X(0x59c548f4), X(0x59d359d2),
2117 X(0x59e16895), X(0x59ef753b), X(0x59fd7fc4), X(0x5a0b882d),
2118 X(0x5a198e77), X(0x5a2792a0), X(0x5a3594a9), X(0x5a43948e),
2119 X(0x5a519251), X(0x5a5f8df0), X(0x5a6d876a), X(0x5a7b7ebe),
2120 X(0x5a8973ec), X(0x5a9766f2), X(0x5aa557d0), X(0x5ab34685),
2121 X(0x5ac1330f), X(0x5acf1d6f), X(0x5add05a3), X(0x5aeaebaa),
2122 X(0x5af8cf84), X(0x5b06b12f), X(0x5b1490ab), X(0x5b226df7),
2123 X(0x5b304912), X(0x5b3e21fc), X(0x5b4bf8b2), X(0x5b59cd35),
2124 X(0x5b679f84), X(0x5b756f9e), X(0x5b833d82), X(0x5b91092e),
2125 X(0x5b9ed2a3), X(0x5bac99e0), X(0x5bba5ee3), X(0x5bc821ac),
2126 X(0x5bd5e23a), X(0x5be3a08c), X(0x5bf15ca1), X(0x5bff1679),
2127 X(0x5c0cce12), X(0x5c1a836c), X(0x5c283686), X(0x5c35e760),
2128 X(0x5c4395f7), X(0x5c51424c), X(0x5c5eec5e), X(0x5c6c942b),
2129 X(0x5c7a39b4), X(0x5c87dcf7), X(0x5c957df3), X(0x5ca31ca8),
2130 X(0x5cb0b915), X(0x5cbe5338), X(0x5ccbeb12), X(0x5cd980a1),
2131 X(0x5ce713e5), X(0x5cf4a4dd), X(0x5d023387), X(0x5d0fbfe4),
2132 X(0x5d1d49f2), X(0x5d2ad1b1), X(0x5d38571f), X(0x5d45da3c),
2133 X(0x5d535b08), X(0x5d60d981), X(0x5d6e55a7), X(0x5d7bcf78),
2134 X(0x5d8946f5), X(0x5d96bc1c), X(0x5da42eec), X(0x5db19f65),
2135 X(0x5dbf0d86), X(0x5dcc794e), X(0x5dd9e2bd), X(0x5de749d1),
2136 X(0x5df4ae8a), X(0x5e0210e7), X(0x5e0f70e7), X(0x5e1cce8a),
2137 X(0x5e2a29ce), X(0x5e3782b4), X(0x5e44d93a), X(0x5e522d5f),
2138 X(0x5e5f7f23), X(0x5e6cce85), X(0x5e7a1b85), X(0x5e876620),
2139 X(0x5e94ae58), X(0x5ea1f42a), X(0x5eaf3797), X(0x5ebc789d),
2140 X(0x5ec9b73c), X(0x5ed6f372), X(0x5ee42d41), X(0x5ef164a5),
2141 X(0x5efe999f), X(0x5f0bcc2f), X(0x5f18fc52), X(0x5f262a09),
2142 X(0x5f335553), X(0x5f407e2f), X(0x5f4da49d), X(0x5f5ac89b),
2143 X(0x5f67ea29), X(0x5f750946), X(0x5f8225f2), X(0x5f8f402b),
2144 X(0x5f9c57f2), X(0x5fa96d44), X(0x5fb68023), X(0x5fc3908c),
2145 X(0x5fd09e7f), X(0x5fdda9fc), X(0x5feab302), X(0x5ff7b990),
2146 X(0x6004bda5), X(0x6011bf40), X(0x601ebe62), X(0x602bbb09),
2147 X(0x6038b534), X(0x6045ace4), X(0x6052a216), X(0x605f94cb),
2148 X(0x606c8502), X(0x607972b9), X(0x60865df2), X(0x609346aa),
2149 X(0x60a02ce1), X(0x60ad1096), X(0x60b9f1c9), X(0x60c6d079),
2150 X(0x60d3aca5), X(0x60e0864d), X(0x60ed5d70), X(0x60fa320d),
2151 X(0x61070424), X(0x6113d3b4), X(0x6120a0bc), X(0x612d6b3c),
2152 X(0x613a3332), X(0x6146f89f), X(0x6153bb82), X(0x61607bd9),
2153 X(0x616d39a5), X(0x6179f4e5), X(0x6186ad98), X(0x619363bd),
2154 X(0x61a01753), X(0x61acc85b), X(0x61b976d3), X(0x61c622bc),
2155 X(0x61d2cc13), X(0x61df72d8), X(0x61ec170c), X(0x61f8b8ad),
2156 X(0x620557ba), X(0x6211f434), X(0x621e8e18), X(0x622b2568),
2157 X(0x6237ba21), X(0x62444c44), X(0x6250dbd0), X(0x625d68c4),
2158 X(0x6269f320), X(0x62767ae2), X(0x6283000b), X(0x628f829a),
2159 X(0x629c028e), X(0x62a87fe6), X(0x62b4faa2), X(0x62c172c2),
2160 X(0x62cde844), X(0x62da5b29), X(0x62e6cb6e), X(0x62f33915),
2161 X(0x62ffa41c), X(0x630c0c83), X(0x63187248), X(0x6324d56d),
2162 X(0x633135ef), X(0x633d93ce), X(0x6349ef0b), X(0x635647a3),
2163 X(0x63629d97), X(0x636ef0e6), X(0x637b418f), X(0x63878f92),
2164 X(0x6393daef), X(0x63a023a4), X(0x63ac69b1), X(0x63b8ad15),
2165 X(0x63c4edd1), X(0x63d12be3), X(0x63dd674b), X(0x63e9a008),
2166 X(0x63f5d61a), X(0x64020980), X(0x640e3a39), X(0x641a6846),
2167 X(0x642693a5), X(0x6432bc56), X(0x643ee258), X(0x644b05ab),
2168 X(0x6457264e), X(0x64634441), X(0x646f5f83), X(0x647b7814),
2169 X(0x64878df3), X(0x6493a120), X(0x649fb199), X(0x64abbf5f),
2170 X(0x64b7ca71), X(0x64c3d2ce), X(0x64cfd877), X(0x64dbdb69),
2171 X(0x64e7dba6), X(0x64f3d92b), X(0x64ffd3fa), X(0x650bcc11),
2172 X(0x6517c16f), X(0x6523b415), X(0x652fa402), X(0x653b9134),
2173 X(0x65477bad), X(0x6553636a), X(0x655f486d), X(0x656b2ab3),
2174 X(0x65770a3d), X(0x6582e70a), X(0x658ec11a), X(0x659a986d),
2175 X(0x65a66d00), X(0x65b23ed5), X(0x65be0deb), X(0x65c9da41),
2176 X(0x65d5a3d7), X(0x65e16aac), X(0x65ed2ebf), X(0x65f8f011),
2177 X(0x6604aea1), X(0x66106a6e), X(0x661c2377), X(0x6627d9be),
2178 X(0x66338d40), X(0x663f3dfd), X(0x664aebf5), X(0x66569728),
2179 X(0x66623f95), X(0x666de53b), X(0x6679881b), X(0x66852833),
2180 X(0x6690c583), X(0x669c600b), X(0x66a7f7ca), X(0x66b38cc0),
2181 X(0x66bf1eec), X(0x66caae4f), X(0x66d63ae6), X(0x66e1c4b3),
2182 X(0x66ed4bb4), X(0x66f8cfea), X(0x67045153), X(0x670fcfef),
2183 X(0x671b4bbe), X(0x6726c4bf), X(0x67323af3), X(0x673dae58),
2184 X(0x67491eee), X(0x67548cb5), X(0x675ff7ab), X(0x676b5fd2),
2185 X(0x6776c528), X(0x678227ad), X(0x678d8761), X(0x6798e443),
2186 X(0x67a43e52), X(0x67af958f), X(0x67bae9f9), X(0x67c63b8f),
2187 X(0x67d18a52), X(0x67dcd640), X(0x67e81f59), X(0x67f3659d),
2188 X(0x67fea90c), X(0x6809e9a5), X(0x68152768), X(0x68206254),
2189 X(0x682b9a68), X(0x6836cfa6), X(0x6842020b), X(0x684d3199),
2190 X(0x68585e4d), X(0x68638829), X(0x686eaf2b), X(0x6879d354),
2191 X(0x6884f4a2), X(0x68901316), X(0x689b2eb0), X(0x68a6476d),
2192 X(0x68b15d50), X(0x68bc7056), X(0x68c78080), X(0x68d28dcd),
2193 X(0x68dd983e), X(0x68e89fd0), X(0x68f3a486), X(0x68fea65d),
2194 X(0x6909a555), X(0x6914a16f), X(0x691f9aa9), X(0x692a9104),
2195 X(0x69358480), X(0x6940751b), X(0x694b62d5), X(0x69564daf),
2196 X(0x696135a7), X(0x696c1abe), X(0x6976fcf3), X(0x6981dc46),
2197 X(0x698cb8b6), X(0x69979243), X(0x69a268ed), X(0x69ad3cb4),
2198 X(0x69b80d97), X(0x69c2db96), X(0x69cda6b0), X(0x69d86ee5),
2199 X(0x69e33436), X(0x69edf6a1), X(0x69f8b626), X(0x6a0372c5),
2200 X(0x6a0e2c7e), X(0x6a18e350), X(0x6a23973c), X(0x6a2e4840),
2201 X(0x6a38f65d), X(0x6a43a191), X(0x6a4e49de), X(0x6a58ef42),
2202 X(0x6a6391be), X(0x6a6e3151), X(0x6a78cdfa), X(0x6a8367ba),
2203 X(0x6a8dfe90), X(0x6a98927c), X(0x6aa3237d), X(0x6aadb194),
2204 X(0x6ab83cc0), X(0x6ac2c500), X(0x6acd4a55), X(0x6ad7ccbf),
2205 X(0x6ae24c3c), X(0x6aecc8cd), X(0x6af74271), X(0x6b01b929),
2206 X(0x6b0c2cf4), X(0x6b169dd1), X(0x6b210bc1), X(0x6b2b76c2),
2207 X(0x6b35ded6), X(0x6b4043fc), X(0x6b4aa632), X(0x6b55057a),
2208 X(0x6b5f61d3), X(0x6b69bb3d), X(0x6b7411b7), X(0x6b7e6541),
2209 X(0x6b88b5db), X(0x6b930385), X(0x6b9d4e3f), X(0x6ba79607),
2210 X(0x6bb1dadf), X(0x6bbc1cc6), X(0x6bc65bbb), X(0x6bd097bf),
2211 X(0x6bdad0d0), X(0x6be506f0), X(0x6bef3a1d), X(0x6bf96a58),
2212 X(0x6c0397a0), X(0x6c0dc1f5), X(0x6c17e957), X(0x6c220dc6),
2213 X(0x6c2c2f41), X(0x6c364dc9), X(0x6c40695c), X(0x6c4a81fc),
2214 X(0x6c5497a7), X(0x6c5eaa5d), X(0x6c68ba1f), X(0x6c72c6eb),
2215 X(0x6c7cd0c3), X(0x6c86d7a6), X(0x6c90db92), X(0x6c9adc8a),
2216 X(0x6ca4da8b), X(0x6caed596), X(0x6cb8cdab), X(0x6cc2c2ca),
2217 X(0x6cccb4f2), X(0x6cd6a424), X(0x6ce0905e), X(0x6cea79a1),
2218 X(0x6cf45fee), X(0x6cfe4342), X(0x6d0823a0), X(0x6d120105),
2219 X(0x6d1bdb73), X(0x6d25b2e8), X(0x6d2f8765), X(0x6d3958ea),
2220 X(0x6d432777), X(0x6d4cf30a), X(0x6d56bba5), X(0x6d608147),
2221 X(0x6d6a43f0), X(0x6d7403a0), X(0x6d7dc056), X(0x6d877a13),
2222 X(0x6d9130d6), X(0x6d9ae4a0), X(0x6da4956f), X(0x6dae4345),
2223 X(0x6db7ee20), X(0x6dc19601), X(0x6dcb3ae7), X(0x6dd4dcd3),
2224 X(0x6dde7bc4), X(0x6de817bb), X(0x6df1b0b6), X(0x6dfb46b7),
2225 X(0x6e04d9bc), X(0x6e0e69c7), X(0x6e17f6d5), X(0x6e2180e9),
2226 X(0x6e2b0801), X(0x6e348c1d), X(0x6e3e0d3d), X(0x6e478b62),
2227 X(0x6e51068a), X(0x6e5a7eb7), X(0x6e63f3e7), X(0x6e6d661b),
2228 X(0x6e76d552), X(0x6e80418e), X(0x6e89aacc), X(0x6e93110f),
2229 X(0x6e9c7454), X(0x6ea5d49d), X(0x6eaf31e9), X(0x6eb88c37),
2230 X(0x6ec1e389), X(0x6ecb37de), X(0x6ed48936), X(0x6eddd790),
2231 X(0x6ee722ee), X(0x6ef06b4d), X(0x6ef9b0b0), X(0x6f02f315),
2232 X(0x6f0c327c), X(0x6f156ee6), X(0x6f1ea852), X(0x6f27dec1),
2233 X(0x6f311232), X(0x6f3a42a5), X(0x6f43701a), X(0x6f4c9a91),
2234 X(0x6f55c20a), X(0x6f5ee686), X(0x6f680803), X(0x6f712682),
2235 X(0x6f7a4203), X(0x6f835a86), X(0x6f8c700b), X(0x6f958291),
2236 X(0x6f9e921a), X(0x6fa79ea4), X(0x6fb0a830), X(0x6fb9aebd),
2237 X(0x6fc2b24c), X(0x6fcbb2dd), X(0x6fd4b06f), X(0x6fddab03),
2238 X(0x6fe6a299), X(0x6fef9730), X(0x6ff888c9), X(0x70017763),
2239 X(0x700a62ff), X(0x70134b9c), X(0x701c313b), X(0x702513dc),
2240 X(0x702df37e), X(0x7036d021), X(0x703fa9c6), X(0x7048806d),
2241 X(0x70515415), X(0x705a24bf), X(0x7062f26b), X(0x706bbd17),
2242 X(0x707484c6), X(0x707d4976), X(0x70860b28), X(0x708ec9dc),
2243 X(0x70978591), X(0x70a03e48), X(0x70a8f400), X(0x70b1a6bb),
2244 X(0x70ba5677), X(0x70c30335), X(0x70cbacf5), X(0x70d453b6),
2245 X(0x70dcf77a), X(0x70e59840), X(0x70ee3607), X(0x70f6d0d1),
2246 X(0x70ff689d), X(0x7107fd6b), X(0x71108f3b), X(0x71191e0d),
2247 X(0x7121a9e2), X(0x712a32b9), X(0x7132b892), X(0x713b3b6e),
2248 X(0x7143bb4c), X(0x714c382d), X(0x7154b211), X(0x715d28f7),
2249 X(0x71659ce0), X(0x716e0dcc), X(0x71767bbb), X(0x717ee6ac),
2250 X(0x71874ea1), X(0x718fb399), X(0x71981594), X(0x71a07493),
2251 X(0x71a8d094), X(0x71b1299a), X(0x71b97fa2), X(0x71c1d2af),
2252 X(0x71ca22bf), X(0x71d26fd2), X(0x71dab9ea), X(0x71e30106),
2253 X(0x71eb4526), X(0x71f3864a), X(0x71fbc472), X(0x7203ff9e),
2254 X(0x720c37cf), X(0x72146d05), X(0x721c9f3f), X(0x7224ce7e),
2255 X(0x722cfac2), X(0x7235240b), X(0x723d4a59), X(0x72456dad),
2256 X(0x724d8e05), X(0x7255ab63), X(0x725dc5c7), X(0x7265dd31),
2257 X(0x726df1a0), X(0x72760315), X(0x727e1191), X(0x72861d12),
2258 X(0x728e259a), X(0x72962b28), X(0x729e2dbd), X(0x72a62d59),
2259 X(0x72ae29fc), X(0x72b623a5), X(0x72be1a56), X(0x72c60e0e),
2260 X(0x72cdfece), X(0x72d5ec95), X(0x72ddd764), X(0x72e5bf3b),
2261 X(0x72eda41a), X(0x72f58601), X(0x72fd64f1), X(0x730540e9),
2262 X(0x730d19e9), X(0x7314eff3), X(0x731cc305), X(0x73249321),
2263 X(0x732c6046), X(0x73342a75), X(0x733bf1ad), X(0x7343b5ef),
2264 X(0x734b773b), X(0x73533591), X(0x735af0f2), X(0x7362a95d),
2265 X(0x736a5ed3), X(0x73721153), X(0x7379c0df), X(0x73816d76),
2266 X(0x73891719), X(0x7390bdc7), X(0x73986181), X(0x73a00247),
2267 X(0x73a7a01a), X(0x73af3af8), X(0x73b6d2e4), X(0x73be67dc),
2268 X(0x73c5f9e1), X(0x73cd88f3), X(0x73d51513), X(0x73dc9e40),
2269 X(0x73e4247c), X(0x73eba7c5), X(0x73f3281c), X(0x73faa582),
2270 X(0x74021ff7), X(0x7409977b), X(0x74110c0d), X(0x74187daf),
2271 X(0x741fec61), X(0x74275822), X(0x742ec0f3), X(0x743626d5),
2272 X(0x743d89c7), X(0x7444e9c9), X(0x744c46dd), X(0x7453a101),
2273 X(0x745af837), X(0x74624c7f), X(0x74699dd8), X(0x7470ec44),
2274 X(0x747837c2), X(0x747f8052), X(0x7486c5f5), X(0x748e08ac),
2275 X(0x74954875), X(0x749c8552), X(0x74a3bf43), X(0x74aaf648),
2276 X(0x74b22a62), X(0x74b95b90), X(0x74c089d2), X(0x74c7b52a),
2277 X(0x74cedd97), X(0x74d6031a), X(0x74dd25b2), X(0x74e44561),
2278 X(0x74eb6226), X(0x74f27c02), X(0x74f992f5), X(0x7500a6ff),
2279 X(0x7507b820), X(0x750ec659), X(0x7515d1aa), X(0x751cda14),
2280 X(0x7523df96), X(0x752ae231), X(0x7531e1e5), X(0x7538deb2),
2281 X(0x753fd89a), X(0x7546cf9b), X(0x754dc3b7), X(0x7554b4ed),
2282 X(0x755ba33e), X(0x75628eaa), X(0x75697732), X(0x75705cd5),
2283 X(0x75773f95), X(0x757e1f71), X(0x7584fc6a), X(0x758bd67f),
2284 X(0x7592adb2), X(0x75998203), X(0x75a05371), X(0x75a721fe),
2285 X(0x75adeda9), X(0x75b4b673), X(0x75bb7c5c), X(0x75c23f65),
2286 X(0x75c8ff8d), X(0x75cfbcd6), X(0x75d6773f), X(0x75dd2ec8),
2287 X(0x75e3e373), X(0x75ea953f), X(0x75f1442d), X(0x75f7f03d),
2288 X(0x75fe996f), X(0x76053fc5), X(0x760be33d), X(0x761283d8),
2289 X(0x76192197), X(0x761fbc7b), X(0x76265482), X(0x762ce9af),
2290 X(0x76337c01), X(0x763a0b78), X(0x76409814), X(0x764721d7),
2291 X(0x764da8c1), X(0x76542cd1), X(0x765aae08), X(0x76612c67),
2292 X(0x7667a7ee), X(0x766e209d), X(0x76749675), X(0x767b0975),
2293 X(0x7681799f), X(0x7687e6f3), X(0x768e5170), X(0x7694b918),
2294 X(0x769b1deb), X(0x76a17fe9), X(0x76a7df13), X(0x76ae3b68),
2295 X(0x76b494ea), X(0x76baeb98), X(0x76c13f74), X(0x76c7907c),
2296 X(0x76cddeb3), X(0x76d42a18), X(0x76da72ab), X(0x76e0b86d),
2297 X(0x76e6fb5e), X(0x76ed3b7f), X(0x76f378d0), X(0x76f9b352),
2298 X(0x76ffeb05), X(0x77061fe8), X(0x770c51fe), X(0x77128145),
2299 X(0x7718adbf), X(0x771ed76c), X(0x7724fe4c), X(0x772b225f),
2300 X(0x773143a7), X(0x77376223), X(0x773d7dd3), X(0x774396ba),
2301 X(0x7749acd5), X(0x774fc027), X(0x7755d0af), X(0x775bde6f),
2302 X(0x7761e965), X(0x7767f193), X(0x776df6fa), X(0x7773f998),
2303 X(0x7779f970), X(0x777ff681), X(0x7785f0cd), X(0x778be852),
2304 X(0x7791dd12), X(0x7797cf0d), X(0x779dbe43), X(0x77a3aab6),
2305 X(0x77a99465), X(0x77af7b50), X(0x77b55f79), X(0x77bb40e0),
2306 X(0x77c11f85), X(0x77c6fb68), X(0x77ccd48a), X(0x77d2aaec),
2307 X(0x77d87e8d), X(0x77de4f6f), X(0x77e41d92), X(0x77e9e8f5),
2308 X(0x77efb19b), X(0x77f57782), X(0x77fb3aad), X(0x7800fb1a),
2309 X(0x7806b8ca), X(0x780c73bf), X(0x78122bf7), X(0x7817e175),
2310 X(0x781d9438), X(0x78234440), X(0x7828f18f), X(0x782e9c25),
2311 X(0x78344401), X(0x7839e925), X(0x783f8b92), X(0x78452b46),
2312 X(0x784ac844), X(0x7850628b), X(0x7855fa1c), X(0x785b8ef8),
2313 X(0x7861211e), X(0x7866b090), X(0x786c3d4d), X(0x7871c757),
2314 X(0x78774ead), X(0x787cd351), X(0x78825543), X(0x7887d483),
2315 X(0x788d5111), X(0x7892caef), X(0x7898421c), X(0x789db69a),
2316 X(0x78a32868), X(0x78a89787), X(0x78ae03f8), X(0x78b36dbb),
2317 X(0x78b8d4d1), X(0x78be393a), X(0x78c39af6), X(0x78c8fa06),
2318 X(0x78ce566c), X(0x78d3b026), X(0x78d90736), X(0x78de5b9c),
2319 X(0x78e3ad58), X(0x78e8fc6c), X(0x78ee48d7), X(0x78f3929b),
2320 X(0x78f8d9b7), X(0x78fe1e2c), X(0x79035ffb), X(0x79089f24),
2321 X(0x790ddba8), X(0x79131587), X(0x79184cc2), X(0x791d8159),
2322 X(0x7922b34d), X(0x7927e29e), X(0x792d0f4d), X(0x7932395a),
2323 X(0x793760c6), X(0x793c8591), X(0x7941a7bd), X(0x7946c749),
2324 X(0x794be435), X(0x7950fe84), X(0x79561634), X(0x795b2b47),
2325 X(0x79603dbc), X(0x79654d96), X(0x796a5ad4), X(0x796f6576),
2326 X(0x79746d7e), X(0x797972eb), X(0x797e75bf), X(0x798375f9),
2327 X(0x7988739b), X(0x798d6ea5), X(0x79926717), X(0x79975cf2),
2328 X(0x799c5037), X(0x79a140e6), X(0x79a62f00), X(0x79ab1a85),
2329 X(0x79b00376), X(0x79b4e9d3), X(0x79b9cd9d), X(0x79beaed4),
2330 X(0x79c38d79), X(0x79c8698d), X(0x79cd4310), X(0x79d21a03),
2331 X(0x79d6ee66), X(0x79dbc03a), X(0x79e08f7f), X(0x79e55c36),
2332 X(0x79ea265f), X(0x79eeedfc), X(0x79f3b30c), X(0x79f87590),
2333 X(0x79fd3589), X(0x7a01f2f7), X(0x7a06addc), X(0x7a0b6636),
2334 X(0x7a101c08), X(0x7a14cf52), X(0x7a198013), X(0x7a1e2e4d),
2335 X(0x7a22da01), X(0x7a27832f), X(0x7a2c29d7), X(0x7a30cdfa),
2336 X(0x7a356f99), X(0x7a3a0eb4), X(0x7a3eab4c), X(0x7a434561),
2337 X(0x7a47dcf5), X(0x7a4c7207), X(0x7a510498), X(0x7a5594a9),
2338 X(0x7a5a223a), X(0x7a5ead4d), X(0x7a6335e0), X(0x7a67bbf6),
2339 X(0x7a6c3f8f), X(0x7a70c0ab), X(0x7a753f4b), X(0x7a79bb6f),
2340 X(0x7a7e3519), X(0x7a82ac48), X(0x7a8720fe), X(0x7a8b933b),
2341 X(0x7a9002ff), X(0x7a94704b), X(0x7a98db20), X(0x7a9d437e),
2342 X(0x7aa1a967), X(0x7aa60cd9), X(0x7aaa6dd7), X(0x7aaecc61),
2343 X(0x7ab32877), X(0x7ab7821b), X(0x7abbd94b), X(0x7ac02e0a),
2344 X(0x7ac48058), X(0x7ac8d035), X(0x7acd1da3), X(0x7ad168a1),
2345 X(0x7ad5b130), X(0x7ad9f751), X(0x7ade3b05), X(0x7ae27c4c),
2346 X(0x7ae6bb27), X(0x7aeaf796), X(0x7aef319a), X(0x7af36934),
2347 X(0x7af79e64), X(0x7afbd12c), X(0x7b00018a), X(0x7b042f81),
2348 X(0x7b085b10), X(0x7b0c8439), X(0x7b10aafc), X(0x7b14cf5a),
2349 X(0x7b18f153), X(0x7b1d10e8), X(0x7b212e1a), X(0x7b2548e9),
2350 X(0x7b296155), X(0x7b2d7761), X(0x7b318b0b), X(0x7b359c55),
2351 X(0x7b39ab3f), X(0x7b3db7cb), X(0x7b41c1f8), X(0x7b45c9c8),
2352 X(0x7b49cf3b), X(0x7b4dd251), X(0x7b51d30b), X(0x7b55d16b),
2353 X(0x7b59cd70), X(0x7b5dc71b), X(0x7b61be6d), X(0x7b65b366),
2354 X(0x7b69a608), X(0x7b6d9653), X(0x7b718447), X(0x7b756fe5),
2355 X(0x7b79592e), X(0x7b7d4022), X(0x7b8124c3), X(0x7b850710),
2356 X(0x7b88e70a), X(0x7b8cc4b3), X(0x7b90a00a), X(0x7b947911),
2357 X(0x7b984fc8), X(0x7b9c242f), X(0x7b9ff648), X(0x7ba3c612),
2358 X(0x7ba79390), X(0x7bab5ec1), X(0x7baf27a5), X(0x7bb2ee3f),
2359 X(0x7bb6b28e), X(0x7bba7493), X(0x7bbe344e), X(0x7bc1f1c1),
2360 X(0x7bc5acec), X(0x7bc965cf), X(0x7bcd1c6c), X(0x7bd0d0c3),
2361 X(0x7bd482d4), X(0x7bd832a1), X(0x7bdbe02a), X(0x7bdf8b70),
2362 X(0x7be33473), X(0x7be6db34), X(0x7bea7fb4), X(0x7bee21f4),
2363 X(0x7bf1c1f3), X(0x7bf55fb3), X(0x7bf8fb35), X(0x7bfc9479),
2364 X(0x7c002b7f), X(0x7c03c04a), X(0x7c0752d8), X(0x7c0ae32b),
2365 X(0x7c0e7144), X(0x7c11fd23), X(0x7c1586c9), X(0x7c190e36),
2366 X(0x7c1c936c), X(0x7c20166b), X(0x7c239733), X(0x7c2715c6),
2367 X(0x7c2a9224), X(0x7c2e0c4e), X(0x7c318444), X(0x7c34fa07),
2368 X(0x7c386d98), X(0x7c3bdef8), X(0x7c3f4e26), X(0x7c42bb25),
2369 X(0x7c4625f4), X(0x7c498e95), X(0x7c4cf507), X(0x7c50594c),
2370 X(0x7c53bb65), X(0x7c571b51), X(0x7c5a7913), X(0x7c5dd4aa),
2371 X(0x7c612e17), X(0x7c64855b), X(0x7c67da76), X(0x7c6b2d6a),
2372 X(0x7c6e7e37), X(0x7c71ccdd), X(0x7c75195e), X(0x7c7863ba),
2373 X(0x7c7babf1), X(0x7c7ef206), X(0x7c8235f7), X(0x7c8577c6),
2374 X(0x7c88b774), X(0x7c8bf502), X(0x7c8f306f), X(0x7c9269bd),
2375 X(0x7c95a0ec), X(0x7c98d5fe), X(0x7c9c08f2), X(0x7c9f39cb),
2376 X(0x7ca26887), X(0x7ca59528), X(0x7ca8bfb0), X(0x7cabe81d),
2377 X(0x7caf0e72), X(0x7cb232af), X(0x7cb554d4), X(0x7cb874e2),
2378 X(0x7cbb92db), X(0x7cbeaebe), X(0x7cc1c88d), X(0x7cc4e047),
2379 X(0x7cc7f5ef), X(0x7ccb0984), X(0x7cce1b08), X(0x7cd12a7b),
2380 X(0x7cd437dd), X(0x7cd74330), X(0x7cda4c74), X(0x7cdd53aa),
2381 X(0x7ce058d3), X(0x7ce35bef), X(0x7ce65cff), X(0x7ce95c04),
2382 X(0x7cec58ff), X(0x7cef53f0), X(0x7cf24cd7), X(0x7cf543b7),
2383 X(0x7cf8388f), X(0x7cfb2b60), X(0x7cfe1c2b), X(0x7d010af1),
2384 X(0x7d03f7b2), X(0x7d06e26f), X(0x7d09cb29), X(0x7d0cb1e0),
2385 X(0x7d0f9696), X(0x7d12794b), X(0x7d1559ff), X(0x7d1838b4),
2386 X(0x7d1b156a), X(0x7d1df022), X(0x7d20c8dd), X(0x7d239f9b),
2387 X(0x7d26745e), X(0x7d294725), X(0x7d2c17f1), X(0x7d2ee6c4),
2388 X(0x7d31b39f), X(0x7d347e81), X(0x7d37476b), X(0x7d3a0e5f),
2389 X(0x7d3cd35d), X(0x7d3f9665), X(0x7d425779), X(0x7d451699),
2390 X(0x7d47d3c6), X(0x7d4a8f01), X(0x7d4d484b), X(0x7d4fffa3),
2391 X(0x7d52b50c), X(0x7d556885), X(0x7d581a0f), X(0x7d5ac9ac),
2392 X(0x7d5d775c), X(0x7d60231f), X(0x7d62ccf6), X(0x7d6574e3),
2393 X(0x7d681ae6), X(0x7d6abeff), X(0x7d6d612f), X(0x7d700178),
2394 X(0x7d729fd9), X(0x7d753c54), X(0x7d77d6e9), X(0x7d7a6f9a),
2395 X(0x7d7d0666), X(0x7d7f9b4f), X(0x7d822e55), X(0x7d84bf79),
2396 X(0x7d874ebc), X(0x7d89dc1e), X(0x7d8c67a1), X(0x7d8ef144),
2397 X(0x7d91790a), X(0x7d93fef2), X(0x7d9682fd), X(0x7d99052d),
2398 X(0x7d9b8581), X(0x7d9e03fb), X(0x7da0809b), X(0x7da2fb62),
2399 X(0x7da57451), X(0x7da7eb68), X(0x7daa60a8), X(0x7dacd413),
2400 X(0x7daf45a9), X(0x7db1b56a), X(0x7db42357), X(0x7db68f71),
2401 X(0x7db8f9b9), X(0x7dbb6230), X(0x7dbdc8d6), X(0x7dc02dac),
2402 X(0x7dc290b3), X(0x7dc4f1eb), X(0x7dc75156), X(0x7dc9aef4),
2403 X(0x7dcc0ac5), X(0x7dce64cc), X(0x7dd0bd07), X(0x7dd31379),
2404 X(0x7dd56821), X(0x7dd7bb01), X(0x7dda0c1a), X(0x7ddc5b6b),
2405 X(0x7ddea8f7), X(0x7de0f4bd), X(0x7de33ebe), X(0x7de586fc),
2406 X(0x7de7cd76), X(0x7dea122e), X(0x7dec5525), X(0x7dee965a),
2407 X(0x7df0d5d0), X(0x7df31386), X(0x7df54f7e), X(0x7df789b8),
2408 X(0x7df9c235), X(0x7dfbf8f5), X(0x7dfe2dfa), X(0x7e006145),
2409 X(0x7e0292d5), X(0x7e04c2ac), X(0x7e06f0cb), X(0x7e091d32),
2410 X(0x7e0b47e1), X(0x7e0d70db), X(0x7e0f981f), X(0x7e11bdaf),
2411 X(0x7e13e18a), X(0x7e1603b3), X(0x7e182429), X(0x7e1a42ed),
2412 X(0x7e1c6001), X(0x7e1e7b64), X(0x7e209518), X(0x7e22ad1d),
2413 X(0x7e24c375), X(0x7e26d81f), X(0x7e28eb1d), X(0x7e2afc70),
2414 X(0x7e2d0c17), X(0x7e2f1a15), X(0x7e31266a), X(0x7e333115),
2415 X(0x7e353a1a), X(0x7e374177), X(0x7e39472e), X(0x7e3b4b3f),
2416 X(0x7e3d4dac), X(0x7e3f4e75), X(0x7e414d9a), X(0x7e434b1e),
2417 X(0x7e4546ff), X(0x7e474140), X(0x7e4939e0), X(0x7e4b30e2),
2418 X(0x7e4d2644), X(0x7e4f1a09), X(0x7e510c30), X(0x7e52fcbc),
2419 X(0x7e54ebab), X(0x7e56d900), X(0x7e58c4bb), X(0x7e5aaedd),
2420 X(0x7e5c9766), X(0x7e5e7e57), X(0x7e6063b2), X(0x7e624776),
2421 X(0x7e6429a5), X(0x7e660a3f), X(0x7e67e945), X(0x7e69c6b8),
2422 X(0x7e6ba299), X(0x7e6d7ce7), X(0x7e6f55a5), X(0x7e712cd3),
2423 X(0x7e730272), X(0x7e74d682), X(0x7e76a904), X(0x7e7879f9),
2424 X(0x7e7a4962), X(0x7e7c173f), X(0x7e7de392), X(0x7e7fae5a),
2425 X(0x7e817799), X(0x7e833f50), X(0x7e85057f), X(0x7e86ca27),
2426 X(0x7e888d49), X(0x7e8a4ee5), X(0x7e8c0efd), X(0x7e8dcd91),
2427 X(0x7e8f8aa1), X(0x7e914630), X(0x7e93003c), X(0x7e94b8c8),
2428 X(0x7e966fd4), X(0x7e982560), X(0x7e99d96e), X(0x7e9b8bfe),
2429 X(0x7e9d3d10), X(0x7e9eeca7), X(0x7ea09ac2), X(0x7ea24762),
2430 X(0x7ea3f288), X(0x7ea59c35), X(0x7ea7446a), X(0x7ea8eb27),
2431 X(0x7eaa906c), X(0x7eac343c), X(0x7eadd696), X(0x7eaf777b),
2432 X(0x7eb116ed), X(0x7eb2b4eb), X(0x7eb45177), X(0x7eb5ec91),
2433 X(0x7eb7863b), X(0x7eb91e74), X(0x7ebab53e), X(0x7ebc4a99),
2434 X(0x7ebdde87), X(0x7ebf7107), X(0x7ec1021b), X(0x7ec291c3),
2435 X(0x7ec42001), X(0x7ec5acd5), X(0x7ec7383f), X(0x7ec8c241),
2436 X(0x7eca4adb), X(0x7ecbd20d), X(0x7ecd57da), X(0x7ecedc41),
2437 X(0x7ed05f44), X(0x7ed1e0e2), X(0x7ed3611d), X(0x7ed4dff6),
2438 X(0x7ed65d6d), X(0x7ed7d983), X(0x7ed95438), X(0x7edacd8f),
2439 X(0x7edc4586), X(0x7eddbc20), X(0x7edf315c), X(0x7ee0a53c),
2440 X(0x7ee217c1), X(0x7ee388ea), X(0x7ee4f8b9), X(0x7ee6672f),
2441 X(0x7ee7d44c), X(0x7ee94012), X(0x7eeaaa80), X(0x7eec1397),
2442 X(0x7eed7b59), X(0x7eeee1c6), X(0x7ef046df), X(0x7ef1aaa5),
2443 X(0x7ef30d18), X(0x7ef46e39), X(0x7ef5ce09), X(0x7ef72c88),
2444 X(0x7ef889b8), X(0x7ef9e599), X(0x7efb402c), X(0x7efc9972),
2445 X(0x7efdf16b), X(0x7eff4818), X(0x7f009d79), X(0x7f01f191),
2446 X(0x7f03445f), X(0x7f0495e4), X(0x7f05e620), X(0x7f073516),
2447 X(0x7f0882c5), X(0x7f09cf2d), X(0x7f0b1a51), X(0x7f0c6430),
2448 X(0x7f0daccc), X(0x7f0ef425), X(0x7f103a3b), X(0x7f117f11),
2449 X(0x7f12c2a5), X(0x7f1404fa), X(0x7f15460f), X(0x7f1685e6),
2450 X(0x7f17c47f), X(0x7f1901db), X(0x7f1a3dfb), X(0x7f1b78e0),
2451 X(0x7f1cb28a), X(0x7f1deafa), X(0x7f1f2231), X(0x7f20582f),
2452 X(0x7f218cf5), X(0x7f22c085), X(0x7f23f2de), X(0x7f252401),
2453 X(0x7f2653f0), X(0x7f2782ab), X(0x7f28b032), X(0x7f29dc87),
2454 X(0x7f2b07aa), X(0x7f2c319c), X(0x7f2d5a5e), X(0x7f2e81f0),
2455 X(0x7f2fa853), X(0x7f30cd88), X(0x7f31f18f), X(0x7f33146a),
2456 X(0x7f343619), X(0x7f35569c), X(0x7f3675f6), X(0x7f379425),
2457 X(0x7f38b12c), X(0x7f39cd0a), X(0x7f3ae7c0), X(0x7f3c0150),
2458 X(0x7f3d19ba), X(0x7f3e30fe), X(0x7f3f471e), X(0x7f405c1a),
2459 X(0x7f416ff3), X(0x7f4282a9), X(0x7f43943e), X(0x7f44a4b2),
2460 X(0x7f45b405), X(0x7f46c239), X(0x7f47cf4e), X(0x7f48db45),
2461 X(0x7f49e61f), X(0x7f4aefdc), X(0x7f4bf87e), X(0x7f4d0004),
2462 X(0x7f4e0670), X(0x7f4f0bc2), X(0x7f500ffb), X(0x7f51131c),
2463 X(0x7f521525), X(0x7f531618), X(0x7f5415f4), X(0x7f5514bb),
2464 X(0x7f56126e), X(0x7f570f0c), X(0x7f580a98), X(0x7f590511),
2465 X(0x7f59fe78), X(0x7f5af6ce), X(0x7f5bee14), X(0x7f5ce44a),
2466 X(0x7f5dd972), X(0x7f5ecd8b), X(0x7f5fc097), X(0x7f60b296),
2467 X(0x7f61a389), X(0x7f629370), X(0x7f63824e), X(0x7f647021),
2468 X(0x7f655ceb), X(0x7f6648ad), X(0x7f673367), X(0x7f681d19),
2469 X(0x7f6905c6), X(0x7f69ed6d), X(0x7f6ad40f), X(0x7f6bb9ad),
2470 X(0x7f6c9e48), X(0x7f6d81e0), X(0x7f6e6475), X(0x7f6f460a),
2471 X(0x7f70269d), X(0x7f710631), X(0x7f71e4c6), X(0x7f72c25c),
2472 X(0x7f739ef4), X(0x7f747a8f), X(0x7f75552e), X(0x7f762ed1),
2473 X(0x7f770779), X(0x7f77df27), X(0x7f78b5db), X(0x7f798b97),
2474 X(0x7f7a605a), X(0x7f7b3425), X(0x7f7c06fa), X(0x7f7cd8d9),
2475 X(0x7f7da9c2), X(0x7f7e79b7), X(0x7f7f48b8), X(0x7f8016c5),
2476 X(0x7f80e3e0), X(0x7f81b009), X(0x7f827b40), X(0x7f834588),
2477 X(0x7f840edf), X(0x7f84d747), X(0x7f859ec1), X(0x7f86654d),
2478 X(0x7f872aec), X(0x7f87ef9e), X(0x7f88b365), X(0x7f897641),
2479 X(0x7f8a3832), X(0x7f8af93a), X(0x7f8bb959), X(0x7f8c7890),
2480 X(0x7f8d36df), X(0x7f8df448), X(0x7f8eb0ca), X(0x7f8f6c67),
2481 X(0x7f90271e), X(0x7f90e0f2), X(0x7f9199e2), X(0x7f9251f0),
2482 X(0x7f93091b), X(0x7f93bf65), X(0x7f9474ce), X(0x7f952958),
2483 X(0x7f95dd01), X(0x7f968fcd), X(0x7f9741ba), X(0x7f97f2ca),
2484 X(0x7f98a2fd), X(0x7f995254), X(0x7f9a00d0), X(0x7f9aae71),
2485 X(0x7f9b5b38), X(0x7f9c0726), X(0x7f9cb23b), X(0x7f9d5c78),
2486 X(0x7f9e05de), X(0x7f9eae6e), X(0x7f9f5627), X(0x7f9ffd0b),
2487 X(0x7fa0a31b), X(0x7fa14856), X(0x7fa1ecbf), X(0x7fa29054),
2488 X(0x7fa33318), X(0x7fa3d50b), X(0x7fa4762c), X(0x7fa5167e),
2489 X(0x7fa5b601), X(0x7fa654b5), X(0x7fa6f29b), X(0x7fa78fb3),
2490 X(0x7fa82bff), X(0x7fa8c77f), X(0x7fa96234), X(0x7fa9fc1e),
2491 X(0x7faa953e), X(0x7fab2d94), X(0x7fabc522), X(0x7fac5be8),
2492 X(0x7facf1e6), X(0x7fad871d), X(0x7fae1b8f), X(0x7faeaf3b),
2493 X(0x7faf4222), X(0x7fafd445), X(0x7fb065a4), X(0x7fb0f641),
2494 X(0x7fb1861b), X(0x7fb21534), X(0x7fb2a38c), X(0x7fb33124),
2495 X(0x7fb3bdfb), X(0x7fb44a14), X(0x7fb4d56f), X(0x7fb5600c),
2496 X(0x7fb5e9ec), X(0x7fb6730f), X(0x7fb6fb76), X(0x7fb78323),
2497 X(0x7fb80a15), X(0x7fb8904d), X(0x7fb915cc), X(0x7fb99a92),
2498 X(0x7fba1ea0), X(0x7fbaa1f7), X(0x7fbb2497), X(0x7fbba681),
2499 X(0x7fbc27b5), X(0x7fbca835), X(0x7fbd2801), X(0x7fbda719),
2500 X(0x7fbe257e), X(0x7fbea331), X(0x7fbf2032), X(0x7fbf9c82),
2501 X(0x7fc01821), X(0x7fc09311), X(0x7fc10d52), X(0x7fc186e4),
2502 X(0x7fc1ffc8), X(0x7fc277ff), X(0x7fc2ef89), X(0x7fc36667),
2503 X(0x7fc3dc9a), X(0x7fc45221), X(0x7fc4c6ff), X(0x7fc53b33),
2504 X(0x7fc5aebe), X(0x7fc621a0), X(0x7fc693db), X(0x7fc7056f),
2505 X(0x7fc7765c), X(0x7fc7e6a3), X(0x7fc85645), X(0x7fc8c542),
2506 X(0x7fc9339b), X(0x7fc9a150), X(0x7fca0e63), X(0x7fca7ad3),
2507 X(0x7fcae6a2), X(0x7fcb51cf), X(0x7fcbbc5c), X(0x7fcc2649),
2508 X(0x7fcc8f97), X(0x7fccf846), X(0x7fcd6058), X(0x7fcdc7cb),
2509 X(0x7fce2ea2), X(0x7fce94dd), X(0x7fcefa7b), X(0x7fcf5f7f),
2510 X(0x7fcfc3e8), X(0x7fd027b7), X(0x7fd08aed), X(0x7fd0ed8b),
2511 X(0x7fd14f90), X(0x7fd1b0fd), X(0x7fd211d4), X(0x7fd27214),
2512 X(0x7fd2d1bf), X(0x7fd330d4), X(0x7fd38f55), X(0x7fd3ed41),
2513 X(0x7fd44a9a), X(0x7fd4a761), X(0x7fd50395), X(0x7fd55f37),
2514 X(0x7fd5ba48), X(0x7fd614c9), X(0x7fd66eba), X(0x7fd6c81b),
2515 X(0x7fd720ed), X(0x7fd77932), X(0x7fd7d0e8), X(0x7fd82812),
2516 X(0x7fd87eae), X(0x7fd8d4bf), X(0x7fd92a45), X(0x7fd97f40),
2517 X(0x7fd9d3b0), X(0x7fda2797), X(0x7fda7af5), X(0x7fdacdca),
2518 X(0x7fdb2018), X(0x7fdb71dd), X(0x7fdbc31c), X(0x7fdc13d5),
2519 X(0x7fdc6408), X(0x7fdcb3b6), X(0x7fdd02df), X(0x7fdd5184),
2520 X(0x7fdd9fa5), X(0x7fdded44), X(0x7fde3a60), X(0x7fde86fb),
2521 X(0x7fded314), X(0x7fdf1eac), X(0x7fdf69c4), X(0x7fdfb45d),
2522 X(0x7fdffe76), X(0x7fe04811), X(0x7fe0912e), X(0x7fe0d9ce),
2523 X(0x7fe121f0), X(0x7fe16996), X(0x7fe1b0c1), X(0x7fe1f770),
2524 X(0x7fe23da4), X(0x7fe2835f), X(0x7fe2c89f), X(0x7fe30d67),
2525 X(0x7fe351b5), X(0x7fe3958c), X(0x7fe3d8ec), X(0x7fe41bd4),
2526 X(0x7fe45e46), X(0x7fe4a042), X(0x7fe4e1c8), X(0x7fe522da),
2527 X(0x7fe56378), X(0x7fe5a3a1), X(0x7fe5e358), X(0x7fe6229b),
2528 X(0x7fe6616d), X(0x7fe69fcc), X(0x7fe6ddbb), X(0x7fe71b39),
2529 X(0x7fe75847), X(0x7fe794e5), X(0x7fe7d114), X(0x7fe80cd5),
2530 X(0x7fe84827), X(0x7fe8830c), X(0x7fe8bd84), X(0x7fe8f78f),
2531 X(0x7fe9312f), X(0x7fe96a62), X(0x7fe9a32b), X(0x7fe9db8a),
2532 X(0x7fea137e), X(0x7fea4b09), X(0x7fea822b), X(0x7feab8e5),
2533 X(0x7feaef37), X(0x7feb2521), X(0x7feb5aa4), X(0x7feb8fc1),
2534 X(0x7febc478), X(0x7febf8ca), X(0x7fec2cb6), X(0x7fec603e),
2535 X(0x7fec9363), X(0x7fecc623), X(0x7fecf881), X(0x7fed2a7c),
2536 X(0x7fed5c16), X(0x7fed8d4e), X(0x7fedbe24), X(0x7fedee9b),
2537 X(0x7fee1eb1), X(0x7fee4e68), X(0x7fee7dc0), X(0x7feeacb9),
2538 X(0x7feedb54), X(0x7fef0991), X(0x7fef3771), X(0x7fef64f5),
2539 X(0x7fef921d), X(0x7fefbee8), X(0x7fefeb59), X(0x7ff0176f),
2540 X(0x7ff0432a), X(0x7ff06e8c), X(0x7ff09995), X(0x7ff0c444),
2541 X(0x7ff0ee9c), X(0x7ff1189b), X(0x7ff14243), X(0x7ff16b94),
2542 X(0x7ff1948e), X(0x7ff1bd32), X(0x7ff1e581), X(0x7ff20d7b),
2543 X(0x7ff2351f), X(0x7ff25c70), X(0x7ff2836d), X(0x7ff2aa17),
2544 X(0x7ff2d06d), X(0x7ff2f672), X(0x7ff31c24), X(0x7ff34185),
2545 X(0x7ff36695), X(0x7ff38b55), X(0x7ff3afc4), X(0x7ff3d3e4),
2546 X(0x7ff3f7b4), X(0x7ff41b35), X(0x7ff43e69), X(0x7ff4614e),
2547 X(0x7ff483e6), X(0x7ff4a631), X(0x7ff4c82f), X(0x7ff4e9e1),
2548 X(0x7ff50b47), X(0x7ff52c62), X(0x7ff54d33), X(0x7ff56db9),
2549 X(0x7ff58df5), X(0x7ff5ade7), X(0x7ff5cd90), X(0x7ff5ecf1),
2550 X(0x7ff60c09), X(0x7ff62ada), X(0x7ff64963), X(0x7ff667a5),
2551 X(0x7ff685a1), X(0x7ff6a357), X(0x7ff6c0c7), X(0x7ff6ddf1),
2552 X(0x7ff6fad7), X(0x7ff71778), X(0x7ff733d6), X(0x7ff74fef),
2553 X(0x7ff76bc6), X(0x7ff78759), X(0x7ff7a2ab), X(0x7ff7bdba),
2554 X(0x7ff7d888), X(0x7ff7f315), X(0x7ff80d61), X(0x7ff8276c),
2555 X(0x7ff84138), X(0x7ff85ac4), X(0x7ff87412), X(0x7ff88d20),
2556 X(0x7ff8a5f0), X(0x7ff8be82), X(0x7ff8d6d7), X(0x7ff8eeef),
2557 X(0x7ff906c9), X(0x7ff91e68), X(0x7ff935cb), X(0x7ff94cf2),
2558 X(0x7ff963dd), X(0x7ff97a8f), X(0x7ff99105), X(0x7ff9a742),
2559 X(0x7ff9bd45), X(0x7ff9d30f), X(0x7ff9e8a0), X(0x7ff9fdf9),
2560 X(0x7ffa131a), X(0x7ffa2803), X(0x7ffa3cb4), X(0x7ffa512f),
2561 X(0x7ffa6573), X(0x7ffa7981), X(0x7ffa8d59), X(0x7ffaa0fc),
2562 X(0x7ffab46a), X(0x7ffac7a3), X(0x7ffadaa8), X(0x7ffaed78),
2563 X(0x7ffb0015), X(0x7ffb127f), X(0x7ffb24b6), X(0x7ffb36bb),
2564 X(0x7ffb488d), X(0x7ffb5a2e), X(0x7ffb6b9d), X(0x7ffb7cdb),
2565 X(0x7ffb8de9), X(0x7ffb9ec6), X(0x7ffbaf73), X(0x7ffbbff1),
2566 X(0x7ffbd03f), X(0x7ffbe05e), X(0x7ffbf04f), X(0x7ffc0012),
2567 X(0x7ffc0fa6), X(0x7ffc1f0d), X(0x7ffc2e47), X(0x7ffc3d54),
2568 X(0x7ffc4c35), X(0x7ffc5ae9), X(0x7ffc6971), X(0x7ffc77ce),
2569 X(0x7ffc8600), X(0x7ffc9407), X(0x7ffca1e4), X(0x7ffcaf96),
2570 X(0x7ffcbd1f), X(0x7ffcca7e), X(0x7ffcd7b4), X(0x7ffce4c1),
2571 X(0x7ffcf1a5), X(0x7ffcfe62), X(0x7ffd0af6), X(0x7ffd1763),
2572 X(0x7ffd23a9), X(0x7ffd2fc8), X(0x7ffd3bc1), X(0x7ffd4793),
2573 X(0x7ffd533f), X(0x7ffd5ec5), X(0x7ffd6a27), X(0x7ffd7563),
2574 X(0x7ffd807a), X(0x7ffd8b6e), X(0x7ffd963d), X(0x7ffda0e8),
2575 X(0x7ffdab70), X(0x7ffdb5d5), X(0x7ffdc017), X(0x7ffdca36),
2576 X(0x7ffdd434), X(0x7ffdde0f), X(0x7ffde7c9), X(0x7ffdf161),
2577 X(0x7ffdfad8), X(0x7ffe042f), X(0x7ffe0d65), X(0x7ffe167b),
2578 X(0x7ffe1f71), X(0x7ffe2848), X(0x7ffe30ff), X(0x7ffe3997),
2579 X(0x7ffe4211), X(0x7ffe4a6c), X(0x7ffe52a9), X(0x7ffe5ac8),
2580 X(0x7ffe62c9), X(0x7ffe6aae), X(0x7ffe7275), X(0x7ffe7a1f),
2581 X(0x7ffe81ad), X(0x7ffe891f), X(0x7ffe9075), X(0x7ffe97b0),
2582 X(0x7ffe9ece), X(0x7ffea5d2), X(0x7ffeacbb), X(0x7ffeb38a),
2583 X(0x7ffeba3e), X(0x7ffec0d8), X(0x7ffec758), X(0x7ffecdbf),
2584 X(0x7ffed40d), X(0x7ffeda41), X(0x7ffee05d), X(0x7ffee660),
2585 X(0x7ffeec4b), X(0x7ffef21f), X(0x7ffef7da), X(0x7ffefd7e),
2586 X(0x7fff030b), X(0x7fff0881), X(0x7fff0de0), X(0x7fff1328),
2587 X(0x7fff185b), X(0x7fff1d77), X(0x7fff227e), X(0x7fff276f),
2588 X(0x7fff2c4b), X(0x7fff3112), X(0x7fff35c4), X(0x7fff3a62),
2589 X(0x7fff3eeb), X(0x7fff4360), X(0x7fff47c2), X(0x7fff4c0f),
2590 X(0x7fff504a), X(0x7fff5471), X(0x7fff5885), X(0x7fff5c87),
2591 X(0x7fff6076), X(0x7fff6452), X(0x7fff681d), X(0x7fff6bd6),
2592 X(0x7fff6f7d), X(0x7fff7313), X(0x7fff7698), X(0x7fff7a0c),
2593 X(0x7fff7d6f), X(0x7fff80c2), X(0x7fff8404), X(0x7fff8736),
2594 X(0x7fff8a58), X(0x7fff8d6b), X(0x7fff906e), X(0x7fff9362),
2595 X(0x7fff9646), X(0x7fff991c), X(0x7fff9be3), X(0x7fff9e9c),
2596 X(0x7fffa146), X(0x7fffa3e2), X(0x7fffa671), X(0x7fffa8f1),
2597 X(0x7fffab65), X(0x7fffadca), X(0x7fffb023), X(0x7fffb26f),
2598 X(0x7fffb4ae), X(0x7fffb6e0), X(0x7fffb906), X(0x7fffbb20),
2599 X(0x7fffbd2e), X(0x7fffbf30), X(0x7fffc126), X(0x7fffc311),
2600 X(0x7fffc4f1), X(0x7fffc6c5), X(0x7fffc88f), X(0x7fffca4d),
2601 X(0x7fffcc01), X(0x7fffcdab), X(0x7fffcf4a), X(0x7fffd0e0),
2602 X(0x7fffd26b), X(0x7fffd3ec), X(0x7fffd564), X(0x7fffd6d2),
2603 X(0x7fffd838), X(0x7fffd993), X(0x7fffdae6), X(0x7fffdc31),
2604 X(0x7fffdd72), X(0x7fffdeab), X(0x7fffdfdb), X(0x7fffe104),
2605 X(0x7fffe224), X(0x7fffe33c), X(0x7fffe44d), X(0x7fffe556),
2606 X(0x7fffe657), X(0x7fffe751), X(0x7fffe844), X(0x7fffe930),
2607 X(0x7fffea15), X(0x7fffeaf3), X(0x7fffebca), X(0x7fffec9b),
2608 X(0x7fffed66), X(0x7fffee2a), X(0x7fffeee8), X(0x7fffefa0),
2609 X(0x7ffff053), X(0x7ffff0ff), X(0x7ffff1a6), X(0x7ffff247),
2610 X(0x7ffff2e4), X(0x7ffff37a), X(0x7ffff40c), X(0x7ffff499),
2611 X(0x7ffff520), X(0x7ffff5a3), X(0x7ffff621), X(0x7ffff69b),
2612 X(0x7ffff710), X(0x7ffff781), X(0x7ffff7ee), X(0x7ffff857),
2613 X(0x7ffff8bb), X(0x7ffff91c), X(0x7ffff979), X(0x7ffff9d2),
2614 X(0x7ffffa27), X(0x7ffffa79), X(0x7ffffac8), X(0x7ffffb13),
2615 X(0x7ffffb5b), X(0x7ffffba0), X(0x7ffffbe2), X(0x7ffffc21),
2616 X(0x7ffffc5d), X(0x7ffffc96), X(0x7ffffccd), X(0x7ffffd01),
2617 X(0x7ffffd32), X(0x7ffffd61), X(0x7ffffd8e), X(0x7ffffdb8),
2618 X(0x7ffffde0), X(0x7ffffe07), X(0x7ffffe2b), X(0x7ffffe4d),
2619 X(0x7ffffe6d), X(0x7ffffe8b), X(0x7ffffea8), X(0x7ffffec3),
2620 X(0x7ffffedc), X(0x7ffffef4), X(0x7fffff0a), X(0x7fffff1f),
2621 X(0x7fffff33), X(0x7fffff45), X(0x7fffff56), X(0x7fffff66),
2622 X(0x7fffff75), X(0x7fffff82), X(0x7fffff8f), X(0x7fffff9a),
2623 X(0x7fffffa5), X(0x7fffffaf), X(0x7fffffb8), X(0x7fffffc0),
2624 X(0x7fffffc8), X(0x7fffffce), X(0x7fffffd5), X(0x7fffffda),
2625 X(0x7fffffdf), X(0x7fffffe4), X(0x7fffffe8), X(0x7fffffeb),
2626 X(0x7fffffef), X(0x7ffffff1), X(0x7ffffff4), X(0x7ffffff6),
2627 X(0x7ffffff8), X(0x7ffffff9), X(0x7ffffffb), X(0x7ffffffc),
2628 X(0x7ffffffd), X(0x7ffffffd), X(0x7ffffffe), X(0x7fffffff),
2629 X(0x7fffffff), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
2630 X(0x7fffffff), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
2631 X(0x7fffffff), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
2635 /* ******************************************************************
2636 function: lookup data
2637 ****************************************************************** */
2639 enum FROMdB_LOOKUP_SZ = 35;
2640 enum FROMdB2_LOOKUP_SZ = 32;
2641 enum FROMdB_SHIFT = 5;
2642 enum FROMdB2_SHIFT = 3;
2643 enum FROMdB2_MASK = 31;
2645 static immutable ogg_int32_t[FROMdB_LOOKUP_SZ] FROMdB_LOOKUP=[
2646 0x003fffff, 0x0028619b, 0x00197a96, 0x0010137a,
2647 0x000a24b0, 0x00066666, 0x000409c3, 0x00028c42,
2648 0x00019b8c, 0x000103ab, 0x0000a3d7, 0x00006760,
2649 0x0000413a, 0x00002928, 0x000019f8, 0x00001062,
2650 0x00000a56, 0x00000686, 0x0000041e, 0x00000299,
2651 0x000001a3, 0x00000109, 0x000000a7, 0x00000069,
2652 0x00000042, 0x0000002a, 0x0000001a, 0x00000011,
2653 0x0000000b, 0x00000007, 0x00000004, 0x00000003,
2654 0x00000002, 0x00000001, 0x00000001];
2656 static immutable ogg_int32_t[FROMdB2_LOOKUP_SZ] FROMdB2_LOOKUP=[
2657 0x000001fc, 0x000001f5, 0x000001ee, 0x000001e7,
2658 0x000001e0, 0x000001d9, 0x000001d2, 0x000001cc,
2659 0x000001c5, 0x000001bf, 0x000001b8, 0x000001b2,
2660 0x000001ac, 0x000001a6, 0x000001a0, 0x0000019a,
2661 0x00000194, 0x0000018e, 0x00000188, 0x00000183,
2662 0x0000017d, 0x00000178, 0x00000172, 0x0000016d,
2663 0x00000168, 0x00000163, 0x0000015e, 0x00000159,
2664 0x00000154, 0x0000014f, 0x0000014a, 0x00000145,
2667 enum INVSQ_LOOKUP_I_SHIFT = 10;
2668 enum INVSQ_LOOKUP_I_MASK = 1023;
2669 static immutable trm_long[64+1] INVSQ_LOOKUP_I=[
2670 92682, 91966, 91267, 90583,
2671 89915, 89261, 88621, 87995,
2672 87381, 86781, 86192, 85616,
2673 85051, 84497, 83953, 83420,
2674 82897, 82384, 81880, 81385,
2675 80899, 80422, 79953, 79492,
2676 79039, 78594, 78156, 77726,
2677 77302, 76885, 76475, 76072,
2678 75674, 75283, 74898, 74519,
2679 74146, 73778, 73415, 73058,
2680 72706, 72359, 72016, 71679,
2681 71347, 71019, 70695, 70376,
2682 70061, 69750, 69444, 69141,
2683 68842, 68548, 68256, 67969,
2684 67685, 67405, 67128, 66855,
2685 66585, 66318, 66054, 65794,
2686 65536,
2689 static immutable trm_long[64] INVSQ_LOOKUP_IDel=[
2690 716, 699, 684, 668,
2691 654, 640, 626, 614,
2692 600, 589, 576, 565,
2693 554, 544, 533, 523,
2694 513, 504, 495, 486,
2695 477, 469, 461, 453,
2696 445, 438, 430, 424,
2697 417, 410, 403, 398,
2698 391, 385, 379, 373,
2699 368, 363, 357, 352,
2700 347, 343, 337, 332,
2701 328, 324, 319, 315,
2702 311, 306, 303, 299,
2703 294, 292, 287, 284,
2704 280, 277, 273, 270,
2705 267, 264, 260, 258,
2708 enum COS_LOOKUP_I_SHIFT = 9;
2709 enum COS_LOOKUP_I_MASK = 511;
2710 enum COS_LOOKUP_I_SZ = 128;
2711 static immutable ogg_int32_t[COS_LOOKUP_I_SZ+1] COS_LOOKUP_I=[
2712 16384, 16379, 16364, 16340,
2713 16305, 16261, 16207, 16143,
2714 16069, 15986, 15893, 15791,
2715 15679, 15557, 15426, 15286,
2716 15137, 14978, 14811, 14635,
2717 14449, 14256, 14053, 13842,
2718 13623, 13395, 13160, 12916,
2719 12665, 12406, 12140, 11866,
2720 11585, 11297, 11003, 10702,
2721 10394, 10080, 9760, 9434,
2722 9102, 8765, 8423, 8076,
2723 7723, 7366, 7005, 6639,
2724 6270, 5897, 5520, 5139,
2725 4756, 4370, 3981, 3590,
2726 3196, 2801, 2404, 2006,
2727 1606, 1205, 804, 402,
2728 0, -401, -803, -1204,
2729 -1605, -2005, -2403, -2800,
2730 -3195, -3589, -3980, -4369,
2731 -4755, -5138, -5519, -5896,
2732 -6269, -6638, -7004, -7365,
2733 -7722, -8075, -8422, -8764,
2734 -9101, -9433, -9759, -10079,
2735 -10393, -10701, -11002, -11296,
2736 -11584, -11865, -12139, -12405,
2737 -12664, -12915, -13159, -13394,
2738 -13622, -13841, -14052, -14255,
2739 -14448, -14634, -14810, -14977,
2740 -15136, -15285, -15425, -15556,
2741 -15678, -15790, -15892, -15985,
2742 -16068, -16142, -16206, -16260,
2743 -16304, -16339, -16363, -16378,
2744 -16383,
2748 /* ******************************************************************
2749 function: registry for time, floor, res backends and channel mappings
2750 ****************************************************************** */
2751 enum VI_TRANSFORMB = 1;
2752 enum VI_WINDOWB = 1;
2753 enum VI_TIMEB = 1;
2754 enum VI_FLOORB = 2;
2755 enum VI_RESB = 3;
2756 enum VI_MAPB = 1;
2758 static immutable vorbis_func_floor*[2] floor_P_=[
2759 &floor0_exportbundle,
2760 &floor1_exportbundle,
2763 static immutable vorbis_func_residue*[3] residue_P_=[
2764 &residue0_exportbundle,
2765 &residue1_exportbundle,
2766 &residue2_exportbundle,
2769 static immutable vorbis_func_mapping*[1] mapping_P_=[
2770 &mapping0_exportbundle,
2774 private int block_ilog(uint v){
2775 int ret=0;
2776 if(v)--v;
2777 while(v){
2778 ret++;
2779 v>>=1;
2781 return(ret);
2784 /* pcm accumulator examples (not exhaustive):
2786 <-------------- lW ---------------->
2787 <--------------- W ---------------->
2788 : .....|..... _______________ |
2789 : .''' | '''_--- | |\ |
2790 :.....''' |_____--- '''......| | \_______|
2791 :.................|__________________|_______|__|______|
2792 |<------ Sl ------>| > Sr < |endW
2793 |beginSl |endSl | |endSr
2794 |beginW |endlW |beginSr
2797 |< lW >|
2798 <--------------- W ---------------->
2799 | | .. ______________ |
2800 | | ' `/ | ---_ |
2801 |___.'___/`. | ---_____|
2802 |_______|__|_______|_________________|
2803 | >|Sl|< |<------ Sr ----->|endW
2804 | | |endSl |beginSr |endSr
2805 |beginW | |endlW
2806 mult[0] |beginSl mult[n]
2808 <-------------- lW ----------------->
2809 |<--W-->|
2810 : .............. ___ | |
2811 : .''' |`/ \ | |
2812 :.....''' |/`....\|...|
2813 :.........................|___|___|___|
2814 |Sl |Sr |endW
2815 | | |endSr
2816 | |beginSr
2817 | |endSl
2818 |beginSl
2819 |beginW
2822 /* block abstraction setup *********************************************/
2824 //#ifndef WORD_ALIGN
2825 //#define WORD_ALIGN 8
2826 //#endif
2827 enum WORD_ALIGN = 8;
2829 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
2830 memset(vb, 0, (*vb).sizeof);
2831 vb.vd=v;
2832 vb.localalloc=0;
2833 vb.localstore=null;
2835 return(0);
2838 void *vorbis_block_alloc_(vorbis_block *vb, /*trm_long*/usize bytes) nothrow @trusted @nogc {
2839 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
2840 if(bytes+vb.localtop>vb.localalloc){
2841 /* can't just ogg_realloc_... there are outstanding pointers */
2842 if(vb.localstore){
2843 alloc_chain *link;
2844 link=cast(alloc_chain *)ogg_malloc_((*link).sizeof);
2845 vb.totaluse+=vb.localtop;
2846 link.next=vb.reap;
2847 link.ptr=vb.localstore;
2848 vb.reap=link;
2850 /* highly conservative */
2851 vb.localalloc=bytes;
2852 vb.localstore=ogg_malloc_(vb.localalloc);
2853 vb.localtop=0;
2856 void *ret=cast(void *)((cast(char *)vb.localstore)+vb.localtop);
2857 vb.localtop+=bytes;
2858 return ret;
2862 /* reap the chain, pull the ripcord */
2863 void vorbis_block_ripcord_(vorbis_block *vb){
2864 /* reap the chain */
2865 alloc_chain *reap=vb.reap;
2866 while(reap){
2867 alloc_chain *next=reap.next;
2868 ogg_free_(reap.ptr);
2869 memset(reap, 0, (*reap).sizeof);
2870 ogg_free_(reap);
2871 reap=next;
2873 /* consolidate storage */
2874 if(vb.totaluse){
2875 vb.localstore=ogg_realloc_(vb.localstore, vb.totaluse+vb.localalloc);
2876 vb.localalloc+=vb.totaluse;
2877 vb.totaluse=0;
2880 /* pull the ripcord */
2881 vb.localtop=0;
2882 vb.reap=null;
2885 int vorbis_block_clear(vorbis_block *vb){
2886 vorbis_block_ripcord_(vb);
2887 if(vb.localstore)ogg_free_(vb.localstore);
2889 memset(vb, 0, (*vb).sizeof);
2890 return(0);
2893 private int vds_init_(vorbis_dsp_state *v, vorbis_info *vi){
2894 int i;
2895 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
2896 private_state *b=null;
2898 if(ci==null) return 1;
2900 memset(v, 0, (*v).sizeof);
2901 b=cast(private_state *)(v.backend_state=ogg_calloc_(1, (*b).sizeof));
2903 v.vi=vi;
2904 b.modebits=block_ilog(ci.modes);
2906 /* Vorbis I uses only window type 0 */
2907 b.window[0]=vorbis_window_(0, ci.blocksizes[0]/2);
2908 b.window[1]=vorbis_window_(0, ci.blocksizes[1]/2);
2910 /* finish the codebooks */
2911 if(!ci.fullbooks){
2912 ci.fullbooks=cast(codebook *)ogg_calloc_(ci.books, (*ci.fullbooks).sizeof);
2913 for(i=0;i<ci.books;i++){
2914 if(ci.book_param[i]==null)
2915 goto abort_books;
2916 if(vorbis_book_init_decode(ci.fullbooks+i, ci.book_param[i]))
2917 goto abort_books;
2918 /* decode codebooks are now standalone after init */
2919 vorbis_staticbook_destroy(ci.book_param[i]);
2920 ci.book_param[i]=null;
2924 v.pcm_storage=ci.blocksizes[1];
2925 v.pcm=cast(ogg_int32_t **)ogg_malloc_(vi.channels*(*v.pcm).sizeof);
2926 v.pcmret=cast(ogg_int32_t **)ogg_malloc_(vi.channels*(*v.pcmret).sizeof);
2927 for(i=0;i<vi.channels;i++)
2928 v.pcm[i]=cast(ogg_int32_t *)ogg_calloc_(v.pcm_storage, (*v.pcm[i]).sizeof);
2930 /* all 1 (large block) or 0 (small block) */
2931 /* explicitly set for the sake of clarity */
2932 v.lW=0; /* previous window size */
2933 v.W=0; /* current window size */
2935 /* initialize all the mapping/backend lookups */
2936 b.mode=cast(vorbis_look_mapping **)ogg_calloc_(ci.modes, (*b.mode).sizeof);
2937 for(i=0;i<ci.modes;i++){
2938 int mapnum=ci.mode_param[i].mapping;
2939 int maptype=ci.map_type[mapnum];
2940 b.mode[i]=mapping_P_[maptype].look(v, ci.mode_param[i],
2941 ci.map_param[mapnum]);
2943 return 0;
2944 abort_books:
2945 for(i=0;i<ci.books;i++){
2946 if(ci.book_param[i]!=null){
2947 vorbis_staticbook_destroy(ci.book_param[i]);
2948 ci.book_param[i]=null;
2951 vorbis_dsp_clear(v);
2952 return -1;
2955 int vorbis_synthesis_restart(vorbis_dsp_state *v){
2956 vorbis_info *vi=v.vi;
2957 codec_setup_info *ci;
2959 if(!v.backend_state)return -1;
2960 if(!vi)return -1;
2961 ci=cast(codec_setup_info*)vi.codec_setup;
2962 if(!ci)return -1;
2964 v.centerW=ci.blocksizes[1]/2;
2965 v.pcm_current=v.centerW;
2967 v.pcm_returned=-1;
2968 v.granulepos=-1;
2969 v.sequence=-1;
2970 (cast(private_state *)(v.backend_state)).sample_count=-1;
2972 return(0);
2975 int vorbis_synthesis_init(vorbis_dsp_state *v, vorbis_info *vi){
2976 if(vds_init_(v, vi))return 1;
2977 vorbis_synthesis_restart(v);
2979 return 0;
2982 void vorbis_dsp_clear(vorbis_dsp_state *v){
2983 int i;
2984 if(v){
2985 vorbis_info *vi=v.vi;
2986 codec_setup_info *ci=cast(codec_setup_info *)(vi?vi.codec_setup:null);
2987 private_state *b=cast(private_state *)v.backend_state;
2989 if(v.pcm){
2990 for(i=0;i<vi.channels;i++)
2991 if(v.pcm[i])ogg_free_(v.pcm[i]);
2992 ogg_free_(v.pcm);
2993 if(v.pcmret)ogg_free_(v.pcmret);
2996 /* free mode lookups; these are actually vorbis_look_mapping structs */
2997 if(ci){
2998 for(i=0;i<ci.modes;i++){
2999 int mapnum=ci.mode_param[i].mapping;
3000 int maptype=ci.map_type[mapnum];
3001 if(b && b.mode)mapping_P_[maptype].free_look(b.mode[i]);
3005 if(b){
3006 if(b.mode)ogg_free_(b.mode);
3007 ogg_free_(b);
3010 memset(v, 0, (*v).sizeof);
3014 /* Unlike in analysis, the window is only partially applied for each
3015 block. The time domain envelope is not yet handled at the point of
3016 calling (as it relies on the previous block). */
3018 int vorbis_synthesis_blockin(vorbis_dsp_state *v, vorbis_block *vb){
3019 vorbis_info *vi=v.vi;
3020 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
3021 private_state *b=cast(private_state *)v.backend_state;
3022 int i, j;
3024 if(v.pcm_current>v.pcm_returned && v.pcm_returned!=-1)return(OV_EINVAL);
3026 v.lW=v.W;
3027 v.W=vb.W;
3028 v.nW=-1;
3030 if((v.sequence==-1)||
3031 (v.sequence+1 != vb.sequence)){
3032 v.granulepos=-1; /* out of sequence; lose count */
3033 b.sample_count=-1;
3036 v.sequence=vb.sequence;
3038 if(vb.pcm){ /* no pcm to process if vorbis_synthesis_trackonly
3039 was called on block */
3040 int n=ci.blocksizes[v.W]/2;
3041 int n0=ci.blocksizes[0]/2;
3042 int n1=ci.blocksizes[1]/2;
3044 int thisCenter;
3045 int prevCenter;
3047 if(v.centerW){
3048 thisCenter=n1;
3049 prevCenter=0;
3050 }else{
3051 thisCenter=0;
3052 prevCenter=n1;
3055 /* v.pcm is now used like a two-stage double buffer. We don't want
3056 to have to constantly shift *or* adjust memory usage. Don't
3057 accept a new block until the old is shifted out */
3059 /* overlap/add PCM */
3061 for(j=0;j<vi.channels;j++){
3062 /* the overlap/add section */
3063 if(v.lW){
3064 if(v.W){
3065 /* large/large */
3066 ogg_int32_t *pcm=v.pcm[j]+prevCenter;
3067 ogg_int32_t *p=vb.pcm[j];
3068 for(i=0;i<n1;i++)
3069 pcm[i]+=p[i];
3070 }else{
3071 /* large/small */
3072 ogg_int32_t *pcm=v.pcm[j]+prevCenter+n1/2-n0/2;
3073 ogg_int32_t *p=vb.pcm[j];
3074 for(i=0;i<n0;i++)
3075 pcm[i]+=p[i];
3077 }else{
3078 if(v.W){
3079 /* small/large */
3080 ogg_int32_t *pcm=v.pcm[j]+prevCenter;
3081 ogg_int32_t *p=vb.pcm[j]+n1/2-n0/2;
3082 for(i=0;i<n0;i++)
3083 pcm[i]+=p[i];
3084 for(;i<n1/2+n0/2;i++)
3085 pcm[i]=p[i];
3086 }else{
3087 /* small/small */
3088 ogg_int32_t *pcm=v.pcm[j]+prevCenter;
3089 ogg_int32_t *p=vb.pcm[j];
3090 for(i=0;i<n0;i++)
3091 pcm[i]+=p[i];
3095 /* the copy section */
3097 ogg_int32_t *pcm=v.pcm[j]+thisCenter;
3098 ogg_int32_t *p=vb.pcm[j]+n;
3099 for(i=0;i<n;i++)
3100 pcm[i]=p[i];
3104 if(v.centerW)
3105 v.centerW=0;
3106 else
3107 v.centerW=n1;
3109 /* deal with initial packet state; we do this using the explicit
3110 pcm_returned==-1 flag otherwise we're sensitive to first block
3111 being short or long */
3113 if(v.pcm_returned==-1){
3114 v.pcm_returned=thisCenter;
3115 v.pcm_current=thisCenter;
3116 }else{
3117 v.pcm_returned=prevCenter;
3118 v.pcm_current=prevCenter+
3119 ci.blocksizes[v.lW]/4+
3120 ci.blocksizes[v.W]/4;
3125 /* track the frame number... This is for convenience, but also
3126 making sure our last packet doesn't end with added padding. If
3127 the last packet is partial, the number of samples we'll have to
3128 return will be past the vb.granulepos.
3130 This is not foolproof! It will be confused if we begin
3131 decoding at the last page after a seek or hole. In that case,
3132 we don't have a starting point to judge where the last frame
3133 is. For this reason, vorbisfile will always try to make sure
3134 it reads the last two marked pages in proper sequence */
3136 if(b.sample_count==-1){
3137 b.sample_count=0;
3138 }else{
3139 b.sample_count+=ci.blocksizes[v.lW]/4+ci.blocksizes[v.W]/4;
3142 if(v.granulepos==-1){
3143 if(vb.granulepos!=-1){ /* only set if we have a position to set to */
3145 v.granulepos=vb.granulepos;
3147 /* is this a short page? */
3148 if(b.sample_count>v.granulepos){
3149 /* corner case; if this is both the first and last audio page,
3150 then spec says the end is cut, not beginning */
3151 trm_long extra=cast(trm_long)(b.sample_count-vb.granulepos);
3153 /* we use ogg_int64_t for granule positions because a
3154 uint64 isn't universally available. Unfortunately,
3155 that means granposes can be 'negative' and result in
3156 extra being negative */
3157 if(extra<0)
3158 extra=0;
3160 if(vb.eofflag){
3161 /* trim the end */
3162 /* no preceeding granulepos; assume we started at zero (we'd
3163 have to in a short single-page stream) */
3164 /* granulepos could be -1 due to a seek, but that would result
3165 in a long coun`t, not short count */
3167 /* Guard against corrupt/malicious frames that set EOP and
3168 a backdated granpos; don't rewind more samples than we
3169 actually have */
3170 if(extra > v.pcm_current - v.pcm_returned)
3171 extra = v.pcm_current - v.pcm_returned;
3173 v.pcm_current-=extra;
3174 }else{
3175 /* trim the beginning */
3176 v.pcm_returned+=extra;
3177 if(v.pcm_returned>v.pcm_current)
3178 v.pcm_returned=v.pcm_current;
3184 }else{
3185 v.granulepos+=ci.blocksizes[v.lW]/4+ci.blocksizes[v.W]/4;
3186 if(vb.granulepos!=-1 && v.granulepos!=vb.granulepos){
3188 if(v.granulepos>vb.granulepos){
3189 trm_long extra=cast(trm_long)(v.granulepos-vb.granulepos);
3191 if(extra)
3192 if(vb.eofflag){
3193 /* partial last frame. Strip the extra samples off */
3195 /* Guard against corrupt/malicious frames that set EOP and
3196 a backdated granpos; don't rewind more samples than we
3197 actually have */
3198 if(extra > v.pcm_current - v.pcm_returned)
3199 extra = v.pcm_current - v.pcm_returned;
3201 /* we use ogg_int64_t for granule positions because a
3202 uint64 isn't universally available. Unfortunately,
3203 that means granposes can be 'negative' and result in
3204 extra being negative */
3205 if(extra<0)
3206 extra=0;
3208 v.pcm_current-=extra;
3210 } /* else {Shouldn't happen *unless* the bitstream is out of
3211 spec. Either way, believe the bitstream } */
3212 } /* else {Shouldn't happen *unless* the bitstream is out of
3213 spec. Either way, believe the bitstream } */
3214 v.granulepos=vb.granulepos;
3218 /* Update, cleanup */
3220 if(vb.eofflag)v.eofflag=1;
3221 return(0);
3224 /* pcm==null indicates we just want the pending samples, no more */
3225 int vorbis_synthesis_pcmout(vorbis_dsp_state *v, ogg_int32_t ***pcm){
3226 vorbis_info *vi=v.vi;
3227 if(v.pcm_returned>-1 && v.pcm_returned<v.pcm_current){
3228 if(pcm){
3229 int i;
3230 for(i=0;i<vi.channels;i++)
3231 v.pcmret[i]=v.pcm[i]+v.pcm_returned;
3232 *pcm=v.pcmret;
3234 return(v.pcm_current-v.pcm_returned);
3236 return(0);
3239 int vorbis_synthesis_read(vorbis_dsp_state *v, int bytes){
3240 if(bytes && v.pcm_returned+bytes>v.pcm_current)return(OV_EINVAL);
3241 v.pcm_returned+=bytes;
3242 return(0);
3246 /* ******************************************************************
3247 function: basic shared codebook operations
3248 ****************************************************************** */
3250 /* This structure encapsulates huffman and VQ style encoding books; it
3251 doesn't do anything specific to either.
3253 valuelist/quantlist are nonNULL (and q_* significant) only if
3254 there's entry->value mapping to be done.
3256 If encode-side mapping must be done (and thus the entry needs to be
3257 hunted), the auxiliary encode pointer will point to a decision
3258 tree. This is true of both VQ and huffman, but is mostly useful
3259 with VQ.
3263 struct static_codebook {
3264 trm_long dim; /* codebook dimensions (elements per vector) */
3265 trm_long entries; /* codebook entries */
3266 trm_long *lengthlist; /* codeword lengths in bits */
3268 /* mapping ***************************************************************/
3269 int maptype; /* 0=none
3270 1=implicitly populated values from map column
3271 2=listed arbitrary values */
3273 /* The below does a linear, single monotonic sequence mapping. */
3274 trm_long q_min; /* packed 32 bit float; quant value 0 maps to minval */
3275 trm_long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */
3276 int q_quant; /* bits: 0 < quant <= 16 */
3277 int q_sequencep; /* bitflag */
3279 trm_long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map
3280 map == 2: list of dim*entries quantized entry vals
3284 struct codebook {
3285 trm_long dim; /* codebook dimensions (elements per vector) */
3286 trm_long entries; /* codebook entries */
3287 trm_long used_entries; /* populated codebook entries */
3289 /* the below are ordered by bitreversed codeword and only used
3290 entries are populated */
3291 int binarypoint;
3292 ogg_int32_t *valuelist; /* list of dim*entries actual entry values */
3293 ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */
3295 int *dec_index;
3296 char *dec_codelengths;
3297 ogg_uint32_t *dec_firsttable;
3298 int dec_firsttablen;
3299 int dec_maxlength;
3301 trm_long q_min; /* packed 32 bit float; quant value 0 maps to minval */
3302 trm_long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */
3306 /* unpacks a codebook from the packet buffer into the codebook struct,
3307 readies the codebook auxiliary structures for decode *************/
3308 static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
3309 trm_long i, j;
3310 static_codebook *s;
3311 s=cast(static_codebook *)ogg_calloc_(1, (*s).sizeof);
3313 /* make sure alignment is correct */
3314 if(oggpack_read(opb, 24)!=0x564342)goto eofout_;
3316 /* first the basic parameters */
3317 s.dim=oggpack_read(opb, 16);
3318 s.entries=oggpack_read(opb, 24);
3319 if(s.entries==-1)goto eofout_;
3321 if(ilog_(s.dim)+ilog_(s.entries)>24)goto eofout_;
3323 /* codeword ordering.... length ordered or unordered? */
3324 switch(cast(int)oggpack_read(opb, 1)){
3325 case 0:{
3326 trm_long unused;
3327 /* allocated but unused entries? */
3328 unused=oggpack_read(opb, 1);
3329 if((s.entries*(unused?1:5)+7)>>3>opb.storage-oggpack_bytes(opb))
3330 goto eofout_;
3331 /* unordered */
3332 s.lengthlist=cast(trm_long *)ogg_malloc_((*s.lengthlist).sizeof*s.entries);
3334 /* allocated but unused entries? */
3335 if(unused){
3336 /* yes, unused entries */
3338 for(i=0;i<s.entries;i++){
3339 if(oggpack_read(opb, 1)){
3340 trm_long num=oggpack_read(opb, 5);
3341 if(num==-1)goto eofout_;
3342 s.lengthlist[i]=num+1;
3343 }else
3344 s.lengthlist[i]=0;
3346 }else{
3347 /* all entries used; no tagging */
3348 for(i=0;i<s.entries;i++){
3349 trm_long num=oggpack_read(opb, 5);
3350 if(num==-1)goto eofout_;
3351 s.lengthlist[i]=num+1;
3355 break;
3357 case 1:
3358 /* ordered */
3360 trm_long length=oggpack_read(opb, 5)+1;
3361 if(length==0)goto eofout_;
3362 s.lengthlist=cast(trm_long *)ogg_malloc_((*s.lengthlist).sizeof*s.entries);
3364 for(i=0;i<s.entries;){
3365 trm_long num=oggpack_read(opb, ilog_(s.entries-i));
3366 if(num==-1)goto eofout_;
3367 if(length>32 || num>s.entries-i ||
3368 (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
3369 goto errout_;
3371 for(j=0;j<num;j++, i++)
3372 s.lengthlist[i]=length;
3373 length++;
3376 break;
3377 default:
3378 /* EOF */
3379 goto eofout_;
3382 /* Do we have a mapping to unpack? */
3383 switch((s.maptype=oggpack_read(opb, 4))){
3384 case 0:
3385 /* no mapping */
3386 break;
3387 case 1: case 2:
3388 /* implicitly populated value mapping */
3389 /* explicitly populated value mapping */
3391 s.q_min=oggpack_read(opb, 32);
3392 s.q_delta=oggpack_read(opb, 32);
3393 s.q_quant=oggpack_read(opb, 4)+1;
3394 s.q_sequencep=oggpack_read(opb, 1);
3395 if(s.q_sequencep==-1)goto eofout_;
3398 int quantvals=0;
3399 switch(s.maptype){
3400 case 1:
3401 quantvals=(s.dim==0?0:book_maptype1_quantvals_(s));
3402 break;
3403 case 2:
3404 quantvals=s.entries*s.dim;
3405 break;
3406 default: break;
3409 /* quantized values */
3410 if((quantvals*s.q_quant+7)>>3>opb.storage-oggpack_bytes(opb))
3411 goto eofout_;
3412 s.quantlist=cast(trm_long *)ogg_malloc_((*s.quantlist).sizeof*quantvals);
3413 for(i=0;i<quantvals;i++)
3414 s.quantlist[i]=oggpack_read(opb, s.q_quant);
3416 if(quantvals&&s.quantlist[quantvals-1]==-1)goto eofout_;
3418 break;
3419 default:
3420 goto errout_;
3423 /* all set */
3424 return(s);
3426 errout_:
3427 eofout_:
3428 vorbis_staticbook_destroy(s);
3429 return(null);
3432 /* the 'eliminate the decode tree' optimization actually requires the
3433 codewords to be MSb first, not LSb. This is an annoying inelegancy
3434 (and one of the first places where carefully thought out design
3435 turned out to be wrong; Vorbis II and future Ogg codecs should go
3436 to an MSb bitpacker), but not actually the huge hit it appears to
3437 be. The first-stage decode table catches most words so that
3438 bitreverse is not in the main execution path. */
3440 private ogg_uint32_t bitreverse(ogg_uint32_t x) nothrow @trusted @nogc {
3441 pragma(inline, true);
3442 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
3443 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
3444 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
3445 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
3446 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
3449 /*STIN*/ trm_long decode_packed_entry_number(codebook *book,
3450 oggpack_buffer *b) nothrow @trusted @nogc {
3451 int read=book.dec_maxlength;
3452 trm_long lo, hi;
3453 trm_long lok = oggpack_look(b, book.dec_firsttablen);
3455 if (lok >= 0) {
3456 trm_long entry = book.dec_firsttable[lok];
3457 if(entry&0x80000000U){
3458 lo=(entry>>15)&0x7fff;
3459 hi=book.used_entries-(entry&0x7fff);
3460 }else{
3461 oggpack_adv(b, book.dec_codelengths[entry-1]);
3462 return(entry-1);
3464 }else{
3465 lo=0;
3466 hi=book.used_entries;
3469 lok = oggpack_look(b, read);
3471 while(lok<0 && read>1)
3472 lok = oggpack_look(b, --read);
3474 if(lok<0){
3475 oggpack_adv(b, 1); /* force eop */
3476 return -1;
3479 /* bisect search for the codeword in the ordered list */
3481 ogg_uint32_t testword=bitreverse(cast(ogg_uint32_t)lok);
3483 while(hi-lo>1){
3484 trm_long p=(hi-lo)>>1;
3485 trm_long test=book.codelist[lo+p]>testword;
3486 lo+=p&(test-1);
3487 hi-=p&(-test);
3490 if(book.dec_codelengths[lo]<=read){
3491 oggpack_adv(b, book.dec_codelengths[lo]);
3492 return(lo);
3496 oggpack_adv(b, read+1);
3497 return(-1);
3500 /* Decode side is specced and easier, because we don't need to find
3501 matches using different criteria; we simply read and map. There are
3502 two things we need to do 'depending':
3504 We may need to support interleave. We don't really, but it's
3505 convenient to do it here rather than rebuild the vector later.
3507 Cascades may be additive or multiplicitive; this is not inherent in
3508 the codebook, but set in the code using the codebook. Like
3509 interleaving, it's easiest to do it here.
3510 addmul==0 . declarative (set the value)
3511 addmul==1 . additive
3512 addmul==2 . multiplicitive */
3514 /* returns the [original, not compacted] entry number or -1 on eof *********/
3515 trm_long vorbis_book_decode(codebook *book, oggpack_buffer *b) nothrow @trusted @nogc {
3516 if(book.used_entries>0){
3517 trm_long packed_entry=decode_packed_entry_number(book, b);
3518 if(packed_entry>=0)
3519 return(book.dec_index[packed_entry]);
3522 /* if there's no dec_index, the codebook unpacking isn't collapsed */
3523 return(-1);
3526 /* returns 0 on OK or -1 on eof *************************************/
3527 /* decode vector / dim granularity gaurding is done in the upper layer */
3528 trm_long vorbis_book_decodevs_add(codebook *book, ogg_int32_t *a,
3529 oggpack_buffer *b, int n, int point) nothrow @trusted @nogc {
3530 import core.stdc.stdlib : alloca;
3531 if(book.used_entries>0){
3532 int step=n/book.dim;
3533 trm_long *entry;
3534 entry = cast(trm_long *)alloca((*entry).sizeof*step);
3535 ogg_int32_t **t;
3536 t = cast(ogg_int32_t **)alloca((*t).sizeof*step);
3537 int i, j, o;
3538 int shift=point-book.binarypoint;
3540 if(shift>=0){
3541 for (i = 0; i < step; i++) {
3542 entry[i]=decode_packed_entry_number(book, b);
3543 if(entry[i]==-1)return(-1);
3544 t[i] = book.valuelist+entry[i]*book.dim;
3546 for(i=0, o=0;i<book.dim;i++, o+=step)
3547 for (j=0;j<step;j++)
3548 a[o+j]+=t[j][i]>>shift;
3549 }else{
3550 for (i = 0; i < step; i++) {
3551 entry[i]=decode_packed_entry_number(book, b);
3552 if(entry[i]==-1)return(-1);
3553 t[i] = book.valuelist+entry[i]*book.dim;
3555 for(i=0, o=0;i<book.dim;i++, o+=step)
3556 for (j=0;j<step;j++)
3557 a[o+j]+=t[j][i]<<-shift;
3560 return(0);
3563 /* decode vector / dim granularity gaurding is done in the upper layer */
3564 trm_long vorbis_book_decodev_add(codebook *book, ogg_int32_t *a,
3565 oggpack_buffer *b, int n, int point) nothrow @trusted @nogc {
3566 if(book.used_entries>0){
3567 int i, j, entry;
3568 ogg_int32_t *t;
3569 int shift=point-book.binarypoint;
3571 if(shift>=0){
3572 for(i=0;i<n;){
3573 entry = decode_packed_entry_number(book, b);
3574 if(entry==-1)return(-1);
3575 t = book.valuelist+entry*book.dim;
3576 for (j=0;j<book.dim;)
3577 a[i++]+=t[j++]>>shift;
3579 }else{
3580 for(i=0;i<n;){
3581 entry = decode_packed_entry_number(book, b);
3582 if(entry==-1)return(-1);
3583 t = book.valuelist+entry*book.dim;
3584 for (j=0;j<book.dim;)
3585 a[i++]+=t[j++]<<-shift;
3589 return(0);
3592 /* unlike the others, we guard against n not being an integer number
3593 of <dim> internally rather than in the upper layer (called only by
3594 floor0) */
3595 trm_long vorbis_book_decodev_set(codebook *book, ogg_int32_t *a,
3596 oggpack_buffer *b, int n, int point) nothrow @trusted @nogc {
3597 if(book.used_entries>0){
3598 int i, j, entry;
3599 ogg_int32_t *t;
3600 int shift=point-book.binarypoint;
3602 if(shift>=0){
3604 for(i=0;i<n;){
3605 entry = decode_packed_entry_number(book, b);
3606 if(entry==-1)return(-1);
3607 t = book.valuelist+entry*book.dim;
3608 for (j=0;i<n && j<book.dim;){
3609 a[i++]=t[j++]>>shift;
3612 }else{
3614 for(i=0;i<n;){
3615 entry = decode_packed_entry_number(book, b);
3616 if(entry==-1)return(-1);
3617 t = book.valuelist+entry*book.dim;
3618 for (j=0;i<n && j<book.dim;){
3619 a[i++]=t[j++]<<-shift;
3623 }else{
3625 int i, j;
3626 for(i=0;i<n;){
3627 a[i++]=0;
3630 return(0);
3633 /* decode vector / dim granularity gaurding is done in the upper layer */
3634 trm_long vorbis_book_decodevv_add(codebook *book, ogg_int32_t **a,
3635 trm_long offset, int ch,
3636 oggpack_buffer *b, int n, int point) nothrow @trusted @nogc {
3637 if(book.used_entries>0){
3638 trm_long i, j, entry;
3639 int chptr=0;
3640 int shift=point-book.binarypoint;
3642 if(shift>=0){
3644 for(i=offset;i<offset+n;){
3645 entry = decode_packed_entry_number(book, b);
3646 if(entry==-1)return(-1);
3648 const ogg_int32_t *t = book.valuelist+entry*book.dim;
3649 for (j=0;j<book.dim;j++){
3650 a[chptr++][i]+=t[j]>>shift;
3651 if(chptr==ch){
3652 chptr=0;
3653 i++;
3658 }else{
3660 for(i=offset;i<offset+n;){
3661 entry = decode_packed_entry_number(book, b);
3662 if(entry==-1)return(-1);
3664 const ogg_int32_t *t = book.valuelist+entry*book.dim;
3665 for (j=0;j<book.dim;j++){
3666 a[chptr++][i]+=t[j]<<-shift;
3667 if(chptr==ch){
3668 chptr=0;
3669 i++;
3676 return(0);
3680 /* ******************************************************************
3681 function: floor backend 0 implementation
3682 ****************************************************************** */
3683 enum LSP_FRACBITS = 14;
3685 struct vorbis_look_floor0 {
3686 trm_long n;
3687 int ln;
3688 int m;
3689 int *linearmap;
3691 vorbis_info_floor0 *vi;
3692 ogg_int32_t *lsp_look;
3695 /* ************* LSP decode ****************** */
3697 /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
3698 16.16 format
3699 returns in m.8 format */
3701 static immutable trm_long[2] ADJUST_SQRT2=[8192, 5792];
3703 /*STIN*/ ogg_int32_t vorbis_invsqlook_i(trm_long a, trm_long e) nothrow @trusted @nogc {
3704 pragma(inline, true);
3705 trm_long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
3706 trm_long d=a&INVSQ_LOOKUP_I_MASK; /* 0.10 */
3707 trm_long val=INVSQ_LOOKUP_I[i]- /* 1.16 */
3708 ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT); /* result 1.16 */
3709 val*=ADJUST_SQRT2[e&1];
3710 e=(e>>1)+21;
3711 return(val>>e);
3714 /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
3715 /* a is in n.12 format */
3716 /*STIN*/ ogg_int32_t vorbis_fromdBlook_i(trm_long a) nothrow @trusted @nogc {
3717 //pragma(inline, true);
3718 int i=(-a)>>(12-FROMdB2_SHIFT);
3719 if(i<0) return 0x7fffffff;
3720 if(i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))return 0;
3722 return FROMdB_LOOKUP[i>>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK];
3725 /* interpolated lookup based cos function, domain 0 to PI only */
3726 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
3727 /*STIN*/ ogg_int32_t vorbis_coslook_i(trm_long a) nothrow @trusted @nogc {
3728 pragma(inline, true);
3729 int i=a>>COS_LOOKUP_I_SHIFT;
3730 int d=a&COS_LOOKUP_I_MASK;
3731 return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
3732 COS_LOOKUP_I_SHIFT);
3735 /* interpolated lookup based cos function */
3736 /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
3737 /*STIN*/ ogg_int32_t vorbis_coslook2_i(trm_long a) nothrow @trusted @nogc {
3738 pragma(inline, true);
3739 a=a&0x1ffff;
3741 if(a>0x10000)a=0x20000-a;
3743 int i=a>>COS_LOOKUP_I_SHIFT;
3744 int d=a&COS_LOOKUP_I_MASK;
3745 a=((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
3746 d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
3747 (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
3750 return(a);
3753 static immutable int[28] barklook=[
3754 0,100,200,301, 405,516,635,766,
3755 912,1077,1263,1476, 1720,2003,2333,2721,
3756 3184,3742,4428,5285, 6376,7791,9662,12181,
3757 15624,20397,27087,36554
3760 /* used in init only; interpolate the trm_long way */
3761 /*STIN*/ ogg_int32_t toBARK(int n) nothrow @trusted @nogc {
3762 int i;
3763 for(i=0;i<27;i++)
3764 if(n>=barklook[i] && n<barklook[i+1])break;
3766 if(i==27){
3767 return 27<<15;
3768 }else{
3769 int gap=barklook[i+1]-barklook[i];
3770 int del=n-barklook[i];
3772 return((i<<15)+((del<<15)/gap));
3776 static immutable ubyte[64] MLOOP_1=[
3777 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
3778 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
3779 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
3780 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
3783 static immutable ubyte[64] MLOOP_2=[
3784 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
3785 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
3786 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
3787 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
3790 static immutable ubyte[8] MLOOP_3=[0,1,2,2,3,3,3,3];
3792 void vorbis_lsp_to_curve(ogg_int32_t *curve, int *map, int n, int ln,
3793 ogg_int32_t *lsp, int m,
3794 ogg_int32_t amp,
3795 ogg_int32_t ampoffset,
3796 ogg_int32_t *icos) nothrow @trusted @nogc
3798 import core.stdc.stdlib : alloca;
3799 /* 0 <= m < 256 */
3801 /* set up for using all int later */
3802 int i;
3803 int ampoffseti=ampoffset*4096;
3804 int ampi=amp;
3805 ogg_int32_t *ilsp;
3806 ilsp=cast(ogg_int32_t *)alloca(m*(*ilsp).sizeof);
3807 /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
3808 for(i=0;i<m;i++){
3809 version(LOW_ACCURACY__)
3810 ogg_int32_t val=((lsp[i]>>10)*0x517d)>>14;
3811 else
3812 ogg_int32_t val=MULT32(lsp[i], 0x517cc2);
3814 /* safeguard against a malicious stream */
3815 if(val<0 || (val>>COS_LOOKUP_I_SHIFT)>=COS_LOOKUP_I_SZ){
3816 memset(curve, 0, (*curve).sizeof*n);
3817 return;
3820 ilsp[i]=vorbis_coslook_i(val);
3823 i=0;
3824 while(i<n){
3825 int j, k=map[i];
3826 ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
3827 ogg_uint32_t qi=46341;
3828 ogg_int32_t qexp=0, shift;
3829 ogg_int32_t wi=icos[k];
3831 j=1;
3832 if(m>1){
3833 import std.math : labs = abs;
3834 qi*=labs(ilsp[0]-wi);
3835 pi*=labs(ilsp[1]-wi);
3837 for(j+=2;j<m;j+=2){
3838 if((shift=MLOOP_1[(pi|qi)>>25])==0)
3839 if((shift=MLOOP_2[(pi|qi)>>19])==0)
3840 shift=MLOOP_3[(pi|qi)>>16];
3841 qi=(qi>>shift)*labs(ilsp[j-1]-wi);
3842 pi=(pi>>shift)*labs(ilsp[j]-wi);
3843 qexp+=shift;
3846 if((shift=MLOOP_1[(pi|qi)>>25])==0)
3847 if((shift=MLOOP_2[(pi|qi)>>19])==0)
3848 shift=MLOOP_3[(pi|qi)>>16];
3850 /* pi, qi normalized collectively, both tracked using qexp */
3852 if(m&1){
3853 /* odd order filter; slightly assymetric */
3854 /* the last coefficient */
3855 import std.math : labs = abs;
3856 qi=(qi>>shift)*labs(ilsp[j-1]-wi);
3857 pi=(pi>>shift)<<14;
3858 qexp+=shift;
3860 if((shift=MLOOP_1[(pi|qi)>>25])==0)
3861 if((shift=MLOOP_2[(pi|qi)>>19])==0)
3862 shift=MLOOP_3[(pi|qi)>>16];
3864 pi>>=shift;
3865 qi>>=shift;
3866 qexp+=shift-14*((m+1)>>1);
3868 pi=((pi*pi)>>16);
3869 qi=((qi*qi)>>16);
3870 qexp=qexp*2+m;
3872 pi*=(1<<14)-((wi*wi)>>14);
3873 qi+=pi>>14;
3875 }else{
3876 /* even order filter; still symmetric */
3878 /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
3879 worth tracking step by step */
3881 pi>>=shift;
3882 qi>>=shift;
3883 qexp+=shift-7*m;
3885 pi=((pi*pi)>>16);
3886 qi=((qi*qi)>>16);
3887 qexp=qexp*2+m;
3889 pi*=(1<<14)-wi;
3890 qi*=(1<<14)+wi;
3891 qi=(qi+pi)>>14;
3896 /* we've let the normalization drift because it wasn't important;
3897 however, for the lookup, things must be normalized again. We
3898 need at most one right shift or a number of left shifts */
3900 if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
3901 qi>>=1; qexp++;
3902 }else
3903 while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
3904 qi<<=1; qexp--;
3907 amp=vorbis_fromdBlook_i(ampi* /* n.4 */
3908 vorbis_invsqlook_i(qi, qexp)-
3909 /* m.8, m+n<=8 */
3910 ampoffseti); /* 8.12[0] */
3912 version(LOW_ACCURACY__)
3913 amp>>=9;
3914 curve[i]= MULT31_SHIFT15(curve[i], amp);
3915 while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i], amp);
3919 /* ************* vorbis decode glue ********** */
3921 private void floor0_free_info(vorbis_info_floor *i) nothrow @trusted @nogc {
3922 vorbis_info_floor0 *info=cast(vorbis_info_floor0 *)i;
3923 if(info){
3924 memset(info, 0, (*info).sizeof);
3925 ogg_free_(info);
3929 private void floor0_free_look(vorbis_look_floor *i) nothrow @trusted @nogc {
3930 vorbis_look_floor0 *look=cast(vorbis_look_floor0 *)i;
3931 if(look){
3933 if(look.linearmap)ogg_free_(look.linearmap);
3934 if(look.lsp_look)ogg_free_(look.lsp_look);
3935 memset(look, 0, (*look).sizeof);
3936 ogg_free_(look);
3940 private vorbis_info_floor *floor0_unpack (vorbis_info *vi, oggpack_buffer *opb) nothrow @trusted @nogc {
3941 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
3942 int j;
3944 vorbis_info_floor0 *info;
3945 info=cast(vorbis_info_floor0 *)ogg_malloc_((*info).sizeof);
3946 info.order=oggpack_read(opb, 8);
3947 info.rate=oggpack_read(opb, 16);
3948 info.barkmap=oggpack_read(opb, 16);
3949 info.ampbits=oggpack_read(opb, 6);
3950 info.ampdB=oggpack_read(opb, 8);
3951 info.numbooks=oggpack_read(opb, 4)+1;
3953 if(info.order<1)goto err_out;
3954 if(info.rate<1)goto err_out;
3955 if(info.barkmap<1)goto err_out;
3956 if(info.numbooks<1)goto err_out;
3958 for(j=0;j<info.numbooks;j++){
3959 info.books[j]=oggpack_read(opb, 8);
3960 if(info.books[j]<0 || info.books[j]>=ci.books)goto err_out;
3961 if(ci.book_param[info.books[j]].maptype==0)goto err_out;
3962 if(ci.book_param[info.books[j]].dim<1)goto err_out;
3964 return(info);
3966 err_out:
3967 floor0_free_info(info);
3968 return(null);
3971 /* initialize Bark scale and normalization lookups. We could do this
3972 with static tables, but Vorbis allows a number of possible
3973 combinations, so it's best to do it computationally.
3975 The below is authoritative in terms of defining scale mapping.
3976 Note that the scale depends on the sampling rate as well as the
3977 linear block and mapping sizes */
3979 private vorbis_look_floor *floor0_look (vorbis_dsp_state *vd, vorbis_info_mode *mi,
3980 vorbis_info_floor *i) nothrow @trusted @nogc {
3981 int j;
3982 vorbis_info *vi=vd.vi;
3983 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
3984 vorbis_info_floor0 *info=cast(vorbis_info_floor0 *)i;
3985 vorbis_look_floor0 *look;
3986 look=cast(vorbis_look_floor0 *)ogg_calloc_(1, (*look).sizeof);
3987 look.m=info.order;
3988 look.n=ci.blocksizes[mi.blockflag]/2;
3989 look.ln=info.barkmap;
3990 look.vi=info;
3992 /* the mapping from a linear scale to a smaller bark scale is
3993 straightforward. We do *not* make sure that the linear mapping
3994 does not skip bark-scale bins; the decoder simply skips them and
3995 the encoder may do what it wishes in filling them. They're
3996 necessary in some mapping combinations to keep the scale spacing
3997 accurate */
3998 look.linearmap=cast(int *)ogg_malloc_((look.n+1)*(*look.linearmap).sizeof);
3999 for(j=0;j<look.n;j++){
4001 int val=(look.ln*
4002 ((toBARK(info.rate/2*j/look.n)<<11)/toBARK(info.rate/2)))>>11;
4004 if(val>=look.ln)val=look.ln-1; /* guard against the approximation */
4005 look.linearmap[j]=val;
4007 look.linearmap[j]=-1;
4009 look.lsp_look=cast(ogg_int32_t *)ogg_malloc_(look.ln*(*look.lsp_look).sizeof);
4010 for(j=0;j<look.ln;j++)
4011 look.lsp_look[j]=vorbis_coslook2_i(0x10000*j/look.ln);
4013 return look;
4016 private void *floor0_inverse1(vorbis_block *vb, vorbis_look_floor *i) nothrow @trusted @nogc {
4017 vorbis_look_floor0 *look=cast(vorbis_look_floor0 *)i;
4018 vorbis_info_floor0 *info=look.vi;
4019 int j, k;
4021 int ampraw=oggpack_read(&vb.opb, info.ampbits);
4022 if(ampraw>0){ /* also handles the -1 out of data case */
4023 trm_long maxval=(1<<info.ampbits)-1;
4024 int amp=((ampraw*info.ampdB)<<4)/maxval;
4025 int booknum=oggpack_read(&vb.opb, ilog_(info.numbooks));
4027 if(booknum!=-1 && booknum<info.numbooks){ /* be paranoid */
4028 codec_setup_info *ci=cast(codec_setup_info *)vb.vd.vi.codec_setup;
4029 codebook *b=ci.fullbooks+info.books[booknum];
4030 ogg_int32_t last=0;
4031 ogg_int32_t *lsp;
4032 lsp=cast(ogg_int32_t *)vorbis_block_alloc_(vb, (*lsp).sizeof*(look.m+1));
4034 if(vorbis_book_decodev_set(b, lsp, &vb.opb, look.m, -24)==-1)goto eop;
4035 for(j=0;j<look.m;){
4036 for(k=0;j<look.m && k<b.dim;k++, j++)lsp[j]+=last;
4037 last=lsp[j-1];
4040 lsp[look.m]=amp;
4041 return(lsp);
4044 eop:
4045 return(null);
4048 private int floor0_inverse2(vorbis_block *vb, vorbis_look_floor *i,
4049 void *memo, ogg_int32_t *out_) nothrow @trusted @nogc {
4050 vorbis_look_floor0 *look=cast(vorbis_look_floor0 *)i;
4051 vorbis_info_floor0 *info=look.vi;
4053 if(memo){
4054 ogg_int32_t *lsp=cast(ogg_int32_t *)memo;
4055 ogg_int32_t amp=lsp[look.m];
4057 /* take the coefficients back to a spectral envelope curve */
4058 vorbis_lsp_to_curve(out_, look.linearmap, look.n, look.ln,
4059 lsp, look.m, amp, info.ampdB, look.lsp_look);
4060 return(1);
4062 memset(out_, 0, (*out_).sizeof*look.n);
4063 return(0);
4066 /* export hooks */
4067 static immutable vorbis_func_floor floor0_exportbundle={
4068 &floor0_unpack, &floor0_look, &floor0_free_info,
4069 &floor0_free_look, &floor0_inverse1, &floor0_inverse2
4073 /* ******************************************************************
4074 function: floor backend 1 implementation
4075 ****************************************************************** */
4077 enum floor1_rangedB = 140; /* floor 1 fixed at -140dB to 0dB range */
4079 struct vorbis_look_floor1 {
4080 /*int*/usize[VIF_POSIT+2] forward_index;
4082 int[VIF_POSIT] hineighbor;
4083 int[VIF_POSIT] loneighbor;
4084 int posts;
4086 int n;
4087 int quant_q;
4088 vorbis_info_floor1 *vi;
4091 /* ******************************************* */
4093 private void floor1_free_info(vorbis_info_floor *i) nothrow @trusted @nogc {
4094 vorbis_info_floor1 *info=cast(vorbis_info_floor1 *)i;
4095 if(info){
4096 memset(info, 0, (*info).sizeof);
4097 ogg_free_(info);
4101 private void floor1_free_look(vorbis_look_floor *i) nothrow @trusted @nogc {
4102 vorbis_look_floor1 *look=cast(vorbis_look_floor1 *)i;
4103 if(look){
4104 memset(look, 0, (*look).sizeof);
4105 ogg_free_(look);
4109 static int flr_ilog(uint v) nothrow @trusted @nogc {
4110 int ret=0;
4111 while(v){
4112 ret++;
4113 v>>=1;
4115 return(ret);
4118 private extern(C) int icomp(in void *a, in void *b) nothrow @trusted @nogc {
4119 return(**cast(int **)a-**cast(int **)b);
4122 private vorbis_info_floor *floor1_unpack (vorbis_info *vi, oggpack_buffer *opb) nothrow @trusted @nogc {
4123 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
4124 int j, k, count=0, maxclass=-1, rangebits;
4126 vorbis_info_floor1 *info;
4127 info=cast(vorbis_info_floor1 *)ogg_calloc_(1, (*info).sizeof);
4128 /* read partitions */
4129 info.partitions=oggpack_read(opb, 5); /* only 0 to 31 legal */
4130 for(j=0;j<info.partitions;j++){
4131 info.partitionclass[j]=oggpack_read(opb, 4); /* only 0 to 15 legal */
4132 if(info.partitionclass[j]<0)goto err_out;
4133 if(maxclass<info.partitionclass[j])maxclass=info.partitionclass[j];
4136 /* read partition classes */
4137 for(j=0;j<maxclass+1;j++){
4138 info.class_dim[j]=oggpack_read(opb, 3)+1; /* 1 to 8 */
4139 info.class_subs[j]=oggpack_read(opb, 2); /* 0,1,2,3 bits */
4140 if(info.class_subs[j]<0)
4141 goto err_out;
4142 if(info.class_subs[j])info.class_book[j]=oggpack_read(opb, 8);
4143 if(info.class_book[j]<0 || info.class_book[j]>=ci.books)
4144 goto err_out;
4145 for(k=0;k<(1<<info.class_subs[j]);k++){
4146 info.class_subbook[j][k]=oggpack_read(opb, 8)-1;
4147 if(info.class_subbook[j][k]<-1 || info.class_subbook[j][k]>=ci.books)
4148 goto err_out;
4152 /* read the post list */
4153 info.mult=oggpack_read(opb, 2)+1; /* only 1,2,3,4 legal now */
4154 rangebits=oggpack_read(opb, 4);
4155 if(rangebits<0)goto err_out;
4157 for(j=0, k=0;j<info.partitions;j++){
4158 count+=info.class_dim[info.partitionclass[j]];
4159 if(count>VIF_POSIT)goto err_out;
4160 for(;k<count;k++){
4161 int t=info.postlist[k+2]=oggpack_read(opb, rangebits);
4162 if(t<0 || t>=(1<<rangebits))
4163 goto err_out;
4166 info.postlist[0]=0;
4167 info.postlist[1]=1<<rangebits;
4169 /* don't allow repeated values in post list as they'd result in
4170 zero-length segments */
4172 int*[VIF_POSIT+2] sortpointer;
4173 for(j=0;j<count+2;j++)sortpointer[j]=info.postlist.ptr+j;
4174 qsort(sortpointer.ptr, count+2, (sortpointer[0]).sizeof, &icomp);
4176 for(j=1;j<count+2;j++)
4177 if(*sortpointer[j-1]==*sortpointer[j])goto err_out;
4180 return(info);
4182 err_out:
4183 floor1_free_info(info);
4184 return(null);
4187 private vorbis_look_floor *floor1_look(vorbis_dsp_state *vd, vorbis_info_mode *mi,
4188 vorbis_info_floor *in_) nothrow @trusted @nogc {
4190 int*[VIF_POSIT+2] sortpointer;
4191 vorbis_info_floor1 *info=cast(vorbis_info_floor1 *)in_;
4192 vorbis_look_floor1 *look;
4193 look=cast(vorbis_look_floor1 *)ogg_calloc_(1, (*look).sizeof);
4194 int i, j, n=0;
4196 look.vi=info;
4197 look.n=info.postlist[1];
4199 /* we drop each position value in-between already decoded values,
4200 and use linear interpolation to predict each new value past the
4201 edges. The positions are read in the order of the position
4202 list... we precompute the bounding positions in the lookup. Of
4203 course, the neighbors can change (if a position is declined), but
4204 this is an initial mapping */
4206 for(i=0;i<info.partitions;i++)n+=info.class_dim[info.partitionclass[i]];
4207 n+=2;
4208 look.posts=n;
4210 /* also store a sorted position index */
4211 for(i=0;i<n;i++)sortpointer[i]=info.postlist.ptr+i;
4212 qsort(sortpointer.ptr, n, (sortpointer[0]).sizeof, &icomp);
4214 /* points from sort order back to range number */
4215 for(i=0;i<n;i++)look.forward_index[i]=sortpointer[i]-info.postlist.ptr;
4217 /* quantize values to multiplier spec */
4218 switch(info.mult){
4219 case 1: /* 1024 . 256 */
4220 look.quant_q=256;
4221 break;
4222 case 2: /* 1024 . 128 */
4223 look.quant_q=128;
4224 break;
4225 case 3: /* 1024 . 86 */
4226 look.quant_q=86;
4227 break;
4228 case 4: /* 1024 . 64 */
4229 look.quant_q=64;
4230 break;
4231 default: break;
4234 /* discover our neighbors for decode where we don't use fit flags
4235 (that would push the neighbors outward) */
4236 for(i=0;i<n-2;i++){
4237 int lo=0;
4238 int hi=1;
4239 int lx=0;
4240 int hx=look.n;
4241 int currentx=info.postlist[i+2];
4242 for(j=0;j<i+2;j++){
4243 int x=info.postlist[j];
4244 if(x>lx && x<currentx){
4245 lo=j;
4246 lx=x;
4248 if(x<hx && x>currentx){
4249 hi=j;
4250 hx=x;
4253 look.loneighbor[i]=lo;
4254 look.hineighbor[i]=hi;
4257 return(look);
4260 private int render_point(int x0, int x1, int y0, int y1, int x) nothrow @trusted @nogc {
4261 y0&=0x7fff; /* mask off flag */
4262 y1&=0x7fff;
4265 import std.math : abs;
4266 int dy=y1-y0;
4267 int adx=x1-x0;
4268 int ady=abs(dy);
4269 int err=ady*(x-x0);
4271 int off=err/adx;
4272 if(dy<0)return(y0-off);
4273 return(y0+off);
4277 version(LOW_ACCURACY__) {
4278 private ogg_int32_t XdB (ogg_int32_t n) pure nothrow @safe @nogc { return ((((n)>>8)+1)>>1); }
4279 } else {
4280 private ogg_int32_t XdB (ogg_int32_t n) pure nothrow @safe @nogc { return n; }
4283 static immutable ogg_int32_t[256] FLOOR_fromdB_LOOKUP=[
4284 XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114),
4285 XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163),
4286 XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9),
4287 XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c),
4288 XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4),
4289 XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd),
4290 XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4),
4291 XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a),
4292 XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818),
4293 XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69),
4294 XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64),
4295 XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a),
4296 XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629),
4297 XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82),
4298 XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac),
4299 XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c),
4300 XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf),
4301 XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10),
4302 XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b),
4303 XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e),
4304 XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d),
4305 XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4),
4306 XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd),
4307 XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf),
4308 XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e),
4309 XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962),
4310 XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109),
4311 XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4),
4312 XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23),
4313 XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306),
4314 XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20),
4315 XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6),
4316 XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471),
4317 XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1),
4318 XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7),
4319 XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d),
4320 XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1),
4321 XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc),
4322 XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2),
4323 XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488),
4324 XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0),
4325 XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f),
4326 XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41),
4327 XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17),
4328 XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e),
4329 XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7),
4330 XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf),
4331 XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea),
4332 XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793),
4333 XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2),
4334 XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013),
4335 XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204),
4336 XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299),
4337 XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e),
4338 XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca),
4339 XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea),
4340 XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1),
4341 XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1),
4342 XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870),
4343 XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6),
4344 XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44),
4345 XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e),
4346 XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298),
4347 XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff),
4350 private void render_line(int n, int x0, int x1, int y0, int y1, ogg_int32_t *d) nothrow @trusted @nogc {
4351 import std.math : abs;
4352 int dy=y1-y0;
4353 int adx=x1-x0;
4354 int ady=abs(dy);
4355 int base=dy/adx;
4356 int sy=(dy<0?base-1:base+1);
4357 int x=x0;
4358 int y=y0;
4359 int err=0;
4361 if(n>x1)n=x1;
4362 ady-=abs(base*adx);
4364 if(x<n)
4365 d[x]= MULT31_SHIFT15(d[x], FLOOR_fromdB_LOOKUP[y]);
4367 while(++x<n){
4368 err=err+ady;
4369 if(err>=adx){
4370 err-=adx;
4371 y+=sy;
4372 }else{
4373 y+=base;
4375 d[x]= MULT31_SHIFT15(d[x], FLOOR_fromdB_LOOKUP[y]);
4379 private void *floor1_inverse1(vorbis_block *vb, vorbis_look_floor *in_) nothrow @trusted @nogc {
4380 vorbis_look_floor1 *look=cast(vorbis_look_floor1 *)in_;
4381 vorbis_info_floor1 *info=look.vi;
4382 codec_setup_info *ci=cast(codec_setup_info *)vb.vd.vi.codec_setup;
4384 int i, j, k;
4385 codebook *books=ci.fullbooks;
4387 /* unpack wrapped/predicted values from stream */
4388 if(oggpack_read(&vb.opb, 1)==1){
4389 int *fit_value;
4390 fit_value=cast(int *)vorbis_block_alloc_(vb, (look.posts)*(*fit_value).sizeof);
4392 fit_value[0]=oggpack_read(&vb.opb, flr_ilog(look.quant_q-1));
4393 fit_value[1]=oggpack_read(&vb.opb, flr_ilog(look.quant_q-1));
4395 /* partition by partition */
4396 /* partition by partition */
4397 for(i=0, j=2;i<info.partitions;i++){
4398 int classv=info.partitionclass[i];
4399 int cdim=info.class_dim[classv];
4400 int csubbits=info.class_subs[classv];
4401 int csub=1<<csubbits;
4402 int cval=0;
4404 /* decode the partition's first stage cascade value */
4405 if(csubbits){
4406 cval=vorbis_book_decode(books+info.class_book[classv], &vb.opb);
4408 if(cval==-1)goto eop;
4411 for(k=0;k<cdim;k++){
4412 int book=info.class_subbook[classv][cval&(csub-1)];
4413 cval>>=csubbits;
4414 if(book>=0){
4415 if((fit_value[j+k]=vorbis_book_decode(books+book, &vb.opb))==-1)
4416 goto eop;
4417 }else{
4418 fit_value[j+k]=0;
4421 j+=cdim;
4424 /* unwrap positive values and reconsitute via linear interpolation */
4425 for(i=2;i<look.posts;i++){
4426 int predicted=render_point(info.postlist[look.loneighbor[i-2]],
4427 info.postlist[look.hineighbor[i-2]],
4428 fit_value[look.loneighbor[i-2]],
4429 fit_value[look.hineighbor[i-2]],
4430 info.postlist[i]);
4431 int hiroom=look.quant_q-predicted;
4432 int loroom=predicted;
4433 int room=(hiroom<loroom?hiroom:loroom)<<1;
4434 int val=fit_value[i];
4436 if(val){
4437 if(val>=room){
4438 if(hiroom>loroom){
4439 val = val-loroom;
4440 }else{
4441 val = -1-(val-hiroom);
4443 }else{
4444 if(val&1){
4445 val= -((val+1)>>1);
4446 }else{
4447 val>>=1;
4451 fit_value[i]=(val+predicted)&0x7fff;
4452 fit_value[look.loneighbor[i-2]]&=0x7fff;
4453 fit_value[look.hineighbor[i-2]]&=0x7fff;
4455 }else{
4456 fit_value[i]=predicted|0x8000;
4461 return(fit_value);
4463 eop:
4464 return(null);
4467 private int floor1_inverse2(vorbis_block *vb, vorbis_look_floor *in_, void *memo,
4468 ogg_int32_t *out_) nothrow @trusted @nogc {
4469 vorbis_look_floor1 *look=cast(vorbis_look_floor1 *)in_;
4470 vorbis_info_floor1 *info=look.vi;
4472 codec_setup_info *ci=cast(codec_setup_info *)vb.vd.vi.codec_setup;
4473 int n=ci.blocksizes[vb.W]/2;
4474 int j;
4476 if(memo){
4477 /* render the lines */
4478 int *fit_value=cast(int *)memo;
4479 int hx=0;
4480 int lx=0;
4481 int ly=fit_value[0]*info.mult;
4482 /* guard lookup against out-of-range values */
4483 ly=(ly<0?0:ly>255?255:ly);
4485 for(j=1;j<look.posts;j++){
4486 auto current=look.forward_index[j];
4487 int hy=fit_value[current]&0x7fff;
4488 if(hy==fit_value[current]){
4490 hx=info.postlist[current];
4491 hy*=info.mult;
4492 /* guard lookup against out-of-range values */
4493 hy=(hy<0?0:hy>255?255:hy);
4495 render_line(n, lx, hx, ly, hy, out_);
4497 lx=hx;
4498 ly=hy;
4501 for(j=hx;j<n;j++)out_[j]*=ly; /* be certain */
4502 return(1);
4504 memset(out_, 0, (*out_).sizeof*n);
4505 return(0);
4508 /* export hooks */
4509 static immutable vorbis_func_floor floor1_exportbundle={
4510 &floor1_unpack, &floor1_look, &floor1_free_info,
4511 &floor1_free_look, &floor1_inverse1, &floor1_inverse2
4515 /* ******************************************************************
4516 function: maintain the info structure, info <. header packets
4517 ****************************************************************** */
4519 /* helpers */
4520 private void v_readstring_(oggpack_buffer *o, char *buf, int bytes){
4521 while(bytes--){
4522 *buf++=cast(char)oggpack_read(o, 8);
4526 /* Header packing/unpacking ********************************************/
4528 private int vorbis_unpack_info_(vorbis_info *vi, oggpack_buffer *opb){
4529 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
4530 if(!ci)return(OV_EFAULT);
4532 vi.ver=oggpack_read(opb, 32);
4533 if(vi.ver!=0)return(OV_EVERSION);
4535 vi.channels=oggpack_read(opb, 8);
4536 vi.rate=oggpack_read(opb, 32);
4538 vi.bitrate_upper=oggpack_read(opb, 32);
4539 vi.bitrate_nominal=oggpack_read(opb, 32);
4540 vi.bitrate_lower=oggpack_read(opb, 32);
4542 ci.blocksizes[0]=1<<oggpack_read(opb, 4);
4543 ci.blocksizes[1]=1<<oggpack_read(opb, 4);
4545 if(vi.rate<1)goto err_out;
4546 if(vi.channels<1)goto err_out;
4547 if(ci.blocksizes[0]<64)goto err_out;
4548 if(ci.blocksizes[1]<ci.blocksizes[0])goto err_out;
4549 if(ci.blocksizes[1]>8192)goto err_out;
4551 if(oggpack_read(opb, 1)!=1)goto err_out; /* EOP check */
4553 return(0);
4554 err_out:
4555 vorbis_info_clear(vi);
4556 return(OV_EBADHEADER);
4559 private int vorbis_unpack_comment_(vorbis_comment *vc, oggpack_buffer *opb){
4560 int i;
4561 int vendorlen;
4562 vendorlen=oggpack_read(opb, 32);
4563 if(vendorlen<0)goto err_out;
4564 if(vendorlen>opb.storage-oggpack_bytes(opb))goto err_out;
4565 vc.vendor=cast(char *)ogg_calloc_(vendorlen+1, 1);
4566 if(vc.vendor==null)goto err_out;
4567 v_readstring_(opb, vc.vendor, vendorlen);
4568 i=oggpack_read(opb, 32);
4569 if(i<0||i>=int.max||i>(opb.storage-oggpack_bytes(opb))>>2)goto err_out;
4570 vc.user_comments=cast(char **)ogg_calloc_(i+1, (*vc.user_comments).sizeof);
4571 vc.comment_lengths=cast(int *)ogg_calloc_(i+1, (*vc.comment_lengths).sizeof);
4572 if(vc.user_comments==null||vc.comment_lengths==null)goto err_out;
4573 vc.comments=i;
4575 for(i=0;i<vc.comments;i++){
4576 int len=oggpack_read(opb, 32);
4577 if(len<0||len>opb.storage-oggpack_bytes(opb))goto err_out;
4578 vc.comment_lengths[i]=len;
4579 vc.user_comments[i]=cast(char *)ogg_calloc_(len+1, 1);
4580 if(vc.user_comments[i]==null){
4581 vc.comments=i;
4582 goto err_out;
4584 v_readstring_(opb, vc.user_comments[i], len);
4586 if(oggpack_read(opb, 1)!=1)goto err_out; /* EOP check */
4588 return(0);
4589 err_out:
4590 vorbis_comment_clear(vc);
4591 return(OV_EBADHEADER);
4594 /* all of the real encoding details are here. The modes, books,
4595 everything */
4596 private int vorbis_unpack_books_(vorbis_info *vi, oggpack_buffer *opb){
4597 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
4598 int i;
4599 if(!ci)return(OV_EFAULT);
4601 /* codebooks */
4602 ci.books=oggpack_read(opb, 8)+1;
4603 if(ci.books<=0)goto err_out;
4604 for(i=0;i<ci.books;i++){
4605 ci.book_param[i]=vorbis_staticbook_unpack(opb);
4606 if(!ci.book_param[i])goto err_out;
4609 /* time backend settings */
4610 ci.times=oggpack_read(opb, 6)+1;
4611 if(ci.times<=0)goto err_out;
4612 for(i=0;i<ci.times;i++){
4613 ci.time_type[i]=oggpack_read(opb, 16);
4614 if(ci.time_type[i]<0 || ci.time_type[i]>=VI_TIMEB)goto err_out;
4615 /* ci.time_param[i]=time_P_[ci.time_type[i]].unpack(vi, opb);
4616 Vorbis I has no time backend */
4617 /*if(!ci.time_param[i])goto err_out;*/
4620 /* floor backend settings */
4621 ci.floors=oggpack_read(opb, 6)+1;
4622 if(ci.floors<=0)goto err_out;
4623 for(i=0;i<ci.floors;i++){
4624 ci.floor_type[i]=oggpack_read(opb, 16);
4625 if(ci.floor_type[i]<0 || ci.floor_type[i]>=VI_FLOORB)goto err_out;
4626 ci.floor_param[i]=floor_P_[ci.floor_type[i]].unpack(vi, opb);
4627 if(!ci.floor_param[i])goto err_out;
4630 /* residue backend settings */
4631 ci.residues=oggpack_read(opb, 6)+1;
4632 if(ci.residues<=0)goto err_out;
4633 for(i=0;i<ci.residues;i++){
4634 ci.residue_type[i]=oggpack_read(opb, 16);
4635 if(ci.residue_type[i]<0 || ci.residue_type[i]>=VI_RESB)goto err_out;
4636 ci.residue_param[i]=residue_P_[ci.residue_type[i]].unpack(vi, opb);
4637 if(!ci.residue_param[i])goto err_out;
4640 /* map backend settings */
4641 ci.maps=oggpack_read(opb, 6)+1;
4642 if(ci.maps<=0)goto err_out;
4643 for(i=0;i<ci.maps;i++){
4644 ci.map_type[i]=oggpack_read(opb, 16);
4645 if(ci.map_type[i]<0 || ci.map_type[i]>=VI_MAPB)goto err_out;
4646 ci.map_param[i]=mapping_P_[ci.map_type[i]].unpack(vi, opb);
4647 if(!ci.map_param[i])goto err_out;
4650 /* mode settings */
4651 ci.modes=oggpack_read(opb, 6)+1;
4652 if(ci.modes<=0)goto err_out;
4653 for(i=0;i<ci.modes;i++){
4654 ci.mode_param[i]=cast(vorbis_info_mode *)ogg_calloc_(1, (*ci.mode_param[i]).sizeof);
4655 ci.mode_param[i].blockflag=oggpack_read(opb, 1);
4656 ci.mode_param[i].windowtype=oggpack_read(opb, 16);
4657 ci.mode_param[i].transformtype=oggpack_read(opb, 16);
4658 ci.mode_param[i].mapping=oggpack_read(opb, 8);
4660 if(ci.mode_param[i].windowtype>=VI_WINDOWB)goto err_out;
4661 if(ci.mode_param[i].transformtype>=VI_WINDOWB)goto err_out;
4662 if(ci.mode_param[i].mapping>=ci.maps)goto err_out;
4663 if(ci.mode_param[i].mapping<0)goto err_out;
4666 if(oggpack_read(opb, 1)!=1)goto err_out; /* top level EOP check */
4668 return(0);
4669 err_out:
4670 vorbis_info_clear(vi);
4671 return(OV_EBADHEADER);
4674 /* Is this packet a vorbis ID header? */
4675 int vorbis_synthesis_idheader(ogg_packet *op){
4676 oggpack_buffer opb;
4677 char[6] buffer=void;
4679 if(op){
4680 oggpack_readinit(&opb, op.packet, op.bytes);
4682 if(!op.b_o_s)
4683 return(0); /* Not the initial packet */
4685 if(oggpack_read(&opb, 8) != 1)
4686 return 0; /* not an ID header */
4688 memset(buffer.ptr, 0, 6);
4689 v_readstring_(&opb, buffer.ptr, 6);
4690 if(memcmp(buffer.ptr, "vorbis".ptr, 6))
4691 return 0; /* not vorbis */
4693 return 1;
4696 return 0;
4699 /* The Vorbis header is in three packets; the initial small packet in
4700 the first page that identifies basic parameters, a second packet
4701 with bitstream comments and a third packet that holds the
4702 codebook. */
4704 int vorbis_synthesis_headerin(vorbis_info *vi, vorbis_comment *vc, ogg_packet *op){
4705 oggpack_buffer opb;
4707 if(op){
4708 oggpack_readinit(&opb, op.packet, op.bytes);
4710 /* Which of the three types of header is this? */
4711 /* Also verify header-ness, vorbis */
4713 char[6] buffer=void;
4714 int packtype=oggpack_read(&opb, 8);
4715 memset(buffer.ptr, 0, 6);
4716 v_readstring_(&opb, buffer.ptr, 6);
4717 if(memcmp(buffer.ptr, "vorbis".ptr, 6)){
4718 /* not a vorbis header */
4719 return(OV_ENOTVORBIS);
4721 switch(packtype){
4722 case 0x01: /* least significant *bit* is read first */
4723 if(!op.b_o_s){
4724 /* Not the initial packet */
4725 return(OV_EBADHEADER);
4727 if(vi.rate!=0){
4728 /* previously initialized info header */
4729 return(OV_EBADHEADER);
4732 return(vorbis_unpack_info_(vi, &opb));
4734 case 0x03: /* least significant *bit* is read first */
4735 if(vi.rate==0){
4736 /* um... we didn't get the initial header */
4737 return(OV_EBADHEADER);
4740 return(vorbis_unpack_comment_(vc, &opb));
4742 case 0x05: /* least significant *bit* is read first */
4743 if(vi.rate==0 || vc.vendor==null){
4744 /* um... we didn;t get the initial header or comments yet */
4745 return(OV_EBADHEADER);
4748 return(vorbis_unpack_books_(vi, &opb));
4750 default:
4751 /* Not a valid vorbis header type */
4752 return(OV_EBADHEADER);
4753 break;
4757 return(OV_EBADHEADER);
4761 /* ******************************************************************
4762 function: channel mapping 0 implementation
4763 ****************************************************************** */
4765 /* simplistic, wasteful way of doing this (unique lookup for each
4766 mode/submapping); there should be a central repository for
4767 identical lookups. That will require minor work, so I'm putting it
4768 off as low priority.
4770 Why a lookup for each backend in a given mode? Because the
4771 blocksize is set by the mode, and low backend lookups may require
4772 parameters from other areas of the mode/mapping */
4774 struct vorbis_look_mapping0 {
4775 vorbis_info_mode *mode;
4776 vorbis_info_mapping0 *map;
4778 vorbis_look_floor **floor_look;
4780 vorbis_look_residue **residue_look;
4782 vorbis_func_floor **floor_func;
4783 vorbis_func_residue **residue_func;
4785 int ch;
4786 trm_long lastframe; /* if a different mode is called, we need to
4787 invalidate decay */
4790 private void mapping0_free_info(vorbis_info_mapping *i) nothrow @trusted @nogc {
4791 vorbis_info_mapping0 *info=cast(vorbis_info_mapping0 *)i;
4792 if(info){
4793 memset(info, 0, (*info).sizeof);
4794 ogg_free_(info);
4798 private void mapping0_free_look(vorbis_look_mapping *look) nothrow @trusted @nogc {
4799 int i;
4800 vorbis_look_mapping0 *l=cast(vorbis_look_mapping0 *)look;
4801 if(l){
4803 for(i=0;i<l.map.submaps;i++){
4804 l.floor_func[i].free_look(l.floor_look[i]);
4805 l.residue_func[i].free_look(l.residue_look[i]);
4808 ogg_free_(l.floor_func);
4809 ogg_free_(l.residue_func);
4810 ogg_free_(l.floor_look);
4811 ogg_free_(l.residue_look);
4812 memset(l, 0, (*l).sizeof);
4813 ogg_free_(l);
4817 private vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd, vorbis_info_mode *vm,
4818 vorbis_info_mapping *m) nothrow @trusted @nogc {
4819 int i;
4820 vorbis_info *vi=vd.vi;
4821 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
4822 vorbis_look_mapping0 *look;
4823 look=cast(vorbis_look_mapping0 *)ogg_calloc_(1, (*look).sizeof);
4824 vorbis_info_mapping0 *info=look.map=cast(vorbis_info_mapping0 *)m;
4825 look.mode=vm;
4827 look.floor_look=cast(vorbis_look_floor **)ogg_calloc_(info.submaps, (*look.floor_look).sizeof);
4829 look.residue_look=cast(vorbis_look_residue **)ogg_calloc_(info.submaps, (*look.residue_look).sizeof);
4831 look.floor_func=cast(vorbis_func_floor **)ogg_calloc_(info.submaps, (*look.floor_func).sizeof);
4832 look.residue_func=cast(vorbis_func_residue **)ogg_calloc_(info.submaps, (*look.residue_func).sizeof);
4834 for(i=0;i<info.submaps;i++){
4835 int floornum=info.floorsubmap[i];
4836 int resnum=info.residuesubmap[i];
4838 look.floor_func[i]=cast(vorbis_func_floor*)(floor_P_[ci.floor_type[floornum]]);
4839 look.floor_look[i]=look.floor_func[i].look(vd, vm, ci.floor_param[floornum]);
4840 look.residue_func[i]=cast(vorbis_func_residue*)residue_P_[ci.residue_type[resnum]];
4841 look.residue_look[i]=look.residue_func[i].
4842 look(vd, vm, ci.residue_param[resnum]);
4846 look.ch=vi.channels;
4848 return(look);
4851 private int mapping_ilog(uint v) nothrow @trusted @nogc {
4852 int ret=0;
4853 if(v)--v;
4854 while(v){
4855 ret++;
4856 v>>=1;
4858 return(ret);
4861 /* also responsible for range checking */
4862 private vorbis_info_mapping *mapping0_unpack(vorbis_info *vi, oggpack_buffer *opb) nothrow @trusted @nogc {
4863 import core.stdc.stdlib : alloca;
4864 int i, b;
4865 vorbis_info_mapping0 *info;
4866 info=cast(vorbis_info_mapping0 *)ogg_calloc_(1, (*info).sizeof);
4867 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
4868 memset(info, 0, (*info).sizeof);
4870 b=oggpack_read(opb, 1);
4871 if(b<0)goto err_out;
4872 if(b){
4873 info.submaps=oggpack_read(opb, 4)+1;
4874 if(info.submaps<=0)goto err_out;
4875 }else
4876 info.submaps=1;
4878 b=oggpack_read(opb, 1);
4879 if(b<0)goto err_out;
4880 if(b){
4881 info.coupling_steps=oggpack_read(opb, 8)+1;
4882 if(info.coupling_steps<=0)goto err_out;
4883 for(i=0;i<info.coupling_steps;i++){
4884 int testM=info.coupling_mag[i]=oggpack_read(opb, mapping_ilog(vi.channels));
4885 int testA=info.coupling_ang[i]=oggpack_read(opb, mapping_ilog(vi.channels));
4887 if(testM<0 ||
4888 testA<0 ||
4889 testM==testA ||
4890 testM>=vi.channels ||
4891 testA>=vi.channels) goto err_out;
4896 if(oggpack_read(opb, 2)!=0)goto err_out; /* 2,3:reserved */
4898 if(info.submaps>1){
4899 for(i=0;i<vi.channels;i++){
4900 info.chmuxlist[i]=oggpack_read(opb, 4);
4901 if(info.chmuxlist[i]>=info.submaps || info.chmuxlist[i]<0)goto err_out;
4904 for(i=0;i<info.submaps;i++){
4905 int temp=oggpack_read(opb, 8);
4906 if(temp>=ci.times)goto err_out;
4907 info.floorsubmap[i]=oggpack_read(opb, 8);
4908 if(info.floorsubmap[i]>=ci.floors || info.floorsubmap[i]<0)goto err_out;
4909 info.residuesubmap[i]=oggpack_read(opb, 8);
4910 if(info.residuesubmap[i]>=ci.residues || info.residuesubmap[i]<0)
4911 goto err_out;
4914 return info;
4916 err_out:
4917 mapping0_free_info(info);
4918 return(null);
4921 //static int seq=0;
4922 private int mapping0_inverse(vorbis_block *vb, vorbis_look_mapping *l) nothrow @trusted @nogc {
4923 import core.stdc.stdlib : alloca;
4924 vorbis_dsp_state *vd=vb.vd;
4925 vorbis_info *vi=vd.vi;
4926 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
4927 private_state *b=cast(private_state *)vd.backend_state;
4928 vorbis_look_mapping0 *look=cast(vorbis_look_mapping0 *)l;
4929 vorbis_info_mapping0 *info=look.map;
4931 int i, j;
4932 trm_long n=vb.pcmend=ci.blocksizes[vb.W];
4934 ogg_int32_t **pcmbundle;
4935 pcmbundle=cast(ogg_int32_t **)alloca((*pcmbundle).sizeof*vi.channels);
4936 int* zerobundle;
4937 zerobundle=cast(int *)alloca((*zerobundle).sizeof*vi.channels);
4939 int* nonzero;
4940 nonzero=cast(int *)alloca((*nonzero).sizeof*vi.channels);
4941 void **floormemo;
4942 floormemo=cast(void **)alloca((*floormemo).sizeof*vi.channels);
4944 /* time domain information decode (note that applying the
4945 information would have to happen later; we'll probably add a
4946 function entry to the harness for that later */
4947 /* NOT IMPLEMENTED */
4949 /* recover the spectral envelope; store it in the PCM vector for now */
4950 for(i=0;i<vi.channels;i++){
4951 int submap=info.chmuxlist[i];
4952 floormemo[i]=look.floor_func[submap].
4953 inverse1(vb, look.floor_look[submap]);
4954 if(floormemo[i])
4955 nonzero[i]=1;
4956 else
4957 nonzero[i]=0;
4958 memset(vb.pcm[i], 0, (*vb.pcm[i]).sizeof*n/2);
4961 /* channel coupling can 'dirty' the nonzero listing */
4962 for(i=0;i<info.coupling_steps;i++){
4963 if(nonzero[info.coupling_mag[i]] ||
4964 nonzero[info.coupling_ang[i]]){
4965 nonzero[info.coupling_mag[i]]=1;
4966 nonzero[info.coupling_ang[i]]=1;
4970 /* recover the residue into our working vectors */
4971 for(i=0;i<info.submaps;i++){
4972 int ch_in_bundle=0;
4973 for(j=0;j<vi.channels;j++){
4974 if(info.chmuxlist[j]==i){
4975 if(nonzero[j])
4976 zerobundle[ch_in_bundle]=1;
4977 else
4978 zerobundle[ch_in_bundle]=0;
4979 pcmbundle[ch_in_bundle++]=vb.pcm[j];
4983 look.residue_func[i].inverse(vb, look.residue_look[i], pcmbundle, zerobundle, ch_in_bundle);
4986 //for(j=0;j<vi.channels;j++)
4987 //analysis_output_("coupled", seq+j, vb.pcm[j], -8, n/2, 0, 0);
4990 /* channel coupling */
4991 for(i=info.coupling_steps-1;i>=0;i--){
4992 ogg_int32_t *pcmM=vb.pcm[info.coupling_mag[i]];
4993 ogg_int32_t *pcmA=vb.pcm[info.coupling_ang[i]];
4995 for(j=0;j<n/2;j++){
4996 ogg_int32_t mag=pcmM[j];
4997 ogg_int32_t ang=pcmA[j];
4999 if(mag>0)
5000 if(ang>0){
5001 pcmM[j]=mag;
5002 pcmA[j]=mag-ang;
5003 }else{
5004 pcmA[j]=mag;
5005 pcmM[j]=mag+ang;
5007 else
5008 if(ang>0){
5009 pcmM[j]=mag;
5010 pcmA[j]=mag+ang;
5011 }else{
5012 pcmA[j]=mag;
5013 pcmM[j]=mag-ang;
5018 //for(j=0;j<vi.channels;j++)
5019 //analysis_output_("residue", seq+j, vb.pcm[j], -8, n/2, 0, 0);
5021 /* compute and apply spectral envelope */
5022 for(i=0;i<vi.channels;i++){
5023 ogg_int32_t *pcm=vb.pcm[i];
5024 int submap=info.chmuxlist[i];
5025 look.floor_func[submap].
5026 inverse2(vb, look.floor_look[submap], floormemo[i], pcm);
5029 //for(j=0;j<vi.channels;j++)
5030 //analysis_output_("mdct", seq+j, vb.pcm[j], -24, n/2, 0, 1);
5032 /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
5033 /* only MDCT right now.... */
5034 for(i=0;i<vi.channels;i++){
5035 ogg_int32_t *pcm=vb.pcm[i];
5036 mdct_backward(n, pcm, pcm);
5039 //for(j=0;j<vi.channels;j++)
5040 //analysis_output_("imdct", seq+j, vb.pcm[j], -24, n, 0, 0);
5042 /* window the data */
5043 for(i=0;i<vi.channels;i++){
5044 ogg_int32_t *pcm=vb.pcm[i];
5045 if(nonzero[i])
5046 vorbis_apply_window_(pcm, b.window.ptr, ci.blocksizes.ptr, vb.lW, vb.W, vb.nW);
5047 else
5048 for(j=0;j<n;j++)
5049 pcm[j]=0;
5053 //for(j=0;j<vi.channels;j++)
5054 //analysis_output_("window", seq+j, vb.pcm[j], -24, n, 0, 0);
5056 //seq+=vi.channels;
5057 /* all done! */
5058 return(0);
5061 /* export hooks */
5062 static immutable vorbis_func_mapping mapping0_exportbundle={
5063 &mapping0_unpack,
5064 &mapping0_look,
5065 &mapping0_free_info,
5066 &mapping0_free_look,
5067 &mapping0_inverse
5071 /* ******************************************************************
5072 function: modified discrete cosine transform
5074 function: normalized modified discrete cosine transform
5075 power of two length transform only [64 <= n ]
5076 last mod: $Id$
5078 Original algorithm adapted trm_long ago from _The use of multirate filter
5079 banks for coding of high quality digital audio_, by T. Sporer,
5080 K. Brandenburg and B. Edler, collection of the European Signal
5081 Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
5082 211-214
5084 The below code implements an algorithm that no longer looks much like
5085 that presented in the paper, but the basic structure remains if you
5086 dig deep enough to see it.
5088 This module DOES NOT INCLUDE code to generate/apply the window
5089 function. Everybody has their own weird favorite including me... I
5090 happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
5091 vehemently disagree.
5092 ****************************************************************** */
5094 alias DATA_TYPE = ogg_int32_t;
5095 alias REG_TYPE = ogg_int32_t; /*register*/
5097 version(LOW_ACCURACY__) {
5098 enum cPI3_8 = (0x0062);
5099 enum cPI2_8 = (0x00b5);
5100 enum cPI1_8 = (0x00ed);
5101 } else {
5102 enum cPI3_8 = (0x30fbc54d);
5103 enum cPI2_8 = (0x5a82799a);
5104 enum cPI1_8 = (0x7641af3d);
5107 /* 8 point butterfly (in place) */
5108 /*STIN*/ void mdct_butterfly_8(DATA_TYPE *x) nothrow @trusted @nogc {
5110 REG_TYPE r0 = x[4] + x[0];
5111 REG_TYPE r1 = x[4] - x[0];
5112 REG_TYPE r2 = x[5] + x[1];
5113 REG_TYPE r3 = x[5] - x[1];
5114 REG_TYPE r4 = x[6] + x[2];
5115 REG_TYPE r5 = x[6] - x[2];
5116 REG_TYPE r6 = x[7] + x[3];
5117 REG_TYPE r7 = x[7] - x[3];
5119 x[0] = r5 + r3;
5120 x[1] = r7 - r1;
5121 x[2] = r5 - r3;
5122 x[3] = r7 + r1;
5123 x[4] = r4 - r0;
5124 x[5] = r6 - r2;
5125 x[6] = r4 + r0;
5126 x[7] = r6 + r2;
5127 /*MB();*/
5130 /* 16 point butterfly (in place, 4 register) */
5131 /*STIN*/ void mdct_butterfly_16(DATA_TYPE *x) nothrow @trusted @nogc {
5133 REG_TYPE r0, r1;
5135 r0 = x[ 0] - x[ 8]; x[ 8] += x[ 0];
5136 r1 = x[ 1] - x[ 9]; x[ 9] += x[ 1];
5137 x[ 0] = MULT31((r0 + r1) , cPI2_8);
5138 x[ 1] = MULT31((r1 - r0) , cPI2_8);
5139 /*MB();*/
5141 r0 = x[10] - x[ 2]; x[10] += x[ 2];
5142 r1 = x[ 3] - x[11]; x[11] += x[ 3];
5143 x[ 2] = r1; x[ 3] = r0;
5144 /*MB();*/
5146 r0 = x[12] - x[ 4]; x[12] += x[ 4];
5147 r1 = x[13] - x[ 5]; x[13] += x[ 5];
5148 x[ 4] = MULT31((r0 - r1) , cPI2_8);
5149 x[ 5] = MULT31((r0 + r1) , cPI2_8);
5150 /*MB();*/
5152 r0 = x[14] - x[ 6]; x[14] += x[ 6];
5153 r1 = x[15] - x[ 7]; x[15] += x[ 7];
5154 x[ 6] = r0; x[ 7] = r1;
5155 /*MB();*/
5157 mdct_butterfly_8(x);
5158 mdct_butterfly_8(x+8);
5161 /* 32 point butterfly (in place, 4 register) */
5162 /*STIN*/ void mdct_butterfly_32(DATA_TYPE *x) nothrow @trusted @nogc {
5164 REG_TYPE r0, r1;
5166 r0 = x[30] - x[14]; x[30] += x[14];
5167 r1 = x[31] - x[15]; x[31] += x[15];
5168 x[14] = r0; x[15] = r1;
5169 /*MB();*/
5171 r0 = x[28] - x[12]; x[28] += x[12];
5172 r1 = x[29] - x[13]; x[29] += x[13];
5173 XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[12], &x[13] );
5174 /*MB();*/
5176 r0 = x[26] - x[10]; x[26] += x[10];
5177 r1 = x[27] - x[11]; x[27] += x[11];
5178 x[10] = MULT31((r0 - r1) , cPI2_8);
5179 x[11] = MULT31((r0 + r1) , cPI2_8);
5180 /*MB();*/
5182 r0 = x[24] - x[ 8]; x[24] += x[ 8];
5183 r1 = x[25] - x[ 9]; x[25] += x[ 9];
5184 XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 8], &x[ 9] );
5185 /*MB();*/
5187 r0 = x[22] - x[ 6]; x[22] += x[ 6];
5188 r1 = x[ 7] - x[23]; x[23] += x[ 7];
5189 x[ 6] = r1; x[ 7] = r0;
5190 /*MB();*/
5192 r0 = x[ 4] - x[20]; x[20] += x[ 4];
5193 r1 = x[ 5] - x[21]; x[21] += x[ 5];
5194 XPROD31 ( r0, r1, cPI3_8, cPI1_8, &x[ 4], &x[ 5] );
5195 /*MB();*/
5197 r0 = x[ 2] - x[18]; x[18] += x[ 2];
5198 r1 = x[ 3] - x[19]; x[19] += x[ 3];
5199 x[ 2] = MULT31((r1 + r0) , cPI2_8);
5200 x[ 3] = MULT31((r1 - r0) , cPI2_8);
5201 /*MB();*/
5203 r0 = x[ 0] - x[16]; x[16] += x[ 0];
5204 r1 = x[ 1] - x[17]; x[17] += x[ 1];
5205 XPROD31 ( r0, r1, cPI1_8, cPI3_8, &x[ 0], &x[ 1] );
5206 /*MB();*/
5208 mdct_butterfly_16(x);
5209 mdct_butterfly_16(x+16);
5212 /* N/stage point generic N stage butterfly (in place, 2 register) */
5213 /*STIN*/ void mdct_butterfly_generic(DATA_TYPE *x, int points, int step) nothrow @trusted @nogc {
5215 immutable(LOOKUP_T)*T = sincos_lookup0.ptr;
5216 DATA_TYPE *x1 = x + points - 8;
5217 DATA_TYPE *x2 = x + (points>>1) - 8;
5218 REG_TYPE r0;
5219 REG_TYPE r1;
5222 r0 = x1[6] - x2[6]; x1[6] += x2[6];
5223 r1 = x2[7] - x1[7]; x1[7] += x2[7];
5224 XPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T+=step;
5226 r0 = x1[4] - x2[4]; x1[4] += x2[4];
5227 r1 = x2[5] - x1[5]; x1[5] += x2[5];
5228 XPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T+=step;
5230 r0 = x1[2] - x2[2]; x1[2] += x2[2];
5231 r1 = x2[3] - x1[3]; x1[3] += x2[3];
5232 XPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T+=step;
5234 r0 = x1[0] - x2[0]; x1[0] += x2[0];
5235 r1 = x2[1] - x1[1]; x1[1] += x2[1];
5236 XPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T+=step;
5238 x1-=8; x2-=8;
5239 }while(T<sincos_lookup0.ptr+1024);
5241 r0 = x1[6] - x2[6]; x1[6] += x2[6];
5242 r1 = x1[7] - x2[7]; x1[7] += x2[7];
5243 XNPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T-=step;
5245 r0 = x1[4] - x2[4]; x1[4] += x2[4];
5246 r1 = x1[5] - x2[5]; x1[5] += x2[5];
5247 XNPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T-=step;
5249 r0 = x1[2] - x2[2]; x1[2] += x2[2];
5250 r1 = x1[3] - x2[3]; x1[3] += x2[3];
5251 XNPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T-=step;
5253 r0 = x1[0] - x2[0]; x1[0] += x2[0];
5254 r1 = x1[1] - x2[1]; x1[1] += x2[1];
5255 XNPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T-=step;
5257 x1-=8; x2-=8;
5258 }while(T>sincos_lookup0.ptr);
5260 r0 = x2[6] - x1[6]; x1[6] += x2[6];
5261 r1 = x2[7] - x1[7]; x1[7] += x2[7];
5262 XPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T+=step;
5264 r0 = x2[4] - x1[4]; x1[4] += x2[4];
5265 r1 = x2[5] - x1[5]; x1[5] += x2[5];
5266 XPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T+=step;
5268 r0 = x2[2] - x1[2]; x1[2] += x2[2];
5269 r1 = x2[3] - x1[3]; x1[3] += x2[3];
5270 XPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T+=step;
5272 r0 = x2[0] - x1[0]; x1[0] += x2[0];
5273 r1 = x2[1] - x1[1]; x1[1] += x2[1];
5274 XPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T+=step;
5276 x1-=8; x2-=8;
5277 }while(T<sincos_lookup0.ptr+1024);
5279 r0 = x1[6] - x2[6]; x1[6] += x2[6];
5280 r1 = x2[7] - x1[7]; x1[7] += x2[7];
5281 XNPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T-=step;
5283 r0 = x1[4] - x2[4]; x1[4] += x2[4];
5284 r1 = x2[5] - x1[5]; x1[5] += x2[5];
5285 XNPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T-=step;
5287 r0 = x1[2] - x2[2]; x1[2] += x2[2];
5288 r1 = x2[3] - x1[3]; x1[3] += x2[3];
5289 XNPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T-=step;
5291 r0 = x1[0] - x2[0]; x1[0] += x2[0];
5292 r1 = x2[1] - x1[1]; x1[1] += x2[1];
5293 XNPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T-=step;
5295 x1-=8; x2-=8;
5296 }while(T>sincos_lookup0.ptr);
5299 /*STIN*/ void mdct_butterflies(DATA_TYPE *x, int points, int shift) nothrow @trusted @nogc {
5301 int stages=8-shift;
5302 int i, j;
5304 for(i=0;--stages>0;i++){
5305 for(j=0;j<(1<<i);j++)
5306 mdct_butterfly_generic(x+(points>>i)*j, points>>i, 4<<(i+shift));
5309 for(j=0;j<points;j+=32)
5310 mdct_butterfly_32(x+j);
5314 static immutable ubyte[16] bitrev=[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15];
5316 /*STIN*/ int bitrev12(int x) nothrow @trusted @nogc {
5317 pragma(inline, true);
5318 return bitrev.ptr[x>>8]|(bitrev.ptr[(x&0x0f0)>>4]<<4)|((cast(int)bitrev.ptr[x&0x00f])<<8);
5321 /*STIN*/ void mdct_bitreverse(DATA_TYPE *x, int n, int step, int shift) nothrow @trusted @nogc {
5323 int bit = 0;
5324 DATA_TYPE *w0 = x;
5325 DATA_TYPE *w1 = x = w0+(n>>1);
5326 immutable(LOOKUP_T)*T = (step>=4)?(sincos_lookup0.ptr+(step>>1)):sincos_lookup1.ptr;
5327 immutable(LOOKUP_T)*Ttop = T+1024;
5328 DATA_TYPE r2;
5331 DATA_TYPE r3 = bitrev12(bit++);
5332 DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1;
5333 DATA_TYPE *x1 = x + (r3>>shift);
5335 REG_TYPE r0 = x0[0] + x1[0];
5336 REG_TYPE r1 = x1[1] - x0[1];
5338 XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step;
5340 w1 -= 4;
5342 r0 = (x0[1] + x1[1])>>1;
5343 r1 = (x0[0] - x1[0])>>1;
5344 w0[0] = r0 + r2;
5345 w0[1] = r1 + r3;
5346 w1[2] = r0 - r2;
5347 w1[3] = r3 - r1;
5349 r3 = bitrev12(bit++);
5350 x0 = x + ((r3 ^ 0xfff)>>shift) -1;
5351 x1 = x + (r3>>shift);
5353 r0 = x0[0] + x1[0];
5354 r1 = x1[1] - x0[1];
5356 XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step;
5358 r0 = (x0[1] + x1[1])>>1;
5359 r1 = (x0[0] - x1[0])>>1;
5360 w0[2] = r0 + r2;
5361 w0[3] = r1 + r3;
5362 w1[0] = r0 - r2;
5363 w1[1] = r3 - r1;
5365 w0 += 4;
5366 }while(T<Ttop);
5368 DATA_TYPE r3 = bitrev12(bit++);
5369 DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1;
5370 DATA_TYPE *x1 = x + (r3>>shift);
5372 REG_TYPE r0 = x0[0] + x1[0];
5373 REG_TYPE r1 = x1[1] - x0[1];
5375 T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
5377 w1 -= 4;
5379 r0 = (x0[1] + x1[1])>>1;
5380 r1 = (x0[0] - x1[0])>>1;
5381 w0[0] = r0 + r2;
5382 w0[1] = r1 + r3;
5383 w1[2] = r0 - r2;
5384 w1[3] = r3 - r1;
5386 r3 = bitrev12(bit++);
5387 x0 = x + ((r3 ^ 0xfff)>>shift) -1;
5388 x1 = x + (r3>>shift);
5390 r0 = x0[0] + x1[0];
5391 r1 = x1[1] - x0[1];
5393 T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
5395 r0 = (x0[1] + x1[1])>>1;
5396 r1 = (x0[0] - x1[0])>>1;
5397 w0[2] = r0 + r2;
5398 w0[3] = r1 + r3;
5399 w1[0] = r0 - r2;
5400 w1[1] = r3 - r1;
5402 w0 += 4;
5403 }while(w0<w1);
5406 void mdct_backward(int n, DATA_TYPE *in_, DATA_TYPE *out_) nothrow @trusted @nogc {
5407 int n2=n>>1;
5408 int n4=n>>2;
5409 DATA_TYPE *iX;
5410 DATA_TYPE *oX;
5411 immutable(LOOKUP_T)*T;
5412 immutable(LOOKUP_T)*V;
5413 int shift;
5414 int step;
5416 for (shift=6;!(n&(1<<shift));shift++) {}
5417 shift=13-shift;
5418 step=2<<shift;
5420 /* rotate */
5422 iX = in_+n2-7;
5423 oX = out_+n2+n4;
5424 T = sincos_lookup0.ptr;
5427 oX-=4;
5428 XPROD31( iX[4], iX[6], T[0], T[1], &oX[2], &oX[3] ); T+=step;
5429 XPROD31( iX[0], iX[2], T[0], T[1], &oX[0], &oX[1] ); T+=step;
5430 iX-=8;
5431 }while(iX>=in_+n4);
5433 oX-=4;
5434 XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] ); T-=step;
5435 XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] ); T-=step;
5436 iX-=8;
5437 }while(iX>=in_);
5439 iX = in_+n2-8;
5440 oX = out_+n2+n4;
5441 T = sincos_lookup0.ptr;
5444 T+=step; XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] );
5445 T+=step; XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] );
5446 iX-=8;
5447 oX+=4;
5448 }while(iX>=in_+n4);
5450 T-=step; XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] );
5451 T-=step; XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] );
5452 iX-=8;
5453 oX+=4;
5454 }while(iX>=in_);
5456 mdct_butterflies(out_+n2, n2, shift);
5457 mdct_bitreverse(out_, n, step, shift);
5459 /* rotate + window */
5461 step>>=2;
5463 DATA_TYPE *oX1=out_+n2+n4;
5464 DATA_TYPE *oX2=out_+n2+n4;
5465 DATA_TYPE *iX_ =out_;
5467 switch(step) {
5468 default: {
5469 T=(step>=4)?(sincos_lookup0.ptr+(step>>1)):sincos_lookup1.ptr;
5471 oX1-=4;
5472 XPROD31( iX_[0], -iX_[1], T[0], T[1], &oX1[3], &oX2[0] ); T+=step;
5473 XPROD31( iX_[2], -iX_[3], T[0], T[1], &oX1[2], &oX2[1] ); T+=step;
5474 XPROD31( iX_[4], -iX_[5], T[0], T[1], &oX1[1], &oX2[2] ); T+=step;
5475 XPROD31( iX_[6], -iX_[7], T[0], T[1], &oX1[0], &oX2[3] ); T+=step;
5476 oX2+=4;
5477 iX_+=8;
5478 }while(iX_<oX1);
5479 break;
5482 case 1: {
5483 /* linear interpolation between table values: offset=0.5, step=1 */
5484 REG_TYPE t0, t1, v0, v1;
5485 T = sincos_lookup0.ptr;
5486 V = sincos_lookup1.ptr;
5487 t0 = (*T++)>>1;
5488 t1 = (*T++)>>1;
5490 oX1-=4;
5492 t0 += (v0 = (*V++)>>1);
5493 t1 += (v1 = (*V++)>>1);
5494 XPROD31( iX_[0], -iX_[1], t0, t1, &oX1[3], &oX2[0] );
5495 v0 += (t0 = (*T++)>>1);
5496 v1 += (t1 = (*T++)>>1);
5497 XPROD31( iX_[2], -iX_[3], v0, v1, &oX1[2], &oX2[1] );
5498 t0 += (v0 = (*V++)>>1);
5499 t1 += (v1 = (*V++)>>1);
5500 XPROD31( iX_[4], -iX_[5], t0, t1, &oX1[1], &oX2[2] );
5501 v0 += (t0 = (*T++)>>1);
5502 v1 += (t1 = (*T++)>>1);
5503 XPROD31( iX_[6], -iX_[7], v0, v1, &oX1[0], &oX2[3] );
5505 oX2+=4;
5506 iX_+=8;
5507 }while(iX_<oX1);
5508 break;
5511 case 0: {
5512 /* linear interpolation between table values: offset=0.25, step=0.5 */
5513 REG_TYPE t0, t1, v0, v1, q0, q1;
5514 T = sincos_lookup0.ptr;
5515 V = sincos_lookup1.ptr;
5516 t0 = *T++;
5517 t1 = *T++;
5519 oX1-=4;
5521 v0 = *V++;
5522 v1 = *V++;
5523 t0 += (q0 = (v0-t0)>>2);
5524 t1 += (q1 = (v1-t1)>>2);
5525 XPROD31( iX_[0], -iX_[1], t0, t1, &oX1[3], &oX2[0] );
5526 t0 = v0-q0;
5527 t1 = v1-q1;
5528 XPROD31( iX_[2], -iX_[3], t0, t1, &oX1[2], &oX2[1] );
5530 t0 = *T++;
5531 t1 = *T++;
5532 v0 += (q0 = (t0-v0)>>2);
5533 v1 += (q1 = (t1-v1)>>2);
5534 XPROD31( iX_[4], -iX_[5], v0, v1, &oX1[1], &oX2[2] );
5535 v0 = t0-q0;
5536 v1 = t1-q1;
5537 XPROD31( iX_[6], -iX_[7], v0, v1, &oX1[0], &oX2[3] );
5539 oX2+=4;
5540 iX_+=8;
5541 }while(iX_<oX1);
5542 break;
5546 iX_=out_+n2+n4;
5547 oX1=out_+n4;
5548 oX2=oX1;
5551 oX1-=4;
5552 iX_-=4;
5554 oX2[0] = -(oX1[3] = iX_[3]);
5555 oX2[1] = -(oX1[2] = iX_[2]);
5556 oX2[2] = -(oX1[1] = iX_[1]);
5557 oX2[3] = -(oX1[0] = iX_[0]);
5559 oX2+=4;
5560 }while(oX2<iX_);
5562 iX_=out_+n2+n4;
5563 oX1=out_+n2+n4;
5564 oX2=out_+n2;
5567 oX1-=4;
5568 oX1[0]= iX_[3];
5569 oX1[1]= iX_[2];
5570 oX1[2]= iX_[1];
5571 oX1[3]= iX_[0];
5572 iX_+=4;
5573 }while(oX1>oX2);
5578 /* ******************************************************************
5579 function: sin,cos lookup tables
5580 ****************************************************************** */
5582 /* [sin(2*i*PI/4096), cos(2*i*PI/4096)}, with i = 0 to 512 */
5583 static immutable LOOKUP_T[1026] sincos_lookup0 = [
5584 X(0x00000000), X(0x7fffffff), X(0x003243f5), X(0x7ffff621),
5585 X(0x006487e3), X(0x7fffd886), X(0x0096cbc1), X(0x7fffa72c),
5586 X(0x00c90f88), X(0x7fff6216), X(0x00fb5330), X(0x7fff0943),
5587 X(0x012d96b1), X(0x7ffe9cb2), X(0x015fda03), X(0x7ffe1c65),
5588 X(0x01921d20), X(0x7ffd885a), X(0x01c45ffe), X(0x7ffce093),
5589 X(0x01f6a297), X(0x7ffc250f), X(0x0228e4e2), X(0x7ffb55ce),
5590 X(0x025b26d7), X(0x7ffa72d1), X(0x028d6870), X(0x7ff97c18),
5591 X(0x02bfa9a4), X(0x7ff871a2), X(0x02f1ea6c), X(0x7ff75370),
5592 X(0x03242abf), X(0x7ff62182), X(0x03566a96), X(0x7ff4dbd9),
5593 X(0x0388a9ea), X(0x7ff38274), X(0x03bae8b2), X(0x7ff21553),
5594 X(0x03ed26e6), X(0x7ff09478), X(0x041f6480), X(0x7feeffe1),
5595 X(0x0451a177), X(0x7fed5791), X(0x0483ddc3), X(0x7feb9b85),
5596 X(0x04b6195d), X(0x7fe9cbc0), X(0x04e8543e), X(0x7fe7e841),
5597 X(0x051a8e5c), X(0x7fe5f108), X(0x054cc7b1), X(0x7fe3e616),
5598 X(0x057f0035), X(0x7fe1c76b), X(0x05b137df), X(0x7fdf9508),
5599 X(0x05e36ea9), X(0x7fdd4eec), X(0x0615a48b), X(0x7fdaf519),
5600 X(0x0647d97c), X(0x7fd8878e), X(0x067a0d76), X(0x7fd6064c),
5601 X(0x06ac406f), X(0x7fd37153), X(0x06de7262), X(0x7fd0c8a3),
5602 X(0x0710a345), X(0x7fce0c3e), X(0x0742d311), X(0x7fcb3c23),
5603 X(0x077501be), X(0x7fc85854), X(0x07a72f45), X(0x7fc560cf),
5604 X(0x07d95b9e), X(0x7fc25596), X(0x080b86c2), X(0x7fbf36aa),
5605 X(0x083db0a7), X(0x7fbc040a), X(0x086fd947), X(0x7fb8bdb8),
5606 X(0x08a2009a), X(0x7fb563b3), X(0x08d42699), X(0x7fb1f5fc),
5607 X(0x09064b3a), X(0x7fae7495), X(0x09386e78), X(0x7faadf7c),
5608 X(0x096a9049), X(0x7fa736b4), X(0x099cb0a7), X(0x7fa37a3c),
5609 X(0x09cecf89), X(0x7f9faa15), X(0x0a00ece8), X(0x7f9bc640),
5610 X(0x0a3308bd), X(0x7f97cebd), X(0x0a6522fe), X(0x7f93c38c),
5611 X(0x0a973ba5), X(0x7f8fa4b0), X(0x0ac952aa), X(0x7f8b7227),
5612 X(0x0afb6805), X(0x7f872bf3), X(0x0b2d7baf), X(0x7f82d214),
5613 X(0x0b5f8d9f), X(0x7f7e648c), X(0x0b919dcf), X(0x7f79e35a),
5614 X(0x0bc3ac35), X(0x7f754e80), X(0x0bf5b8cb), X(0x7f70a5fe),
5615 X(0x0c27c389), X(0x7f6be9d4), X(0x0c59cc68), X(0x7f671a05),
5616 X(0x0c8bd35e), X(0x7f62368f), X(0x0cbdd865), X(0x7f5d3f75),
5617 X(0x0cefdb76), X(0x7f5834b7), X(0x0d21dc87), X(0x7f531655),
5618 X(0x0d53db92), X(0x7f4de451), X(0x0d85d88f), X(0x7f489eaa),
5619 X(0x0db7d376), X(0x7f434563), X(0x0de9cc40), X(0x7f3dd87c),
5620 X(0x0e1bc2e4), X(0x7f3857f6), X(0x0e4db75b), X(0x7f32c3d1),
5621 X(0x0e7fa99e), X(0x7f2d1c0e), X(0x0eb199a4), X(0x7f2760af),
5622 X(0x0ee38766), X(0x7f2191b4), X(0x0f1572dc), X(0x7f1baf1e),
5623 X(0x0f475bff), X(0x7f15b8ee), X(0x0f7942c7), X(0x7f0faf25),
5624 X(0x0fab272b), X(0x7f0991c4), X(0x0fdd0926), X(0x7f0360cb),
5625 X(0x100ee8ad), X(0x7efd1c3c), X(0x1040c5bb), X(0x7ef6c418),
5626 X(0x1072a048), X(0x7ef05860), X(0x10a4784b), X(0x7ee9d914),
5627 X(0x10d64dbd), X(0x7ee34636), X(0x11082096), X(0x7edc9fc6),
5628 X(0x1139f0cf), X(0x7ed5e5c6), X(0x116bbe60), X(0x7ecf1837),
5629 X(0x119d8941), X(0x7ec8371a), X(0x11cf516a), X(0x7ec14270),
5630 X(0x120116d5), X(0x7eba3a39), X(0x1232d979), X(0x7eb31e78),
5631 X(0x1264994e), X(0x7eabef2c), X(0x1296564d), X(0x7ea4ac58),
5632 X(0x12c8106f), X(0x7e9d55fc), X(0x12f9c7aa), X(0x7e95ec1a),
5633 X(0x132b7bf9), X(0x7e8e6eb2), X(0x135d2d53), X(0x7e86ddc6),
5634 X(0x138edbb1), X(0x7e7f3957), X(0x13c0870a), X(0x7e778166),
5635 X(0x13f22f58), X(0x7e6fb5f4), X(0x1423d492), X(0x7e67d703),
5636 X(0x145576b1), X(0x7e5fe493), X(0x148715ae), X(0x7e57dea7),
5637 X(0x14b8b17f), X(0x7e4fc53e), X(0x14ea4a1f), X(0x7e47985b),
5638 X(0x151bdf86), X(0x7e3f57ff), X(0x154d71aa), X(0x7e37042a),
5639 X(0x157f0086), X(0x7e2e9cdf), X(0x15b08c12), X(0x7e26221f),
5640 X(0x15e21445), X(0x7e1d93ea), X(0x16139918), X(0x7e14f242),
5641 X(0x16451a83), X(0x7e0c3d29), X(0x1676987f), X(0x7e0374a0),
5642 X(0x16a81305), X(0x7dfa98a8), X(0x16d98a0c), X(0x7df1a942),
5643 X(0x170afd8d), X(0x7de8a670), X(0x173c6d80), X(0x7ddf9034),
5644 X(0x176dd9de), X(0x7dd6668f), X(0x179f429f), X(0x7dcd2981),
5645 X(0x17d0a7bc), X(0x7dc3d90d), X(0x1802092c), X(0x7dba7534),
5646 X(0x183366e9), X(0x7db0fdf8), X(0x1864c0ea), X(0x7da77359),
5647 X(0x18961728), X(0x7d9dd55a), X(0x18c7699b), X(0x7d9423fc),
5648 X(0x18f8b83c), X(0x7d8a5f40), X(0x192a0304), X(0x7d808728),
5649 X(0x195b49ea), X(0x7d769bb5), X(0x198c8ce7), X(0x7d6c9ce9),
5650 X(0x19bdcbf3), X(0x7d628ac6), X(0x19ef0707), X(0x7d58654d),
5651 X(0x1a203e1b), X(0x7d4e2c7f), X(0x1a517128), X(0x7d43e05e),
5652 X(0x1a82a026), X(0x7d3980ec), X(0x1ab3cb0d), X(0x7d2f0e2b),
5653 X(0x1ae4f1d6), X(0x7d24881b), X(0x1b161479), X(0x7d19eebf),
5654 X(0x1b4732ef), X(0x7d0f4218), X(0x1b784d30), X(0x7d048228),
5655 X(0x1ba96335), X(0x7cf9aef0), X(0x1bda74f6), X(0x7ceec873),
5656 X(0x1c0b826a), X(0x7ce3ceb2), X(0x1c3c8b8c), X(0x7cd8c1ae),
5657 X(0x1c6d9053), X(0x7ccda169), X(0x1c9e90b8), X(0x7cc26de5),
5658 X(0x1ccf8cb3), X(0x7cb72724), X(0x1d00843d), X(0x7cabcd28),
5659 X(0x1d31774d), X(0x7ca05ff1), X(0x1d6265dd), X(0x7c94df83),
5660 X(0x1d934fe5), X(0x7c894bde), X(0x1dc4355e), X(0x7c7da505),
5661 X(0x1df5163f), X(0x7c71eaf9), X(0x1e25f282), X(0x7c661dbc),
5662 X(0x1e56ca1e), X(0x7c5a3d50), X(0x1e879d0d), X(0x7c4e49b7),
5663 X(0x1eb86b46), X(0x7c4242f2), X(0x1ee934c3), X(0x7c362904),
5664 X(0x1f19f97b), X(0x7c29fbee), X(0x1f4ab968), X(0x7c1dbbb3),
5665 X(0x1f7b7481), X(0x7c116853), X(0x1fac2abf), X(0x7c0501d2),
5666 X(0x1fdcdc1b), X(0x7bf88830), X(0x200d888d), X(0x7bebfb70),
5667 X(0x203e300d), X(0x7bdf5b94), X(0x206ed295), X(0x7bd2a89e),
5668 X(0x209f701c), X(0x7bc5e290), X(0x20d0089c), X(0x7bb9096b),
5669 X(0x21009c0c), X(0x7bac1d31), X(0x21312a65), X(0x7b9f1de6),
5670 X(0x2161b3a0), X(0x7b920b89), X(0x219237b5), X(0x7b84e61f),
5671 X(0x21c2b69c), X(0x7b77ada8), X(0x21f3304f), X(0x7b6a6227),
5672 X(0x2223a4c5), X(0x7b5d039e), X(0x225413f8), X(0x7b4f920e),
5673 X(0x22847de0), X(0x7b420d7a), X(0x22b4e274), X(0x7b3475e5),
5674 X(0x22e541af), X(0x7b26cb4f), X(0x23159b88), X(0x7b190dbc),
5675 X(0x2345eff8), X(0x7b0b3d2c), X(0x23763ef7), X(0x7afd59a4),
5676 X(0x23a6887f), X(0x7aef6323), X(0x23d6cc87), X(0x7ae159ae),
5677 X(0x24070b08), X(0x7ad33d45), X(0x243743fa), X(0x7ac50dec),
5678 X(0x24677758), X(0x7ab6cba4), X(0x2497a517), X(0x7aa8766f),
5679 X(0x24c7cd33), X(0x7a9a0e50), X(0x24f7efa2), X(0x7a8b9348),
5680 X(0x25280c5e), X(0x7a7d055b), X(0x2558235f), X(0x7a6e648a),
5681 X(0x2588349d), X(0x7a5fb0d8), X(0x25b84012), X(0x7a50ea47),
5682 X(0x25e845b6), X(0x7a4210d8), X(0x26184581), X(0x7a332490),
5683 X(0x26483f6c), X(0x7a24256f), X(0x26783370), X(0x7a151378),
5684 X(0x26a82186), X(0x7a05eead), X(0x26d809a5), X(0x79f6b711),
5685 X(0x2707ebc7), X(0x79e76ca7), X(0x2737c7e3), X(0x79d80f6f),
5686 X(0x27679df4), X(0x79c89f6e), X(0x27976df1), X(0x79b91ca4),
5687 X(0x27c737d3), X(0x79a98715), X(0x27f6fb92), X(0x7999dec4),
5688 X(0x2826b928), X(0x798a23b1), X(0x2856708d), X(0x797a55e0),
5689 X(0x288621b9), X(0x796a7554), X(0x28b5cca5), X(0x795a820e),
5690 X(0x28e5714b), X(0x794a7c12), X(0x29150fa1), X(0x793a6361),
5691 X(0x2944a7a2), X(0x792a37fe), X(0x29743946), X(0x7919f9ec),
5692 X(0x29a3c485), X(0x7909a92d), X(0x29d34958), X(0x78f945c3),
5693 X(0x2a02c7b8), X(0x78e8cfb2), X(0x2a323f9e), X(0x78d846fb),
5694 X(0x2a61b101), X(0x78c7aba2), X(0x2a911bdc), X(0x78b6fda8),
5695 X(0x2ac08026), X(0x78a63d11), X(0x2aefddd8), X(0x789569df),
5696 X(0x2b1f34eb), X(0x78848414), X(0x2b4e8558), X(0x78738bb3),
5697 X(0x2b7dcf17), X(0x786280bf), X(0x2bad1221), X(0x7851633b),
5698 X(0x2bdc4e6f), X(0x78403329), X(0x2c0b83fa), X(0x782ef08b),
5699 X(0x2c3ab2b9), X(0x781d9b65), X(0x2c69daa6), X(0x780c33b8),
5700 X(0x2c98fbba), X(0x77fab989), X(0x2cc815ee), X(0x77e92cd9),
5701 X(0x2cf72939), X(0x77d78daa), X(0x2d263596), X(0x77c5dc01),
5702 X(0x2d553afc), X(0x77b417df), X(0x2d843964), X(0x77a24148),
5703 X(0x2db330c7), X(0x7790583e), X(0x2de2211e), X(0x777e5cc3),
5704 X(0x2e110a62), X(0x776c4edb), X(0x2e3fec8b), X(0x775a2e89),
5705 X(0x2e6ec792), X(0x7747fbce), X(0x2e9d9b70), X(0x7735b6af),
5706 X(0x2ecc681e), X(0x77235f2d), X(0x2efb2d95), X(0x7710f54c),
5707 X(0x2f29ebcc), X(0x76fe790e), X(0x2f58a2be), X(0x76ebea77),
5708 X(0x2f875262), X(0x76d94989), X(0x2fb5fab2), X(0x76c69647),
5709 X(0x2fe49ba7), X(0x76b3d0b4), X(0x30133539), X(0x76a0f8d2),
5710 X(0x3041c761), X(0x768e0ea6), X(0x30705217), X(0x767b1231),
5711 X(0x309ed556), X(0x76680376), X(0x30cd5115), X(0x7654e279),
5712 X(0x30fbc54d), X(0x7641af3d), X(0x312a31f8), X(0x762e69c4),
5713 X(0x3158970e), X(0x761b1211), X(0x3186f487), X(0x7607a828),
5714 X(0x31b54a5e), X(0x75f42c0b), X(0x31e39889), X(0x75e09dbd),
5715 X(0x3211df04), X(0x75ccfd42), X(0x32401dc6), X(0x75b94a9c),
5716 X(0x326e54c7), X(0x75a585cf), X(0x329c8402), X(0x7591aedd),
5717 X(0x32caab6f), X(0x757dc5ca), X(0x32f8cb07), X(0x7569ca99),
5718 X(0x3326e2c3), X(0x7555bd4c), X(0x3354f29b), X(0x75419de7),
5719 X(0x3382fa88), X(0x752d6c6c), X(0x33b0fa84), X(0x751928e0),
5720 X(0x33def287), X(0x7504d345), X(0x340ce28b), X(0x74f06b9e),
5721 X(0x343aca87), X(0x74dbf1ef), X(0x3468aa76), X(0x74c7663a),
5722 X(0x34968250), X(0x74b2c884), X(0x34c4520d), X(0x749e18cd),
5723 X(0x34f219a8), X(0x7489571c), X(0x351fd918), X(0x74748371),
5724 X(0x354d9057), X(0x745f9dd1), X(0x357b3f5d), X(0x744aa63f),
5725 X(0x35a8e625), X(0x74359cbd), X(0x35d684a6), X(0x74208150),
5726 X(0x36041ad9), X(0x740b53fb), X(0x3631a8b8), X(0x73f614c0),
5727 X(0x365f2e3b), X(0x73e0c3a3), X(0x368cab5c), X(0x73cb60a8),
5728 X(0x36ba2014), X(0x73b5ebd1), X(0x36e78c5b), X(0x73a06522),
5729 X(0x3714f02a), X(0x738acc9e), X(0x37424b7b), X(0x73752249),
5730 X(0x376f9e46), X(0x735f6626), X(0x379ce885), X(0x73499838),
5731 X(0x37ca2a30), X(0x7333b883), X(0x37f76341), X(0x731dc70a),
5732 X(0x382493b0), X(0x7307c3d0), X(0x3851bb77), X(0x72f1aed9),
5733 X(0x387eda8e), X(0x72db8828), X(0x38abf0ef), X(0x72c54fc1),
5734 X(0x38d8fe93), X(0x72af05a7), X(0x39060373), X(0x7298a9dd),
5735 X(0x3932ff87), X(0x72823c67), X(0x395ff2c9), X(0x726bbd48),
5736 X(0x398cdd32), X(0x72552c85), X(0x39b9bebc), X(0x723e8a20),
5737 X(0x39e6975e), X(0x7227d61c), X(0x3a136712), X(0x7211107e),
5738 X(0x3a402dd2), X(0x71fa3949), X(0x3a6ceb96), X(0x71e35080),
5739 X(0x3a99a057), X(0x71cc5626), X(0x3ac64c0f), X(0x71b54a41),
5740 X(0x3af2eeb7), X(0x719e2cd2), X(0x3b1f8848), X(0x7186fdde),
5741 X(0x3b4c18ba), X(0x716fbd68), X(0x3b78a007), X(0x71586b74),
5742 X(0x3ba51e29), X(0x71410805), X(0x3bd19318), X(0x7129931f),
5743 X(0x3bfdfecd), X(0x71120cc5), X(0x3c2a6142), X(0x70fa74fc),
5744 X(0x3c56ba70), X(0x70e2cbc6), X(0x3c830a50), X(0x70cb1128),
5745 X(0x3caf50da), X(0x70b34525), X(0x3cdb8e09), X(0x709b67c0),
5746 X(0x3d07c1d6), X(0x708378ff), X(0x3d33ec39), X(0x706b78e3),
5747 X(0x3d600d2c), X(0x70536771), X(0x3d8c24a8), X(0x703b44ad),
5748 X(0x3db832a6), X(0x7023109a), X(0x3de4371f), X(0x700acb3c),
5749 X(0x3e10320d), X(0x6ff27497), X(0x3e3c2369), X(0x6fda0cae),
5750 X(0x3e680b2c), X(0x6fc19385), X(0x3e93e950), X(0x6fa90921),
5751 X(0x3ebfbdcd), X(0x6f906d84), X(0x3eeb889c), X(0x6f77c0b3),
5752 X(0x3f1749b8), X(0x6f5f02b2), X(0x3f430119), X(0x6f463383),
5753 X(0x3f6eaeb8), X(0x6f2d532c), X(0x3f9a5290), X(0x6f1461b0),
5754 X(0x3fc5ec98), X(0x6efb5f12), X(0x3ff17cca), X(0x6ee24b57),
5755 X(0x401d0321), X(0x6ec92683), X(0x40487f94), X(0x6eaff099),
5756 X(0x4073f21d), X(0x6e96a99d), X(0x409f5ab6), X(0x6e7d5193),
5757 X(0x40cab958), X(0x6e63e87f), X(0x40f60dfb), X(0x6e4a6e66),
5758 X(0x4121589b), X(0x6e30e34a), X(0x414c992f), X(0x6e174730),
5759 X(0x4177cfb1), X(0x6dfd9a1c), X(0x41a2fc1a), X(0x6de3dc11),
5760 X(0x41ce1e65), X(0x6dca0d14), X(0x41f93689), X(0x6db02d29),
5761 X(0x42244481), X(0x6d963c54), X(0x424f4845), X(0x6d7c3a98),
5762 X(0x427a41d0), X(0x6d6227fa), X(0x42a5311b), X(0x6d48047e),
5763 X(0x42d0161e), X(0x6d2dd027), X(0x42faf0d4), X(0x6d138afb),
5764 X(0x4325c135), X(0x6cf934fc), X(0x4350873c), X(0x6cdece2f),
5765 X(0x437b42e1), X(0x6cc45698), X(0x43a5f41e), X(0x6ca9ce3b),
5766 X(0x43d09aed), X(0x6c8f351c), X(0x43fb3746), X(0x6c748b3f),
5767 X(0x4425c923), X(0x6c59d0a9), X(0x4450507e), X(0x6c3f055d),
5768 X(0x447acd50), X(0x6c242960), X(0x44a53f93), X(0x6c093cb6),
5769 X(0x44cfa740), X(0x6bee3f62), X(0x44fa0450), X(0x6bd3316a),
5770 X(0x452456bd), X(0x6bb812d1), X(0x454e9e80), X(0x6b9ce39b),
5771 X(0x4578db93), X(0x6b81a3cd), X(0x45a30df0), X(0x6b66536b),
5772 X(0x45cd358f), X(0x6b4af279), X(0x45f7526b), X(0x6b2f80fb),
5773 X(0x4621647d), X(0x6b13fef5), X(0x464b6bbe), X(0x6af86c6c),
5774 X(0x46756828), X(0x6adcc964), X(0x469f59b4), X(0x6ac115e2),
5775 X(0x46c9405c), X(0x6aa551e9), X(0x46f31c1a), X(0x6a897d7d),
5776 X(0x471cece7), X(0x6a6d98a4), X(0x4746b2bc), X(0x6a51a361),
5777 X(0x47706d93), X(0x6a359db9), X(0x479a1d67), X(0x6a1987b0),
5778 X(0x47c3c22f), X(0x69fd614a), X(0x47ed5be6), X(0x69e12a8c),
5779 X(0x4816ea86), X(0x69c4e37a), X(0x48406e08), X(0x69a88c19),
5780 X(0x4869e665), X(0x698c246c), X(0x48935397), X(0x696fac78),
5781 X(0x48bcb599), X(0x69532442), X(0x48e60c62), X(0x69368bce),
5782 X(0x490f57ee), X(0x6919e320), X(0x49389836), X(0x68fd2a3d),
5783 X(0x4961cd33), X(0x68e06129), X(0x498af6df), X(0x68c387e9),
5784 X(0x49b41533), X(0x68a69e81), X(0x49dd282a), X(0x6889a4f6),
5785 X(0x4a062fbd), X(0x686c9b4b), X(0x4a2f2be6), X(0x684f8186),
5786 X(0x4a581c9e), X(0x683257ab), X(0x4a8101de), X(0x68151dbe),
5787 X(0x4aa9dba2), X(0x67f7d3c5), X(0x4ad2a9e2), X(0x67da79c3),
5788 X(0x4afb6c98), X(0x67bd0fbd), X(0x4b2423be), X(0x679f95b7),
5789 X(0x4b4ccf4d), X(0x67820bb7), X(0x4b756f40), X(0x676471c0),
5790 X(0x4b9e0390), X(0x6746c7d8), X(0x4bc68c36), X(0x67290e02),
5791 X(0x4bef092d), X(0x670b4444), X(0x4c177a6e), X(0x66ed6aa1),
5792 X(0x4c3fdff4), X(0x66cf8120), X(0x4c6839b7), X(0x66b187c3),
5793 X(0x4c9087b1), X(0x66937e91), X(0x4cb8c9dd), X(0x6675658c),
5794 X(0x4ce10034), X(0x66573cbb), X(0x4d092ab0), X(0x66390422),
5795 X(0x4d31494b), X(0x661abbc5), X(0x4d595bfe), X(0x65fc63a9),
5796 X(0x4d8162c4), X(0x65ddfbd3), X(0x4da95d96), X(0x65bf8447),
5797 X(0x4dd14c6e), X(0x65a0fd0b), X(0x4df92f46), X(0x65826622),
5798 X(0x4e210617), X(0x6563bf92), X(0x4e48d0dd), X(0x6545095f),
5799 X(0x4e708f8f), X(0x6526438f), X(0x4e984229), X(0x65076e25),
5800 X(0x4ebfe8a5), X(0x64e88926), X(0x4ee782fb), X(0x64c99498),
5801 X(0x4f0f1126), X(0x64aa907f), X(0x4f369320), X(0x648b7ce0),
5802 X(0x4f5e08e3), X(0x646c59bf), X(0x4f857269), X(0x644d2722),
5803 X(0x4faccfab), X(0x642de50d), X(0x4fd420a4), X(0x640e9386),
5804 X(0x4ffb654d), X(0x63ef3290), X(0x50229da1), X(0x63cfc231),
5805 X(0x5049c999), X(0x63b0426d), X(0x5070e92f), X(0x6390b34a),
5806 X(0x5097fc5e), X(0x637114cc), X(0x50bf031f), X(0x635166f9),
5807 X(0x50e5fd6d), X(0x6331a9d4), X(0x510ceb40), X(0x6311dd64),
5808 X(0x5133cc94), X(0x62f201ac), X(0x515aa162), X(0x62d216b3),
5809 X(0x518169a5), X(0x62b21c7b), X(0x51a82555), X(0x6292130c),
5810 X(0x51ced46e), X(0x6271fa69), X(0x51f576ea), X(0x6251d298),
5811 X(0x521c0cc2), X(0x62319b9d), X(0x524295f0), X(0x6211557e),
5812 X(0x5269126e), X(0x61f1003f), X(0x528f8238), X(0x61d09be5),
5813 X(0x52b5e546), X(0x61b02876), X(0x52dc3b92), X(0x618fa5f7),
5814 X(0x53028518), X(0x616f146c), X(0x5328c1d0), X(0x614e73da),
5815 X(0x534ef1b5), X(0x612dc447), X(0x537514c2), X(0x610d05b7),
5816 X(0x539b2af0), X(0x60ec3830), X(0x53c13439), X(0x60cb5bb7),
5817 X(0x53e73097), X(0x60aa7050), X(0x540d2005), X(0x60897601),
5818 X(0x5433027d), X(0x60686ccf), X(0x5458d7f9), X(0x604754bf),
5819 X(0x547ea073), X(0x60262dd6), X(0x54a45be6), X(0x6004f819),
5820 X(0x54ca0a4b), X(0x5fe3b38d), X(0x54efab9c), X(0x5fc26038),
5821 X(0x55153fd4), X(0x5fa0fe1f), X(0x553ac6ee), X(0x5f7f8d46),
5822 X(0x556040e2), X(0x5f5e0db3), X(0x5585adad), X(0x5f3c7f6b),
5823 X(0x55ab0d46), X(0x5f1ae274), X(0x55d05faa), X(0x5ef936d1),
5824 X(0x55f5a4d2), X(0x5ed77c8a), X(0x561adcb9), X(0x5eb5b3a2),
5825 X(0x56400758), X(0x5e93dc1f), X(0x566524aa), X(0x5e71f606),
5826 X(0x568a34a9), X(0x5e50015d), X(0x56af3750), X(0x5e2dfe29),
5827 X(0x56d42c99), X(0x5e0bec6e), X(0x56f9147e), X(0x5de9cc33),
5828 X(0x571deefa), X(0x5dc79d7c), X(0x5742bc06), X(0x5da5604f),
5829 X(0x57677b9d), X(0x5d8314b1), X(0x578c2dba), X(0x5d60baa7),
5830 X(0x57b0d256), X(0x5d3e5237), X(0x57d5696d), X(0x5d1bdb65),
5831 X(0x57f9f2f8), X(0x5cf95638), X(0x581e6ef1), X(0x5cd6c2b5),
5832 X(0x5842dd54), X(0x5cb420e0), X(0x58673e1b), X(0x5c9170bf),
5833 X(0x588b9140), X(0x5c6eb258), X(0x58afd6bd), X(0x5c4be5b0),
5834 X(0x58d40e8c), X(0x5c290acc), X(0x58f838a9), X(0x5c0621b2),
5835 X(0x591c550e), X(0x5be32a67), X(0x594063b5), X(0x5bc024f0),
5836 X(0x59646498), X(0x5b9d1154), X(0x598857b2), X(0x5b79ef96),
5837 X(0x59ac3cfd), X(0x5b56bfbd), X(0x59d01475), X(0x5b3381ce),
5838 X(0x59f3de12), X(0x5b1035cf), X(0x5a1799d1), X(0x5aecdbc5),
5839 X(0x5a3b47ab), X(0x5ac973b5), X(0x5a5ee79a), X(0x5aa5fda5),
5840 X(0x5a82799a), X(0x5a82799a)
5843 /* [sin((2*i+1)*PI/4096), cos((2*i+1)*PI/4096)], with i = 0 to 511 */
5844 static immutable LOOKUP_T[1024] sincos_lookup1 = [
5845 X(0x001921fb), X(0x7ffffd88), X(0x004b65ee), X(0x7fffe9cb),
5846 X(0x007da9d4), X(0x7fffc251), X(0x00afeda8), X(0x7fff8719),
5847 X(0x00e23160), X(0x7fff3824), X(0x011474f6), X(0x7ffed572),
5848 X(0x0146b860), X(0x7ffe5f03), X(0x0178fb99), X(0x7ffdd4d7),
5849 X(0x01ab3e97), X(0x7ffd36ee), X(0x01dd8154), X(0x7ffc8549),
5850 X(0x020fc3c6), X(0x7ffbbfe6), X(0x024205e8), X(0x7ffae6c7),
5851 X(0x027447b0), X(0x7ff9f9ec), X(0x02a68917), X(0x7ff8f954),
5852 X(0x02d8ca16), X(0x7ff7e500), X(0x030b0aa4), X(0x7ff6bcf0),
5853 X(0x033d4abb), X(0x7ff58125), X(0x036f8a51), X(0x7ff4319d),
5854 X(0x03a1c960), X(0x7ff2ce5b), X(0x03d407df), X(0x7ff1575d),
5855 X(0x040645c7), X(0x7fefcca4), X(0x04388310), X(0x7fee2e30),
5856 X(0x046abfb3), X(0x7fec7c02), X(0x049cfba7), X(0x7feab61a),
5857 X(0x04cf36e5), X(0x7fe8dc78), X(0x05017165), X(0x7fe6ef1c),
5858 X(0x0533ab20), X(0x7fe4ee06), X(0x0565e40d), X(0x7fe2d938),
5859 X(0x05981c26), X(0x7fe0b0b1), X(0x05ca5361), X(0x7fde7471),
5860 X(0x05fc89b8), X(0x7fdc247a), X(0x062ebf22), X(0x7fd9c0ca),
5861 X(0x0660f398), X(0x7fd74964), X(0x06932713), X(0x7fd4be46),
5862 X(0x06c5598a), X(0x7fd21f72), X(0x06f78af6), X(0x7fcf6ce8),
5863 X(0x0729bb4e), X(0x7fcca6a7), X(0x075bea8c), X(0x7fc9ccb2),
5864 X(0x078e18a7), X(0x7fc6df08), X(0x07c04598), X(0x7fc3dda9),
5865 X(0x07f27157), X(0x7fc0c896), X(0x08249bdd), X(0x7fbd9fd0),
5866 X(0x0856c520), X(0x7fba6357), X(0x0888ed1b), X(0x7fb7132b),
5867 X(0x08bb13c5), X(0x7fb3af4e), X(0x08ed3916), X(0x7fb037bf),
5868 X(0x091f5d06), X(0x7facac7f), X(0x09517f8f), X(0x7fa90d8e),
5869 X(0x0983a0a7), X(0x7fa55aee), X(0x09b5c048), X(0x7fa1949e),
5870 X(0x09e7de6a), X(0x7f9dbaa0), X(0x0a19fb04), X(0x7f99ccf4),
5871 X(0x0a4c1610), X(0x7f95cb9a), X(0x0a7e2f85), X(0x7f91b694),
5872 X(0x0ab0475c), X(0x7f8d8de1), X(0x0ae25d8d), X(0x7f895182),
5873 X(0x0b147211), X(0x7f850179), X(0x0b4684df), X(0x7f809dc5),
5874 X(0x0b7895f0), X(0x7f7c2668), X(0x0baaa53b), X(0x7f779b62),
5875 X(0x0bdcb2bb), X(0x7f72fcb4), X(0x0c0ebe66), X(0x7f6e4a5e),
5876 X(0x0c40c835), X(0x7f698461), X(0x0c72d020), X(0x7f64aabf),
5877 X(0x0ca4d620), X(0x7f5fbd77), X(0x0cd6da2d), X(0x7f5abc8a),
5878 X(0x0d08dc3f), X(0x7f55a7fa), X(0x0d3adc4e), X(0x7f507fc7),
5879 X(0x0d6cda53), X(0x7f4b43f2), X(0x0d9ed646), X(0x7f45f47b),
5880 X(0x0dd0d01f), X(0x7f409164), X(0x0e02c7d7), X(0x7f3b1aad),
5881 X(0x0e34bd66), X(0x7f359057), X(0x0e66b0c3), X(0x7f2ff263),
5882 X(0x0e98a1e9), X(0x7f2a40d2), X(0x0eca90ce), X(0x7f247ba5),
5883 X(0x0efc7d6b), X(0x7f1ea2dc), X(0x0f2e67b8), X(0x7f18b679),
5884 X(0x0f604faf), X(0x7f12b67c), X(0x0f923546), X(0x7f0ca2e7),
5885 X(0x0fc41876), X(0x7f067bba), X(0x0ff5f938), X(0x7f0040f6),
5886 X(0x1027d784), X(0x7ef9f29d), X(0x1059b352), X(0x7ef390ae),
5887 X(0x108b8c9b), X(0x7eed1b2c), X(0x10bd6356), X(0x7ee69217),
5888 X(0x10ef377d), X(0x7edff570), X(0x11210907), X(0x7ed94538),
5889 X(0x1152d7ed), X(0x7ed28171), X(0x1184a427), X(0x7ecbaa1a),
5890 X(0x11b66dad), X(0x7ec4bf36), X(0x11e83478), X(0x7ebdc0c6),
5891 X(0x1219f880), X(0x7eb6aeca), X(0x124bb9be), X(0x7eaf8943),
5892 X(0x127d7829), X(0x7ea85033), X(0x12af33ba), X(0x7ea1039b),
5893 X(0x12e0ec6a), X(0x7e99a37c), X(0x1312a230), X(0x7e922fd6),
5894 X(0x13445505), X(0x7e8aa8ac), X(0x137604e2), X(0x7e830dff),
5895 X(0x13a7b1bf), X(0x7e7b5fce), X(0x13d95b93), X(0x7e739e1d),
5896 X(0x140b0258), X(0x7e6bc8eb), X(0x143ca605), X(0x7e63e03b),
5897 X(0x146e4694), X(0x7e5be40c), X(0x149fe3fc), X(0x7e53d462),
5898 X(0x14d17e36), X(0x7e4bb13c), X(0x1503153a), X(0x7e437a9c),
5899 X(0x1534a901), X(0x7e3b3083), X(0x15663982), X(0x7e32d2f4),
5900 X(0x1597c6b7), X(0x7e2a61ed), X(0x15c95097), X(0x7e21dd73),
5901 X(0x15fad71b), X(0x7e194584), X(0x162c5a3b), X(0x7e109a24),
5902 X(0x165dd9f0), X(0x7e07db52), X(0x168f5632), X(0x7dff0911),
5903 X(0x16c0cef9), X(0x7df62362), X(0x16f2443e), X(0x7ded2a47),
5904 X(0x1723b5f9), X(0x7de41dc0), X(0x17552422), X(0x7ddafdce),
5905 X(0x17868eb3), X(0x7dd1ca75), X(0x17b7f5a3), X(0x7dc883b4),
5906 X(0x17e958ea), X(0x7dbf298d), X(0x181ab881), X(0x7db5bc02),
5907 X(0x184c1461), X(0x7dac3b15), X(0x187d6c82), X(0x7da2a6c6),
5908 X(0x18aec0db), X(0x7d98ff17), X(0x18e01167), X(0x7d8f4409),
5909 X(0x19115e1c), X(0x7d85759f), X(0x1942a6f3), X(0x7d7b93da),
5910 X(0x1973ebe6), X(0x7d719eba), X(0x19a52ceb), X(0x7d679642),
5911 X(0x19d669fc), X(0x7d5d7a74), X(0x1a07a311), X(0x7d534b50),
5912 X(0x1a38d823), X(0x7d4908d9), X(0x1a6a0929), X(0x7d3eb30f),
5913 X(0x1a9b361d), X(0x7d3449f5), X(0x1acc5ef6), X(0x7d29cd8c),
5914 X(0x1afd83ad), X(0x7d1f3dd6), X(0x1b2ea43a), X(0x7d149ad5),
5915 X(0x1b5fc097), X(0x7d09e489), X(0x1b90d8bb), X(0x7cff1af5),
5916 X(0x1bc1ec9e), X(0x7cf43e1a), X(0x1bf2fc3a), X(0x7ce94dfb),
5917 X(0x1c240786), X(0x7cde4a98), X(0x1c550e7c), X(0x7cd333f3),
5918 X(0x1c861113), X(0x7cc80a0f), X(0x1cb70f43), X(0x7cbcccec),
5919 X(0x1ce80906), X(0x7cb17c8d), X(0x1d18fe54), X(0x7ca618f3),
5920 X(0x1d49ef26), X(0x7c9aa221), X(0x1d7adb73), X(0x7c8f1817),
5921 X(0x1dabc334), X(0x7c837ad8), X(0x1ddca662), X(0x7c77ca65),
5922 X(0x1e0d84f5), X(0x7c6c06c0), X(0x1e3e5ee5), X(0x7c602fec),
5923 X(0x1e6f342c), X(0x7c5445e9), X(0x1ea004c1), X(0x7c4848ba),
5924 X(0x1ed0d09d), X(0x7c3c3860), X(0x1f0197b8), X(0x7c3014de),
5925 X(0x1f325a0b), X(0x7c23de35), X(0x1f63178f), X(0x7c179467),
5926 X(0x1f93d03c), X(0x7c0b3777), X(0x1fc4840a), X(0x7bfec765),
5927 X(0x1ff532f2), X(0x7bf24434), X(0x2025dcec), X(0x7be5ade6),
5928 X(0x205681f1), X(0x7bd9047c), X(0x208721f9), X(0x7bcc47fa),
5929 X(0x20b7bcfe), X(0x7bbf7860), X(0x20e852f6), X(0x7bb295b0),
5930 X(0x2118e3dc), X(0x7ba59fee), X(0x21496fa7), X(0x7b989719),
5931 X(0x2179f64f), X(0x7b8b7b36), X(0x21aa77cf), X(0x7b7e4c45),
5932 X(0x21daf41d), X(0x7b710a49), X(0x220b6b32), X(0x7b63b543),
5933 X(0x223bdd08), X(0x7b564d36), X(0x226c4996), X(0x7b48d225),
5934 X(0x229cb0d5), X(0x7b3b4410), X(0x22cd12bd), X(0x7b2da2fa),
5935 X(0x22fd6f48), X(0x7b1feee5), X(0x232dc66d), X(0x7b1227d3),
5936 X(0x235e1826), X(0x7b044dc7), X(0x238e646a), X(0x7af660c2),
5937 X(0x23beab33), X(0x7ae860c7), X(0x23eeec78), X(0x7ada4dd8),
5938 X(0x241f2833), X(0x7acc27f7), X(0x244f5e5c), X(0x7abdef25),
5939 X(0x247f8eec), X(0x7aafa367), X(0x24afb9da), X(0x7aa144bc),
5940 X(0x24dfdf20), X(0x7a92d329), X(0x250ffeb7), X(0x7a844eae),
5941 X(0x25401896), X(0x7a75b74f), X(0x25702cb7), X(0x7a670d0d),
5942 X(0x25a03b11), X(0x7a584feb), X(0x25d0439f), X(0x7a497feb),
5943 X(0x26004657), X(0x7a3a9d0f), X(0x26304333), X(0x7a2ba75a),
5944 X(0x26603a2c), X(0x7a1c9ece), X(0x26902b39), X(0x7a0d836d),
5945 X(0x26c01655), X(0x79fe5539), X(0x26effb76), X(0x79ef1436),
5946 X(0x271fda96), X(0x79dfc064), X(0x274fb3ae), X(0x79d059c8),
5947 X(0x277f86b5), X(0x79c0e062), X(0x27af53a6), X(0x79b15435),
5948 X(0x27df1a77), X(0x79a1b545), X(0x280edb23), X(0x79920392),
5949 X(0x283e95a1), X(0x79823f20), X(0x286e49ea), X(0x797267f2),
5950 X(0x289df7f8), X(0x79627e08), X(0x28cd9fc1), X(0x79528167),
5951 X(0x28fd4140), X(0x79427210), X(0x292cdc6d), X(0x79325006),
5952 X(0x295c7140), X(0x79221b4b), X(0x298bffb2), X(0x7911d3e2),
5953 X(0x29bb87bc), X(0x790179cd), X(0x29eb0957), X(0x78f10d0f),
5954 X(0x2a1a847b), X(0x78e08dab), X(0x2a49f920), X(0x78cffba3),
5955 X(0x2a796740), X(0x78bf56f9), X(0x2aa8ced3), X(0x78ae9fb0),
5956 X(0x2ad82fd2), X(0x789dd5cb), X(0x2b078a36), X(0x788cf94c),
5957 X(0x2b36ddf7), X(0x787c0a36), X(0x2b662b0e), X(0x786b088c),
5958 X(0x2b957173), X(0x7859f44f), X(0x2bc4b120), X(0x7848cd83),
5959 X(0x2bf3ea0d), X(0x7837942b), X(0x2c231c33), X(0x78264849),
5960 X(0x2c52478a), X(0x7814e9df), X(0x2c816c0c), X(0x780378f1),
5961 X(0x2cb089b1), X(0x77f1f581), X(0x2cdfa071), X(0x77e05f91),
5962 X(0x2d0eb046), X(0x77ceb725), X(0x2d3db928), X(0x77bcfc3f),
5963 X(0x2d6cbb10), X(0x77ab2ee2), X(0x2d9bb5f6), X(0x77994f11),
5964 X(0x2dcaa9d5), X(0x77875cce), X(0x2df996a3), X(0x7775581d),
5965 X(0x2e287c5a), X(0x776340ff), X(0x2e575af3), X(0x77511778),
5966 X(0x2e863267), X(0x773edb8b), X(0x2eb502ae), X(0x772c8d3a),
5967 X(0x2ee3cbc1), X(0x771a2c88), X(0x2f128d99), X(0x7707b979),
5968 X(0x2f41482e), X(0x76f5340e), X(0x2f6ffb7a), X(0x76e29c4b),
5969 X(0x2f9ea775), X(0x76cff232), X(0x2fcd4c19), X(0x76bd35c7),
5970 X(0x2ffbe95d), X(0x76aa670d), X(0x302a7f3a), X(0x76978605),
5971 X(0x30590dab), X(0x768492b4), X(0x308794a6), X(0x76718d1c),
5972 X(0x30b61426), X(0x765e7540), X(0x30e48c22), X(0x764b4b23),
5973 X(0x3112fc95), X(0x76380ec8), X(0x31416576), X(0x7624c031),
5974 X(0x316fc6be), X(0x76115f63), X(0x319e2067), X(0x75fdec60),
5975 X(0x31cc7269), X(0x75ea672a), X(0x31fabcbd), X(0x75d6cfc5),
5976 X(0x3228ff5c), X(0x75c32634), X(0x32573a3f), X(0x75af6a7b),
5977 X(0x32856d5e), X(0x759b9c9b), X(0x32b398b3), X(0x7587bc98),
5978 X(0x32e1bc36), X(0x7573ca75), X(0x330fd7e1), X(0x755fc635),
5979 X(0x333debab), X(0x754bafdc), X(0x336bf78f), X(0x7537876c),
5980 X(0x3399fb85), X(0x75234ce8), X(0x33c7f785), X(0x750f0054),
5981 X(0x33f5eb89), X(0x74faa1b3), X(0x3423d78a), X(0x74e63108),
5982 X(0x3451bb81), X(0x74d1ae55), X(0x347f9766), X(0x74bd199f),
5983 X(0x34ad6b32), X(0x74a872e8), X(0x34db36df), X(0x7493ba34),
5984 X(0x3508fa66), X(0x747eef85), X(0x3536b5be), X(0x746a12df),
5985 X(0x356468e2), X(0x74552446), X(0x359213c9), X(0x744023bc),
5986 X(0x35bfb66e), X(0x742b1144), X(0x35ed50c9), X(0x7415ece2),
5987 X(0x361ae2d3), X(0x7400b69a), X(0x36486c86), X(0x73eb6e6e),
5988 X(0x3675edd9), X(0x73d61461), X(0x36a366c6), X(0x73c0a878),
5989 X(0x36d0d746), X(0x73ab2ab4), X(0x36fe3f52), X(0x73959b1b),
5990 X(0x372b9ee3), X(0x737ff9ae), X(0x3758f5f2), X(0x736a4671),
5991 X(0x37864477), X(0x73548168), X(0x37b38a6d), X(0x733eaa96),
5992 X(0x37e0c7cc), X(0x7328c1ff), X(0x380dfc8d), X(0x7312c7a5),
5993 X(0x383b28a9), X(0x72fcbb8c), X(0x38684c19), X(0x72e69db7),
5994 X(0x389566d6), X(0x72d06e2b), X(0x38c278d9), X(0x72ba2cea),
5995 X(0x38ef821c), X(0x72a3d9f7), X(0x391c8297), X(0x728d7557),
5996 X(0x39497a43), X(0x7276ff0d), X(0x39766919), X(0x7260771b),
5997 X(0x39a34f13), X(0x7249dd86), X(0x39d02c2a), X(0x72333251),
5998 X(0x39fd0056), X(0x721c7580), X(0x3a29cb91), X(0x7205a716),
5999 X(0x3a568dd4), X(0x71eec716), X(0x3a834717), X(0x71d7d585),
6000 X(0x3aaff755), X(0x71c0d265), X(0x3adc9e86), X(0x71a9bdba),
6001 X(0x3b093ca3), X(0x71929789), X(0x3b35d1a5), X(0x717b5fd3),
6002 X(0x3b625d86), X(0x7164169d), X(0x3b8ee03e), X(0x714cbbeb),
6003 X(0x3bbb59c7), X(0x71354fc0), X(0x3be7ca1a), X(0x711dd220),
6004 X(0x3c143130), X(0x7106430e), X(0x3c408f03), X(0x70eea28e),
6005 X(0x3c6ce38a), X(0x70d6f0a4), X(0x3c992ec0), X(0x70bf2d53),
6006 X(0x3cc5709e), X(0x70a7589f), X(0x3cf1a91c), X(0x708f728b),
6007 X(0x3d1dd835), X(0x70777b1c), X(0x3d49fde1), X(0x705f7255),
6008 X(0x3d761a19), X(0x70475839), X(0x3da22cd7), X(0x702f2ccd),
6009 X(0x3dce3614), X(0x7016f014), X(0x3dfa35c8), X(0x6ffea212),
6010 X(0x3e262bee), X(0x6fe642ca), X(0x3e52187f), X(0x6fcdd241),
6011 X(0x3e7dfb73), X(0x6fb5507a), X(0x3ea9d4c3), X(0x6f9cbd79),
6012 X(0x3ed5a46b), X(0x6f841942), X(0x3f016a61), X(0x6f6b63d8),
6013 X(0x3f2d26a0), X(0x6f529d40), X(0x3f58d921), X(0x6f39c57d),
6014 X(0x3f8481dd), X(0x6f20dc92), X(0x3fb020ce), X(0x6f07e285),
6015 X(0x3fdbb5ec), X(0x6eeed758), X(0x40074132), X(0x6ed5bb10),
6016 X(0x4032c297), X(0x6ebc8db0), X(0x405e3a16), X(0x6ea34f3d),
6017 X(0x4089a7a8), X(0x6e89ffb9), X(0x40b50b46), X(0x6e709f2a),
6018 X(0x40e064ea), X(0x6e572d93), X(0x410bb48c), X(0x6e3daaf8),
6019 X(0x4136fa27), X(0x6e24175c), X(0x416235b2), X(0x6e0a72c5),
6020 X(0x418d6729), X(0x6df0bd35), X(0x41b88e84), X(0x6dd6f6b1),
6021 X(0x41e3abbc), X(0x6dbd1f3c), X(0x420ebecb), X(0x6da336dc),
6022 X(0x4239c7aa), X(0x6d893d93), X(0x4264c653), X(0x6d6f3365),
6023 X(0x428fbabe), X(0x6d551858), X(0x42baa4e6), X(0x6d3aec6e),
6024 X(0x42e584c3), X(0x6d20afac), X(0x43105a50), X(0x6d066215),
6025 X(0x433b2585), X(0x6cec03af), X(0x4365e65b), X(0x6cd1947c),
6026 X(0x43909ccd), X(0x6cb71482), X(0x43bb48d4), X(0x6c9c83c3),
6027 X(0x43e5ea68), X(0x6c81e245), X(0x44108184), X(0x6c67300b),
6028 X(0x443b0e21), X(0x6c4c6d1a), X(0x44659039), X(0x6c319975),
6029 X(0x449007c4), X(0x6c16b521), X(0x44ba74bd), X(0x6bfbc021),
6030 X(0x44e4d71c), X(0x6be0ba7b), X(0x450f2edb), X(0x6bc5a431),
6031 X(0x45397bf4), X(0x6baa7d49), X(0x4563be60), X(0x6b8f45c7),
6032 X(0x458df619), X(0x6b73fdae), X(0x45b82318), X(0x6b58a503),
6033 X(0x45e24556), X(0x6b3d3bcb), X(0x460c5cce), X(0x6b21c208),
6034 X(0x46366978), X(0x6b0637c1), X(0x46606b4e), X(0x6aea9cf8),
6035 X(0x468a624a), X(0x6acef1b2), X(0x46b44e65), X(0x6ab335f4),
6036 X(0x46de2f99), X(0x6a9769c1), X(0x470805df), X(0x6a7b8d1e),
6037 X(0x4731d131), X(0x6a5fa010), X(0x475b9188), X(0x6a43a29a),
6038 X(0x478546de), X(0x6a2794c1), X(0x47aef12c), X(0x6a0b7689),
6039 X(0x47d8906d), X(0x69ef47f6), X(0x48022499), X(0x69d3090e),
6040 X(0x482badab), X(0x69b6b9d3), X(0x48552b9b), X(0x699a5a4c),
6041 X(0x487e9e64), X(0x697dea7b), X(0x48a805ff), X(0x69616a65),
6042 X(0x48d16265), X(0x6944da10), X(0x48fab391), X(0x6928397e),
6043 X(0x4923f97b), X(0x690b88b5), X(0x494d341e), X(0x68eec7b9),
6044 X(0x49766373), X(0x68d1f68f), X(0x499f8774), X(0x68b5153a),
6045 X(0x49c8a01b), X(0x689823bf), X(0x49f1ad61), X(0x687b2224),
6046 X(0x4a1aaf3f), X(0x685e106c), X(0x4a43a5b0), X(0x6840ee9b),
6047 X(0x4a6c90ad), X(0x6823bcb7), X(0x4a957030), X(0x68067ac3),
6048 X(0x4abe4433), X(0x67e928c5), X(0x4ae70caf), X(0x67cbc6c0),
6049 X(0x4b0fc99d), X(0x67ae54ba), X(0x4b387af9), X(0x6790d2b6),
6050 X(0x4b6120bb), X(0x677340ba), X(0x4b89badd), X(0x67559eca),
6051 X(0x4bb24958), X(0x6737ecea), X(0x4bdacc28), X(0x671a2b20),
6052 X(0x4c034345), X(0x66fc596f), X(0x4c2baea9), X(0x66de77dc),
6053 X(0x4c540e4e), X(0x66c0866d), X(0x4c7c622d), X(0x66a28524),
6054 X(0x4ca4aa41), X(0x66847408), X(0x4ccce684), X(0x6666531d),
6055 X(0x4cf516ee), X(0x66482267), X(0x4d1d3b7a), X(0x6629e1ec),
6056 X(0x4d455422), X(0x660b91af), X(0x4d6d60df), X(0x65ed31b5),
6057 X(0x4d9561ac), X(0x65cec204), X(0x4dbd5682), X(0x65b0429f),
6058 X(0x4de53f5a), X(0x6591b38c), X(0x4e0d1c30), X(0x657314cf),
6059 X(0x4e34ecfc), X(0x6554666d), X(0x4e5cb1b9), X(0x6535a86b),
6060 X(0x4e846a60), X(0x6516dacd), X(0x4eac16eb), X(0x64f7fd98),
6061 X(0x4ed3b755), X(0x64d910d1), X(0x4efb4b96), X(0x64ba147d),
6062 X(0x4f22d3aa), X(0x649b08a0), X(0x4f4a4f89), X(0x647bed3f),
6063 X(0x4f71bf2e), X(0x645cc260), X(0x4f992293), X(0x643d8806),
6064 X(0x4fc079b1), X(0x641e3e38), X(0x4fe7c483), X(0x63fee4f8),
6065 X(0x500f0302), X(0x63df7c4d), X(0x50363529), X(0x63c0043b),
6066 X(0x505d5af1), X(0x63a07cc7), X(0x50847454), X(0x6380e5f6),
6067 X(0x50ab814d), X(0x63613fcd), X(0x50d281d5), X(0x63418a50),
6068 X(0x50f975e6), X(0x6321c585), X(0x51205d7b), X(0x6301f171),
6069 X(0x5147388c), X(0x62e20e17), X(0x516e0715), X(0x62c21b7e),
6070 X(0x5194c910), X(0x62a219aa), X(0x51bb7e75), X(0x628208a1),
6071 X(0x51e22740), X(0x6261e866), X(0x5208c36a), X(0x6241b8ff),
6072 X(0x522f52ee), X(0x62217a72), X(0x5255d5c5), X(0x62012cc2),
6073 X(0x527c4bea), X(0x61e0cff5), X(0x52a2b556), X(0x61c06410),
6074 X(0x52c91204), X(0x619fe918), X(0x52ef61ee), X(0x617f5f12),
6075 X(0x5315a50e), X(0x615ec603), X(0x533bdb5d), X(0x613e1df0),
6076 X(0x536204d7), X(0x611d66de), X(0x53882175), X(0x60fca0d2),
6077 X(0x53ae3131), X(0x60dbcbd1), X(0x53d43406), X(0x60bae7e1),
6078 X(0x53fa29ed), X(0x6099f505), X(0x542012e1), X(0x6078f344),
6079 X(0x5445eedb), X(0x6057e2a2), X(0x546bbdd7), X(0x6036c325),
6080 X(0x54917fce), X(0x601594d1), X(0x54b734ba), X(0x5ff457ad),
6081 X(0x54dcdc96), X(0x5fd30bbc), X(0x5502775c), X(0x5fb1b104),
6082 X(0x55280505), X(0x5f90478a), X(0x554d858d), X(0x5f6ecf53),
6083 X(0x5572f8ed), X(0x5f4d4865), X(0x55985f20), X(0x5f2bb2c5),
6084 X(0x55bdb81f), X(0x5f0a0e77), X(0x55e303e6), X(0x5ee85b82),
6085 X(0x5608426e), X(0x5ec699e9), X(0x562d73b2), X(0x5ea4c9b3),
6086 X(0x565297ab), X(0x5e82eae5), X(0x5677ae54), X(0x5e60fd84),
6087 X(0x569cb7a8), X(0x5e3f0194), X(0x56c1b3a1), X(0x5e1cf71c),
6088 X(0x56e6a239), X(0x5dfade20), X(0x570b8369), X(0x5dd8b6a7),
6089 X(0x5730572e), X(0x5db680b4), X(0x57551d80), X(0x5d943c4e),
6090 X(0x5779d65b), X(0x5d71e979), X(0x579e81b8), X(0x5d4f883b),
6091 X(0x57c31f92), X(0x5d2d189a), X(0x57e7afe4), X(0x5d0a9a9a),
6092 X(0x580c32a7), X(0x5ce80e41), X(0x5830a7d6), X(0x5cc57394),
6093 X(0x58550f6c), X(0x5ca2ca99), X(0x58796962), X(0x5c801354),
6094 X(0x589db5b3), X(0x5c5d4dcc), X(0x58c1f45b), X(0x5c3a7a05),
6095 X(0x58e62552), X(0x5c179806), X(0x590a4893), X(0x5bf4a7d2),
6096 X(0x592e5e19), X(0x5bd1a971), X(0x595265df), X(0x5bae9ce7),
6097 X(0x59765fde), X(0x5b8b8239), X(0x599a4c12), X(0x5b68596d),
6098 X(0x59be2a74), X(0x5b452288), X(0x59e1faff), X(0x5b21dd90),
6099 X(0x5a05bdae), X(0x5afe8a8b), X(0x5a29727b), X(0x5adb297d),
6100 X(0x5a4d1960), X(0x5ab7ba6c), X(0x5a70b258), X(0x5a943d5e),
6104 /* ******************************************************************
6105 function: residue backend 0, 1 and 2 implementation
6106 ****************************************************************** */
6108 struct vorbis_look_residue0 {
6109 vorbis_info_residue0 *info;
6110 int map;
6112 int parts;
6113 int stages;
6114 codebook *fullbooks;
6115 codebook *phrasebook;
6116 codebook ***partbooks;
6118 int partvals;
6119 int **decodemap;
6123 void res0_free_info(vorbis_info_residue *i) nothrow @trusted @nogc {
6124 vorbis_info_residue0 *info=cast(vorbis_info_residue0 *)i;
6125 if(info){
6126 memset(info, 0, (*info).sizeof);
6127 ogg_free_(info);
6131 void res0_free_look(vorbis_look_residue *i) nothrow @trusted @nogc {
6132 int j;
6133 if(i){
6135 vorbis_look_residue0 *look=cast(vorbis_look_residue0 *)i;
6137 for(j=0;j<look.parts;j++)
6138 if(look.partbooks[j])ogg_free_(look.partbooks[j]);
6139 ogg_free_(look.partbooks);
6140 for(j=0;j<look.partvals;j++)
6141 ogg_free_(look.decodemap[j]);
6142 ogg_free_(look.decodemap);
6144 memset(look, 0, (*look).sizeof);
6145 ogg_free_(look);
6149 private int res_ilog(uint v) nothrow @trusted @nogc {
6150 int ret=0;
6151 while(v){
6152 ret++;
6153 v>>=1;
6155 return(ret);
6158 private int icount(uint v) nothrow @trusted @nogc {
6159 int ret=0;
6160 while(v){
6161 ret+=v&1;
6162 v>>=1;
6164 return(ret);
6167 /* vorbis_info is for range checking */
6168 vorbis_info_residue *res0_unpack(vorbis_info *vi, oggpack_buffer *opb) nothrow @trusted @nogc {
6169 int j, acc=0;
6170 vorbis_info_residue0 *info;
6171 info=cast(vorbis_info_residue0 *)ogg_calloc_(1, (*info).sizeof);
6172 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
6174 info.begin=oggpack_read(opb, 24);
6175 info.end=oggpack_read(opb, 24);
6176 info.grouping=oggpack_read(opb, 24)+1;
6177 info.partitions=oggpack_read(opb, 6)+1;
6178 info.groupbook=oggpack_read(opb, 8);
6180 /* check for premature EOP */
6181 if(info.groupbook<0)goto errout;
6183 for(j=0;j<info.partitions;j++){
6184 int cascade=oggpack_read(opb, 3);
6185 int cflag=oggpack_read(opb, 1);
6186 if(cflag<0) goto errout;
6187 if(cflag){
6188 int c=oggpack_read(opb, 5);
6189 if(c<0) goto errout;
6190 cascade|=(c<<3);
6192 info.secondstages[j]=cascade;
6194 acc+=icount(cascade);
6196 for(j=0;j<acc;j++){
6197 int book=oggpack_read(opb, 8);
6198 if(book<0) goto errout;
6199 info.booklist[j]=book;
6202 if(info.groupbook>=ci.books)goto errout;
6203 for(j=0;j<acc;j++){
6204 if(info.booklist[j]>=ci.books)goto errout;
6205 if(ci.book_param[info.booklist[j]].maptype==0)goto errout;
6208 /* verify the phrasebook is not specifying an impossible or
6209 inconsistent partitioning scheme. */
6210 /* modify the phrasebook ranging check from r16327; an early beta
6211 encoder had a bug where it used an oversized phrasebook by
6212 accident. These files should continue to be playable, but don't
6213 allow an exploit */
6215 int entries = ci.book_param[info.groupbook].entries;
6216 int dim = ci.book_param[info.groupbook].dim;
6217 int partvals = 1;
6218 if (dim<1) goto errout;
6219 while(dim>0){
6220 partvals *= info.partitions;
6221 if(partvals > entries) goto errout;
6222 dim--;
6224 info.partvals = partvals;
6227 return(info);
6228 errout:
6229 res0_free_info(info);
6230 return(null);
6233 vorbis_look_residue *res0_look(vorbis_dsp_state *vd, vorbis_info_mode *vm,
6234 vorbis_info_residue *vr) nothrow @trusted @nogc {
6235 vorbis_info_residue0 *info=cast(vorbis_info_residue0 *)vr;
6236 vorbis_look_residue0 *look;
6237 look=cast(vorbis_look_residue0 *)ogg_calloc_(1, (*look).sizeof);
6238 codec_setup_info *ci=cast(codec_setup_info *)vd.vi.codec_setup;
6240 int j, k, acc=0;
6241 int dim;
6242 int maxstage=0;
6243 look.info=info;
6244 look.map=vm.mapping;
6246 look.parts=info.partitions;
6247 look.fullbooks=ci.fullbooks;
6248 look.phrasebook=ci.fullbooks+info.groupbook;
6249 dim=look.phrasebook.dim;
6251 look.partbooks=cast(codebook ***)ogg_calloc_(look.parts, (*look.partbooks).sizeof);
6253 for(j=0;j<look.parts;j++){
6254 int stages=res_ilog(info.secondstages[j]);
6255 if(stages){
6256 if(stages>maxstage)maxstage=stages;
6257 look.partbooks[j]=cast(codebook **)ogg_calloc_(stages, (*look.partbooks[j]).sizeof);
6258 for(k=0;k<stages;k++)
6259 if(info.secondstages[j]&(1<<k)){
6260 look.partbooks[j][k]=ci.fullbooks+info.booklist[acc++];
6261 version(TRAIN_RES__) {
6262 look.training_data[k][j]=calloc(look.partbooks[j][k].entries, (***look.training_data).sizeof);
6268 look.partvals=look.parts;
6269 for(j=1;j<dim;j++)look.partvals*=look.parts;
6270 look.stages=maxstage;
6271 look.decodemap=cast(int **)ogg_malloc_(look.partvals*(*look.decodemap).sizeof);
6272 for(j=0;j<look.partvals;j++){
6273 trm_long val=j;
6274 trm_long mult=look.partvals/look.parts;
6275 look.decodemap[j]=cast(int *)ogg_malloc_(dim*(*look.decodemap[j]).sizeof);
6276 for(k=0;k<dim;k++){
6277 trm_long deco=val/mult;
6278 val-=deco*mult;
6279 mult/=look.parts;
6280 look.decodemap[j][k]=deco;
6284 return(look);
6288 /* a truncated packet here just means 'stop working'; it's not an error */
6289 private int xx01inverse_(vorbis_block *vb, vorbis_look_residue *vl,
6290 ogg_int32_t **in_, int ch,
6291 trm_long function (codebook *, ogg_int32_t *, oggpack_buffer *, int, int) nothrow @trusted @nogc decodepart) nothrow @trusted @nogc {
6293 import core.stdc.stdlib : alloca;
6294 trm_long i, j, k, l, s;
6295 vorbis_look_residue0 *look=cast(vorbis_look_residue0 *)vl;
6296 vorbis_info_residue0 *info=look.info;
6298 /* move all this setup out later */
6299 int samples_per_partition=info.grouping;
6300 int partitions_per_word=look.phrasebook.dim;
6301 int max=vb.pcmend>>1;
6302 int end=(info.end<max?info.end:max);
6303 int n=end-info.begin;
6305 if(n>0){
6306 int partvals=n/samples_per_partition;
6307 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
6308 int ***partword;
6309 partword=cast(int ***)alloca(ch*(*partword).sizeof);
6311 for(j=0;j<ch;j++)
6312 partword[j]=cast(int **)vorbis_block_alloc_(vb, partwords*(*partword[j]).sizeof);
6314 for(s=0;s<look.stages;s++){
6316 /* each loop decodes on partition codeword containing
6317 partitions_pre_word partitions */
6318 for(i=0, l=0;i<partvals;l++){
6319 if(s==0){
6320 /* fetch the partition word for each channel */
6321 for(j=0;j<ch;j++){
6322 int temp=vorbis_book_decode(look.phrasebook, &vb.opb);
6323 if(temp==-1 || temp>=info.partvals)goto eopbreak;
6324 partword[j][l]=look.decodemap[temp];
6325 if(partword[j][l]==null)goto errout;
6329 /* now we decode residual values for the partitions */
6330 for(k=0;k<partitions_per_word && i<partvals;k++, i++)
6331 for(j=0;j<ch;j++){
6332 trm_long offset=info.begin+i*samples_per_partition;
6333 if(info.secondstages[partword[j][l][k]]&(1<<s)){
6334 codebook *stagebook=look.partbooks[partword[j][l][k]][s];
6335 if(stagebook){
6336 if(decodepart(stagebook, in_[j]+offset, &vb.opb, samples_per_partition, -8)==-1)goto eopbreak;
6343 errout:
6344 eopbreak:
6345 return(0);
6348 int res0_inverse(vorbis_block *vb, vorbis_look_residue *vl,
6349 ogg_int32_t **in_, int *nonzero, int ch) nothrow @trusted @nogc {
6350 int i, used=0;
6351 for(i=0;i<ch;i++)
6352 if(nonzero[i])
6353 in_[used++]=in_[i];
6354 if(used)
6355 return(xx01inverse_(vb, vl, in_, used, &vorbis_book_decodevs_add));
6356 else
6357 return(0);
6360 int res1_inverse(vorbis_block *vb, vorbis_look_residue *vl,
6361 ogg_int32_t **in_, int *nonzero, int ch) nothrow @trusted @nogc {
6362 int i, used=0;
6363 for(i=0;i<ch;i++)
6364 if(nonzero[i])
6365 in_[used++]=in_[i];
6366 if(used)
6367 return(xx01inverse_(vb, vl, in_, used, &vorbis_book_decodev_add));
6368 else
6369 return(0);
6372 /* duplicate code here as speed is somewhat more important */
6373 int res2_inverse(vorbis_block *vb, vorbis_look_residue *vl,
6374 ogg_int32_t **in_, int *nonzero, int ch) nothrow @trusted @nogc {
6375 trm_long i, k, l, s;
6376 vorbis_look_residue0 *look=cast(vorbis_look_residue0 *)vl;
6377 vorbis_info_residue0 *info=look.info;
6379 /* move all this setup out later */
6380 int samples_per_partition=info.grouping;
6381 int partitions_per_word=look.phrasebook.dim;
6382 int max=(vb.pcmend*ch)>>1;
6383 int end=(info.end<max?info.end:max);
6384 int n=end-info.begin;
6386 if(n>0){
6388 int partvals=n/samples_per_partition;
6389 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
6390 int **partword;
6391 partword=cast(int **)vorbis_block_alloc_(vb, partwords*(*partword).sizeof);
6392 int beginoff=info.begin/ch;
6394 for(i=0;i<ch;i++)if(nonzero[i])break;
6395 if(i==ch)return(0); /* no nonzero vectors */
6397 samples_per_partition/=ch;
6399 for(s=0;s<look.stages;s++){
6400 for(i=0, l=0;i<partvals;l++){
6402 if(s==0){
6403 /* fetch the partition word */
6404 int temp=vorbis_book_decode(look.phrasebook, &vb.opb);
6405 if(temp==-1 || temp>=info.partvals)goto eopbreak;
6406 partword[l]=look.decodemap[temp];
6407 if(partword[l]==null)goto errout;
6410 /* now we decode residual values for the partitions */
6411 for(k=0;k<partitions_per_word && i<partvals;k++, i++)
6412 if(info.secondstages[partword[l][k]]&(1<<s)){
6413 codebook *stagebook=look.partbooks[partword[l][k]][s];
6415 if(stagebook){
6416 if(vorbis_book_decodevv_add(stagebook, in_,
6417 i*samples_per_partition+beginoff, ch,
6418 &vb.opb,
6419 samples_per_partition, -8)==-1)
6420 goto eopbreak;
6426 errout:
6427 eopbreak:
6428 return(0);
6432 static immutable vorbis_func_residue residue0_exportbundle={
6433 &res0_unpack,
6434 &res0_look,
6435 &res0_free_info,
6436 &res0_free_look,
6437 &res0_inverse
6440 static immutable vorbis_func_residue residue1_exportbundle={
6441 &res0_unpack,
6442 &res0_look,
6443 &res0_free_info,
6444 &res0_free_look,
6445 &res1_inverse
6448 static immutable vorbis_func_residue residue2_exportbundle={
6449 &res0_unpack,
6450 &res0_look,
6451 &res0_free_info,
6452 &res0_free_look,
6453 &res2_inverse
6457 /* ******************************************************************
6458 function: basic shared codebook operations
6459 ****************************************************************** */
6461 /* ** pack/unpack helpers **************************************** */
6462 /* 32 bit float (not IEEE; nonnormalized mantissa +
6463 biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
6464 Why not IEEE? It's just not that important here. */
6466 enum VQ_FEXP = 10;
6467 enum VQ_FMAN = 21;
6468 enum VQ_FEXP_BIAS = 768; /* bias toward values smaller than 1. */
6470 private ogg_int32_t float32_unpack_(trm_long val, int *point){
6471 trm_long mant=val&0x1fffff;
6472 int sign=val&0x80000000;
6473 trm_long exp =(val&0x7fe00000L)>>VQ_FMAN;
6475 exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS;
6477 if(mant){
6478 while(!(mant&0x40000000)){
6479 mant<<=1;
6480 exp-=1;
6483 if(sign)mant= -mant;
6484 }else{
6485 sign=0;
6486 exp=-9999;
6489 *point=exp;
6490 return mant;
6493 /* given a list of word lengths, generate a list of codewords. Works
6494 for length ordered or unordered, always assigns the lowest valued
6495 codewords first. Extended to handle unused entries (length 0) */
6496 ogg_uint32_t *make_words_(const(trm_long)*l, trm_long n, trm_long sparsecount){
6497 trm_long i, j, count=0;
6498 ogg_uint32_t[33] marker;
6499 ogg_uint32_t *r;
6500 r=cast(ogg_uint32_t *)ogg_malloc_((sparsecount?sparsecount:n)*(*r).sizeof);
6501 memset(marker.ptr, 0, (marker).sizeof);
6503 for(i=0;i<n;i++){
6504 trm_long length=l[i];
6505 if(length>0){
6506 ogg_uint32_t entry=marker[length];
6508 /* when we claim a node for an entry, we also claim the nodes
6509 below it (pruning off the imagined tree that may have dangled
6510 from it) as well as blocking the use of any nodes directly
6511 above for leaves */
6513 /* update ourself */
6514 if(length<32 && (entry>>length)){
6515 /* error condition; the lengths must specify an overpopulated tree */
6516 ogg_free_(r);
6517 return(null);
6519 r[count++]=entry;
6521 /* Look to see if the next shorter marker points to the node
6522 above. if so, update it and repeat. */
6524 for(j=length;j>0;j--){
6526 if(marker[j]&1){
6527 /* have to jump branches */
6528 if(j==1)
6529 marker[1]++;
6530 else
6531 marker[j]=marker[j-1]<<1;
6532 break; /* invariant says next upper marker would already
6533 have been moved if it was on the same path */
6535 marker[j]++;
6539 /* prune the tree; the implicit invariant says all the longer
6540 markers were dangling from our just-taken node. Dangle them
6541 from our *new* node. */
6542 for(j=length+1;j<33;j++)
6543 if((marker[j]>>1) == entry){
6544 entry=marker[j];
6545 marker[j]=marker[j-1]<<1;
6546 }else
6547 break;
6548 }else
6549 if(sparsecount==0)count++;
6552 /* sanity check the huffman tree; an underpopulated tree must be
6553 rejected. The only exception is the one-node pseudo-nil tree,
6554 which appears to be underpopulated because the tree doesn't
6555 really exist; there's only one possible 'codeword' or zero bits,
6556 but the above tree-gen code doesn't mark that. */
6557 if(sparsecount != 1){
6558 for(i=1;i<33;i++)
6559 if(marker[i] & (0xffffffffU>>(32-i))){
6560 ogg_free_(r);
6561 return(null);
6565 /* bitreverse the words because our bitwise packer/unpacker is LSb
6566 endian */
6567 for(i=0, count=0;i<n;i++){
6568 ogg_uint32_t temp=0;
6569 for(j=0;j<l[i];j++){
6570 temp<<=1;
6571 temp|=(r[count]>>j)&1;
6574 if(sparsecount){
6575 if(l[i])
6576 r[count++]=temp;
6577 }else
6578 r[count++]=temp;
6581 return(r);
6584 /* there might be a straightforward one-line way to do the below
6585 that's portable and totally safe against roundoff, but I haven't
6586 thought of it. Therefore, we opt on the side of caution */
6587 trm_long book_maptype1_quantvals_(const static_codebook *b){
6588 /* get us a starting hint, we'll polish it below */
6589 int bits=ilog_(b.entries);
6590 int vals=b.entries>>((bits-1)*(b.dim-1)/b.dim);
6592 while(1){
6593 trm_long acc=1;
6594 trm_long acc1=1;
6595 int i;
6596 for(i=0;i<b.dim;i++){
6597 acc*=vals;
6598 acc1*=vals+1;
6600 if(acc<=b.entries && acc1>b.entries){
6601 return(vals);
6602 }else{
6603 if(acc>b.entries){
6604 vals--;
6605 }else{
6606 vals++;
6612 /* different than what book_unquantize_ does for mainline:
6613 we repack the book in a fixed point format that shares the same
6614 binary point. Upon first use, we can shift point if needed */
6616 /* we need to deal with two map types: in map type 1, the values are
6617 generated algorithmically (each column of the vector counts through
6618 the values in the quant vector). in map type 2, all the values came
6619 in in an explicit list. Both value lists must be unpacked */
6621 ogg_int32_t *book_unquantize_(const static_codebook *b, int n, int *sparsemap,
6622 int *maxpoint){
6623 trm_long j, k, count=0;
6624 if(b.maptype==1 || b.maptype==2){
6625 int quantvals;
6626 int minpoint, delpoint;
6627 ogg_int32_t mindel=float32_unpack_(b.q_min, &minpoint);
6628 ogg_int32_t delta=float32_unpack_(b.q_delta, &delpoint);
6629 ogg_int32_t *r;
6630 r=cast(ogg_int32_t *)ogg_calloc_(n*b.dim, (*r).sizeof);
6631 int *rp;
6632 rp=cast(int *)ogg_calloc_(n*b.dim, (*rp).sizeof);
6634 *maxpoint=minpoint;
6636 /* maptype 1 and 2 both use a quantized value vector, but
6637 different sizes */
6638 switch(b.maptype){
6639 case 1:
6640 /* most of the time, entries%dimensions == 0, but we need to be
6641 well defined. We define that the possible vales at each
6642 scalar is values == entries/dim. If entries%dim != 0, we'll
6643 have 'too few' values (values*dim<entries), which means that
6644 we'll have 'left over' entries; left over entries use zeroed
6645 values (and are wasted). So don't generate codebooks like
6646 that */
6647 quantvals=book_maptype1_quantvals_(b);
6648 for(j=0;j<b.entries;j++){
6649 if((sparsemap && b.lengthlist[j]) || !sparsemap){
6650 ogg_int32_t last=0;
6651 int lastpoint=0;
6652 int indexdiv=1;
6653 for(k=0;k<b.dim;k++){
6654 import std.math : abs;
6655 int index= (j/indexdiv)%quantvals;
6656 int point=0;
6657 int val=VFLOAT_MULTI(delta, delpoint, abs(b.quantlist[index]), &point);
6659 val=VFLOAT_ADD(mindel, minpoint, val, point, &point);
6660 val=VFLOAT_ADD(last, lastpoint, val, point, &point);
6662 if(b.q_sequencep){
6663 last=val;
6664 lastpoint=point;
6667 if(sparsemap){
6668 r[sparsemap[count]*b.dim+k]=val;
6669 rp[sparsemap[count]*b.dim+k]=point;
6670 }else{
6671 r[count*b.dim+k]=val;
6672 rp[count*b.dim+k]=point;
6674 if(*maxpoint<point)*maxpoint=point;
6675 indexdiv*=quantvals;
6677 count++;
6681 break;
6682 case 2:
6683 for(j=0;j<b.entries;j++){
6684 if((sparsemap && b.lengthlist[j]) || !sparsemap){
6685 ogg_int32_t last=0;
6686 int lastpoint=0;
6688 for(k=0;k<b.dim;k++){
6689 import std.math : abs;
6690 int point=0;
6691 int val=VFLOAT_MULTI(delta, delpoint, abs(b.quantlist[j*b.dim+k]), &point);
6693 val=VFLOAT_ADD(mindel, minpoint, val, point, &point);
6694 val=VFLOAT_ADD(last, lastpoint, val, point, &point);
6696 if(b.q_sequencep){
6697 last=val;
6698 lastpoint=point;
6701 if(sparsemap){
6702 r[sparsemap[count]*b.dim+k]=val;
6703 rp[sparsemap[count]*b.dim+k]=point;
6704 }else{
6705 r[count*b.dim+k]=val;
6706 rp[count*b.dim+k]=point;
6708 if(*maxpoint<point)*maxpoint=point;
6710 count++;
6713 break;
6714 default: break;
6717 for(j=0;j<n*b.dim;j++)
6718 if(rp[j]<*maxpoint)
6719 r[j]>>=*maxpoint-rp[j];
6721 ogg_free_(rp);
6722 return(r);
6724 return(null);
6727 void vorbis_staticbook_destroy(static_codebook *b) nothrow @trusted @nogc {
6728 if(b.quantlist)ogg_free_(b.quantlist);
6729 if(b.lengthlist)ogg_free_(b.lengthlist);
6730 memset(b, 0, (*b).sizeof);
6731 ogg_free_(b);
6734 void vorbis_book_clear(codebook *b) nothrow @trusted @nogc {
6735 /* static book is not cleared; we're likely called on the lookup and
6736 the static codebook belongs to the info struct */
6737 if(b.valuelist)ogg_free_(b.valuelist);
6738 if(b.codelist)ogg_free_(b.codelist);
6740 if(b.dec_index)ogg_free_(b.dec_index);
6741 if(b.dec_codelengths)ogg_free_(b.dec_codelengths);
6742 if(b.dec_firsttable)ogg_free_(b.dec_firsttable);
6744 memset(b, 0, (*b).sizeof);
6748 private ogg_uint32_t bitreverse(ogg_uint32_t x){
6749 x= ((x>>16)&0x0000ffffU) | ((x<<16)&0xffff0000U);
6750 x= ((x>> 8)&0x00ff00ffU) | ((x<< 8)&0xff00ff00U);
6751 x= ((x>> 4)&0x0f0f0f0fU) | ((x<< 4)&0xf0f0f0f0U);
6752 x= ((x>> 2)&0x33333333U) | ((x<< 2)&0xccccccccU);
6753 return((x>> 1)&0x55555555U) | ((x<< 1)&0xaaaaaaaaU);
6757 extern(C) int sort32a(const void *a, const void *b) nothrow @trusted @nogc {
6758 return (**cast(ogg_uint32_t **)a>**cast(ogg_uint32_t **)b)-(**cast(ogg_uint32_t **)a<**cast(ogg_uint32_t **)b);
6761 /* decode codebook arrangement is more heavily optimized than encode */
6762 int vorbis_book_init_decode(codebook *c, const static_codebook *s){
6763 import core.stdc.stdlib : alloca;
6764 int i, j, n=0, tabn;
6765 int *sortindex;
6766 memset(c, 0, (*c).sizeof);
6768 /* count actually used entries */
6769 for(i=0;i<s.entries;i++)
6770 if(s.lengthlist[i]>0)
6771 n++;
6773 c.entries=s.entries;
6774 c.used_entries=n;
6775 c.dim=s.dim;
6777 if(n>0){
6778 /* two different remappings go on here.
6780 First, we collapse the likely sparse codebook down only to
6781 actually represented values/words. This collapsing needs to be
6782 indexed as map-valueless books are used to encode original entry
6783 positions as integers.
6785 Second, we reorder all vectors, including the entry index above,
6786 by sorted bitreversed codeword to allow treeless decode. */
6788 /* perform sort */
6789 ogg_uint32_t *codes=make_words_(s.lengthlist, s.entries, c.used_entries);
6790 ogg_uint32_t **codep;
6791 codep=cast(ogg_uint32_t **)alloca((*codep).sizeof*n);
6793 if(codes==null)goto err_out;
6795 for(i=0;i<n;i++){
6796 codes[i]=bitreverse(codes[i]);
6797 codep[i]=codes+i;
6800 qsort(codep, n, (*codep).sizeof, &sort32a);
6802 sortindex=cast(int *)alloca(n*(*sortindex).sizeof);
6803 c.codelist=cast(ogg_uint32_t *)ogg_malloc_(n*(*c.codelist).sizeof);
6804 /* the index is a reverse index */
6805 for(i=0;i<n;i++){
6806 auto position=codep[i]-codes;
6807 sortindex[position]=i;
6810 for(i=0;i<n;i++)
6811 c.codelist[sortindex[i]]=codes[i];
6812 ogg_free_(codes);
6816 c.valuelist=book_unquantize_(s, n, sortindex, &c.binarypoint);
6817 c.dec_index=cast(int *)ogg_malloc_(n*(*c.dec_index).sizeof);
6819 for(n=0, i=0;i<s.entries;i++)
6820 if(s.lengthlist[i]>0)
6821 c.dec_index[sortindex[n++]]=i;
6823 c.dec_codelengths=cast(char *)ogg_malloc_(n*(*c.dec_codelengths).sizeof);
6824 for(n=0, i=0;i<s.entries;i++)
6825 if(s.lengthlist[i]>0)
6826 c.dec_codelengths[sortindex[n++]]=cast(char)s.lengthlist[i];
6828 c.dec_firsttablen=ilog_(c.used_entries)-4; /* this is magic */
6829 if(c.dec_firsttablen<5)c.dec_firsttablen=5;
6830 if(c.dec_firsttablen>8)c.dec_firsttablen=8;
6832 tabn=1<<c.dec_firsttablen;
6833 c.dec_firsttable=cast(ogg_uint32_t *)ogg_calloc_(tabn, (*c.dec_firsttable).sizeof);
6834 c.dec_maxlength=0;
6836 for(i=0;i<n;i++){
6837 if(c.dec_maxlength<c.dec_codelengths[i])
6838 c.dec_maxlength=c.dec_codelengths[i];
6839 if(c.dec_codelengths[i]<=c.dec_firsttablen){
6840 ogg_uint32_t orig=bitreverse(c.codelist[i]);
6841 for(j=0;j<(1<<(c.dec_firsttablen-c.dec_codelengths[i]));j++)
6842 c.dec_firsttable[orig|(j<<c.dec_codelengths[i])]=i+1;
6846 /* now fill in 'unused' entries in the firsttable with hi/lo search
6847 hints for the non-direct-hits */
6849 ogg_uint32_t mask=0xfffffffeU<<(31-c.dec_firsttablen);
6850 trm_long lo=0, hi=0;
6852 for(i=0;i<tabn;i++){
6853 ogg_uint32_t word=i<<(32-c.dec_firsttablen);
6854 if(c.dec_firsttable[bitreverse(word)]==0){
6855 while((lo+1)<n && c.codelist[lo+1]<=word)lo++;
6856 while( hi<n && word>=(c.codelist[hi]&mask))hi++;
6858 /* we only actually have 15 bits per hint to play with here.
6859 In order to overflow gracefully (nothing breaks, efficiency
6860 just drops), encode as the difference from the extremes. */
6862 trm_ulong loval=lo;
6863 trm_ulong hival=n-hi;
6865 if(loval>0x7fff)loval=0x7fff;
6866 if(hival>0x7fff)hival=0x7fff;
6867 c.dec_firsttable[bitreverse(word)]=
6868 0x80000000U | (loval<<15) | hival;
6875 return(0);
6876 err_out:
6877 vorbis_book_clear(c);
6878 return(-1);
6882 /* ******************************************************************
6883 function: single-block PCM synthesis
6884 ****************************************************************** */
6886 private int vorbis_synthesis1_(vorbis_block *vb, ogg_packet *op, int decodep){
6887 vorbis_dsp_state *vd= vb ? vb.vd : null;
6888 private_state *b= vd ? cast(private_state *)vd.backend_state: null;
6889 vorbis_info *vi= vd ? vd.vi : null;
6890 codec_setup_info *ci= vi ? cast(codec_setup_info *)vi.codec_setup : null;
6891 oggpack_buffer *opb=vb ? &vb.opb : null;
6892 int type, mode, i;
6894 if (!vd || !b || !vi || !ci || !opb) {
6895 return OV_EBADPACKET;
6898 /* first things first. Make sure decode is ready */
6899 vorbis_block_ripcord_(vb);
6900 oggpack_readinit(opb, op.packet, op.bytes);
6902 /* Check the packet type */
6903 if(oggpack_read(opb, 1)!=0){
6904 /* Oops. This is not an audio data packet */
6905 return(OV_ENOTAUDIO);
6908 /* read our mode and pre/post windowsize */
6909 mode=oggpack_read(opb, b.modebits);
6910 if(mode==-1)return(OV_EBADPACKET);
6912 vb.mode=mode;
6913 if(!ci.mode_param[mode]){
6914 return(OV_EBADPACKET);
6917 vb.W=ci.mode_param[mode].blockflag;
6918 if(vb.W){
6919 vb.lW=oggpack_read(opb, 1);
6920 vb.nW=oggpack_read(opb, 1);
6921 if(vb.nW==-1) return(OV_EBADPACKET);
6922 }else{
6923 vb.lW=0;
6924 vb.nW=0;
6927 /* more setup */
6928 vb.granulepos=op.granulepos;
6929 vb.sequence=op.packetno; /* first block is third packet */
6930 vb.eofflag=op.e_o_s;
6932 if(decodep){
6933 /* alloc pcm passback storage */
6934 vb.pcmend=ci.blocksizes[vb.W];
6935 vb.pcm=cast(ogg_int32_t **)vorbis_block_alloc_(vb, (*vb.pcm).sizeof*vi.channels);
6936 for(i=0;i<vi.channels;i++)
6937 vb.pcm[i]=cast(ogg_int32_t *)vorbis_block_alloc_(vb, vb.pcmend*(*vb.pcm[i]).sizeof);
6939 /* unpack_header enforces range checking */
6940 type=ci.map_type[ci.mode_param[mode].mapping];
6942 return(mapping_P_[type].inverse(vb, b.mode[mode]));
6943 }else{
6944 /* no pcm */
6945 vb.pcmend=0;
6946 vb.pcm=null;
6948 return(0);
6952 int vorbis_synthesis(vorbis_block *vb, ogg_packet *op){
6953 return vorbis_synthesis1_(vb, op, 1);
6956 /* used to track pcm position without actually performing decode.
6957 Useful for sequential 'fast forward' */
6958 int vorbis_synthesis_trackonly(vorbis_block *vb, ogg_packet *op){
6959 return vorbis_synthesis1_(vb, op, 0);
6962 trm_long vorbis_packet_blocksize(vorbis_info *vi, ogg_packet *op){
6963 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
6964 oggpack_buffer opb;
6965 int mode;
6967 oggpack_readinit(&opb, op.packet, op.bytes);
6969 /* Check the packet type */
6970 if(oggpack_read(&opb, 1)!=0){
6971 /* Oops. This is not an audio data packet */
6972 return(OV_ENOTAUDIO);
6976 int modebits=0;
6977 int v=ci.modes;
6978 while(v>1){
6979 modebits++;
6980 v>>=1;
6983 /* read our mode and pre/post windowsize */
6984 mode=oggpack_read(&opb, modebits);
6986 if(mode==-1 || !ci.mode_param[mode])return(OV_EBADPACKET);
6987 return(ci.blocksizes[ci.mode_param[mode].blockflag]);
6991 /* ******************************************************************
6992 function: window functions
6993 ****************************************************************** */
6996 const(void)* vorbis_window_(int type, int left){
6998 switch(type){
6999 case 0:
7001 switch(left){
7002 case 32:
7003 return vwin64.ptr;
7004 case 64:
7005 return vwin128.ptr;
7006 case 128:
7007 return vwin256.ptr;
7008 case 256:
7009 return vwin512.ptr;
7010 case 512:
7011 return vwin1024.ptr;
7012 case 1024:
7013 return vwin2048.ptr;
7014 case 2048:
7015 return vwin4096.ptr;
7016 case 4096:
7017 return vwin8192.ptr;
7018 default:
7019 return null;
7021 break;
7022 default:
7023 return null;
7027 void vorbis_apply_window_(ogg_int32_t *d, /*const void *window_p[2], */ const(void)** window_p,
7028 trm_long *blocksizes,
7029 int lW, int W, int nW) nothrow @trusted @nogc {
7031 immutable(LOOKUP_T)*[2] window=[cast(immutable(LOOKUP_T)*)window_p[0], cast(immutable(LOOKUP_T)*)window_p[1]];
7032 trm_long n=blocksizes[W];
7033 trm_long ln=blocksizes[lW];
7034 trm_long rn=blocksizes[nW];
7036 trm_long leftbegin=n/4-ln/4;
7037 trm_long leftend=leftbegin+ln/2;
7039 trm_long rightbegin=n/2+n/4-rn/4;
7040 trm_long rightend=rightbegin+rn/2;
7042 int i, p;
7044 for(i=0;i<leftbegin;i++)
7045 d[i]=0;
7047 for(p=0;i<leftend;i++, p++)
7048 d[i]=MULT31(d[i], window[lW][p]);
7050 for(i=rightbegin, p=rn/2-1;i<rightend;i++, p--)
7051 d[i]=MULT31(d[i], window[nW][p]);
7053 for(;i<n;i++)
7054 d[i]=0;
7058 /* ******************************************************************
7059 function: maintain the info structure, info <. header packets
7060 ****************************************************************** */
7062 public void vorbis_comment_init(vorbis_comment *vc) nothrow @trusted @nogc {
7063 memset(vc, 0, (*vc).sizeof);
7066 /* This is more or less the same as strncasecmp - but that doesn't exist
7067 * everywhere, and this is a fairly trivial function, so we include it */
7068 private int tagcompare (const(char)* s1, const(char)* s2, usize n) nothrow @trusted @nogc {
7069 int c=0;
7070 while(c < n){
7071 char c0 = s1[c];
7072 char c1 = s2[c];
7073 if (c0 >= 'a' && c0 <= 'z') c0 -= 32;
7074 if (c1 >= 'a' && c1 <= 'z') c1 -= 32;
7075 if (c0 != c1) return !0;
7076 c++;
7078 return 0;
7082 public char *vorbis_comment_query (vorbis_comment *vc, char *tag, int count) nothrow @trusted @nogc {
7083 import core.stdc.stdlib : alloca;
7084 trm_long i;
7085 int found = 0;
7086 auto taglen = strlen(tag)+1; /* +1 for the = we append */
7087 char *fulltag = cast(char *)alloca(taglen+ 1);
7089 strcpy(fulltag, tag);
7090 strcat(fulltag, "=");
7092 for(i=0;i<vc.comments;i++){
7093 if(!tagcompare(vc.user_comments[i], fulltag, taglen)){
7094 if(count == found)
7095 /* We return a pointer to the data, not a copy */
7096 return vc.user_comments[i] + taglen;
7097 else
7098 found++;
7101 return null; /* didn't find anything */
7105 public int vorbis_comment_query_count (vorbis_comment *vc, char *tag) nothrow @trusted @nogc {
7106 import core.stdc.stdlib : alloca;
7107 int i, count=0;
7108 auto taglen = strlen(tag)+1; /* +1 for the = we append */
7109 char *fulltag = cast(char *)alloca(taglen+1);
7110 strcpy(fulltag, tag);
7111 strcat(fulltag, "=");
7113 for(i=0;i<vc.comments;i++){
7114 if(!tagcompare(vc.user_comments[i], fulltag, taglen))
7115 count++;
7118 return count;
7122 public void vorbis_comment_clear (vorbis_comment *vc) nothrow @trusted @nogc {
7123 if(vc){
7124 trm_long i;
7125 if(vc.user_comments){
7126 for(i=0;i<vc.comments;i++)
7127 if(vc.user_comments[i])ogg_free_(vc.user_comments[i]);
7128 ogg_free_(vc.user_comments);
7130 if(vc.comment_lengths)ogg_free_(vc.comment_lengths);
7131 if(vc.vendor)ogg_free_(vc.vendor);
7132 memset(vc, 0, (*vc).sizeof);
7136 /// blocksize 0 is guaranteed to be short, 1 is guarantted to be trm_long. They may be equal, but short will never ge greater than long
7137 public int vorbis_info_blocksize (vorbis_info *vi, int zo) nothrow @trusted @nogc {
7138 codec_setup_info *ci = cast(codec_setup_info *)vi.codec_setup;
7139 return ci ? ci.blocksizes[zo] : -1;
7142 /// used by synthesis, which has a full, alloced vi
7143 public void vorbis_info_init (vorbis_info *vi) nothrow @trusted @nogc {
7144 memset(vi, 0, (*vi).sizeof);
7145 vi.codec_setup=cast(codec_setup_info *)ogg_calloc_(1, (codec_setup_info).sizeof);
7149 public void vorbis_info_clear (vorbis_info *vi) nothrow @trusted @nogc {
7150 codec_setup_info *ci=cast(codec_setup_info *)vi.codec_setup;
7151 int i;
7153 if(ci){
7155 for(i=0;i<ci.modes;i++)
7156 if(ci.mode_param[i])ogg_free_(ci.mode_param[i]);
7158 for(i=0;i<ci.maps;i++) /* unpack does the range checking */
7159 if(ci.map_param[i])
7160 mapping_P_[ci.map_type[i]].free_info(ci.map_param[i]);
7162 for(i=0;i<ci.floors;i++) /* unpack does the range checking */
7163 if(ci.floor_param[i])
7164 floor_P_[ci.floor_type[i]].free_info(ci.floor_param[i]);
7166 for(i=0;i<ci.residues;i++) /* unpack does the range checking */
7167 if(ci.residue_param[i])
7168 residue_P_[ci.residue_type[i]].free_info(ci.residue_param[i]);
7170 for(i=0;i<ci.books;i++){
7171 if(ci.book_param[i]){
7172 /* knows if the book was not alloced */
7173 vorbis_staticbook_destroy(ci.book_param[i]);
7175 if(ci.fullbooks)
7176 vorbis_book_clear(ci.fullbooks+i);
7178 if(ci.fullbooks)
7179 ogg_free_(ci.fullbooks);
7181 ogg_free_(ci);
7184 memset(vi, 0, (*vi).sizeof);
7188 /* ******************************************************************
7189 function: stdio-based convenience library for opening/seeking/decoding
7190 ****************************************************************** */
7192 enum CHUNKSIZE = 65535;
7193 enum READSIZE = 1024;
7194 /* The function prototypes for the callbacks are basically the same as for
7195 * the stdio functions fread, fseek, fclose, ftell.
7196 * The one difference is that the FILE* arguments have been replaced with
7197 * a void* - this is to be used as a pointer to whatever internal data these
7198 * functions might need. In the stdio case, it's just a FILE* cast to a void*
7200 * If you use other functions, check the docs for these functions and return
7201 * the right values. For seek_func(), you *MUST* return -1 if the stream is
7202 * unseekable
7204 static if (!XoggTremorHasVFS) {
7206 public struct ov_callbacks {
7207 usize function (void *ptr, usize size, usize nmemb, void *datasource) read_func;
7208 int function (void *datasource, ogg_int64_t offset, int whence) seek_func;
7209 int function (void *datasource) close_func;
7210 trm_long function (void *datasource) tell_func;
7214 enum NOTOPEN = 0;
7215 enum PARTOPEN = 1;
7216 enum OPENED = 2;
7217 enum STREAMSET = 3;
7218 enum INITSET = 4;
7221 public struct OggVorbis_File {
7222 static if (XoggTremorHasVFS) {
7223 VFile datasource;
7224 } else {
7225 void* datasource; /// Pointer to a FILE *, etc.
7227 int seekable; /// DO NOT CHANGE!
7228 private ogg_int64_t offset;
7229 private ogg_int64_t end;
7230 private ogg_sync_state oy;
7232 // If the FILE handle isn't seekable (eg, a pipe), only the current stream appears
7233 private int links;
7234 private ogg_int64_t* offsets;
7235 private ogg_int64_t* dataoffsets;
7236 private ogg_uint32_t* serialnos;
7237 private ogg_int64_t* pcmlengths;
7238 vorbis_info* vi; /// DO NOT CHANGE!
7239 vorbis_comment* vc; /// DO NOT CHANGE!
7241 // Decoding working state local storage
7242 private ogg_int64_t pcm_offset;
7243 private int ready_state;
7244 private ogg_uint32_t current_serialno;
7245 private int current_link;
7247 private ogg_int64_t bittrack;
7248 private ogg_int64_t samptrack;
7250 private ogg_stream_state os; // take physical pages, weld into a logical stream of packets
7251 private vorbis_dsp_state vd; // central working state for the packet.PCM decoder
7252 private vorbis_block vb; // local working space for packet.PCM decode
7254 static if (!XoggTremorHasVFS) {
7255 ov_callbacks callbacks; /// DO NOT CHANGE!
7259 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
7260 one logical bitstream arranged end to end (the only form of Ogg
7261 multiplexing allowed in a Vorbis bitstream; grouping [parallel
7262 multiplexing] is not allowed in Vorbis) */
7264 /* A Vorbis file can be played beginning to end (streamed) without
7265 worrying ahead of time about chaining (see decoder_example.c). If
7266 we have the whole file, however, and want random access
7267 (seeking/scrubbing) or desire to know the total length/time of a
7268 file, we need to account for the possibility of chaining. */
7270 /* We can handle things a number of ways; we can determine the entire
7271 bitstream structure right off the bat, or find pieces on demand.
7272 This example determines and caches structure for the entire
7273 bitstream, but builds a virtual decoder on the fly when moving
7274 between links in the chain. */
7276 /* There are also different ways to implement seeking. Enough
7277 information exists in an Ogg bitstream to seek to
7278 sample-granularity positions in the output. Or, one can seek by
7279 picking some portion of the stream roughly in the desired area if
7280 we only want coarse navigation through the stream. */
7282 /* ***********************************************************************
7283 * Many, many internal helpers. The intention is not to be confusing;
7284 * rampant duplication and monolithic function implementation would be
7285 * harder to understand anyway. The high level functions are last. Begin
7286 * grokking near the end of the file */
7289 // read a little more data from the file/pipe into the ogg_sync framer
7290 private trm_long get_data_ (OggVorbis_File* vf) {
7291 static if (XoggTremorHasVFS) {
7292 if (!vf.datasource.isOpen) return -1;
7293 try {
7294 char* buffer = ogg_sync_buffer(&vf.oy, READSIZE);
7295 auto rd = vf.datasource.rawRead(buffer[0..READSIZE]);
7296 if (rd.length > 0) ogg_sync_wrote(&vf.oy, cast(uint)rd.length);
7297 //if (rd.length == 0 && errno) return -1;
7298 return cast(uint)rd.length;
7299 } catch (Exception) {
7300 vf.datasource = VFile.init;
7301 return -1;
7303 } else {
7304 errno = 0;
7305 if (!(vf.callbacks.read_func))return -1;
7306 if (vf.datasource) {
7307 char *buffer = ogg_sync_buffer(&vf.oy, READSIZE);
7308 /*trm_long*/int bytes = cast(int)vf.callbacks.read_func(buffer, 1, READSIZE, vf.datasource);
7309 if (bytes > 0) ogg_sync_wrote(&vf.oy, bytes);
7310 if (bytes == 0 && errno) return -1;
7311 return bytes;
7312 } else {
7313 return 0;
7318 // save a tiny smidge of verbosity to make the code more readable
7319 private int seek_helper_ (OggVorbis_File* vf, ogg_int64_t offset) {
7320 static if (XoggTremorHasVFS) {
7321 if (!vf.datasource.isOpen) return OV_EFAULT;
7322 try {
7323 if (vf.offset != offset) {
7324 vf.datasource.seek(offset);
7325 vf.offset = offset;
7326 ogg_sync_reset(&vf.oy);
7328 return 0;
7329 } catch (Exception) {
7330 vf.datasource = VFile.init;
7331 return OV_EREAD;
7333 } else {
7334 if (vf.datasource) {
7335 // only seek if the file position isn't already there */
7336 if (vf.offset != offset) {
7337 if (vf.callbacks.seek_func is null || vf.callbacks.seek_func(vf.datasource, offset, SEEK_SET) == -1) return OV_EREAD;
7338 vf.offset = offset;
7339 ogg_sync_reset(&vf.oy);
7341 } else {
7342 // shouldn't happen unless someone writes a broken callback
7343 return OV_EFAULT;
7345 return 0;
7349 /* The read/seek functions track absolute position within the stream */
7351 /* from the head of the stream, get the next page. boundary specifies
7352 if the function is allowed to fetch more data from the stream (and
7353 how much) or only use internally buffered data.
7355 boundary: -1) unbounded search
7356 0) read no additional data; use cached only
7357 n) search for a new page beginning for n bytes
7359 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
7360 n) found a page at absolute offset n */
7362 private ogg_int64_t get_next_page_(OggVorbis_File *vf, ogg_page *og,
7363 ogg_int64_t boundary){
7364 if(boundary>0)boundary+=vf.offset;
7365 while(1){
7366 trm_long more;
7368 if(boundary>0 && vf.offset>=boundary)return(OV_FALSE);
7369 more=ogg_sync_pageseek(&vf.oy, og);
7371 if(more<0){
7372 /* skipped n bytes */
7373 vf.offset-=more;
7374 }else{
7375 if(more==0){
7376 /* send more paramedics */
7377 if(!boundary)return(OV_FALSE);
7379 trm_long ret=get_data_(vf);
7380 if(ret==0)return(OV_EOF);
7381 if(ret<0)return(OV_EREAD);
7383 }else{
7384 /* got a page. Return the offset at the page beginning,
7385 advance the internal offset past the page end */
7386 ogg_int64_t ret=vf.offset;
7387 vf.offset+=more;
7388 return(ret);
7395 /* find the latest page beginning before the passed in position. Much
7396 dirtier than the above as Ogg doesn't have any backward search
7397 linkage. no 'readp' as it will certainly have to read. */
7398 /* returns offset or OV_EREAD, OV_FAULT */
7399 private ogg_int64_t get_prev_page_(OggVorbis_File *vf, ogg_int64_t begin, ogg_page *og){
7400 ogg_int64_t end = begin;
7401 ogg_int64_t ret;
7402 ogg_int64_t offset=-1;
7404 while(offset==-1){
7405 begin-=CHUNKSIZE;
7406 if(begin<0)
7407 begin=0;
7409 ret=seek_helper_(vf, begin);
7410 if(ret)return(ret);
7412 while(vf.offset<end){
7413 memset(og, 0, (*og).sizeof);
7414 ret=get_next_page_(vf, og, end-vf.offset);
7415 if(ret==OV_EREAD)return(OV_EREAD);
7416 if(ret<0){
7417 break;
7418 }else{
7419 offset=ret;
7424 /* In a fully compliant, non-multiplexed stream, we'll still be
7425 holding the last page. In multiplexed (or noncompliant streams),
7426 we will probably have to re-read the last page we saw */
7427 if(og.header_len==0){
7428 ret=seek_helper_(vf, offset);
7429 if(ret)return(ret);
7431 ret=get_next_page_(vf, og, CHUNKSIZE);
7432 if(ret<0)
7433 /* this shouldn't be possible */
7434 return(OV_EFAULT);
7437 return(offset);
7440 private void add_serialno_(ogg_page *og, ogg_uint32_t **serialno_list, int *n){
7441 ogg_uint32_t s = ogg_page_serialno(og);
7442 (*n)++;
7444 if(*serialno_list){
7445 *serialno_list = cast(ogg_uint32_t*)ogg_realloc_(*serialno_list, (**serialno_list).sizeof*(*n));
7446 }else{
7447 *serialno_list = cast(ogg_uint32_t*)ogg_malloc_((**serialno_list).sizeof);
7450 (*serialno_list)[(*n)-1] = s;
7453 /* returns nonzero if found */
7454 private int lookup_serialno_(ogg_uint32_t s, ogg_uint32_t *serialno_list, int n){
7455 if(serialno_list){
7456 while(n--){
7457 if(*serialno_list == s) return 1;
7458 serialno_list++;
7461 return 0;
7464 private int lookup_page_serialno_(ogg_page *og, ogg_uint32_t *serialno_list, int n){
7465 ogg_uint32_t s = ogg_page_serialno(og);
7466 return lookup_serialno_(s, serialno_list, n);
7469 /* performs the same search as get_prev_page_, but prefers pages of
7470 the specified serial number. If a page of the specified serialno is
7471 spotted during the seek-back-and-read-forward, it will return the
7472 info of last page of the matching serial number instead of the very
7473 last page. If no page of the specified serialno is seen, it will
7474 return the info of last page and alter *serialno. */
7475 private ogg_int64_t get_prev_page_serial_(OggVorbis_File *vf, ogg_int64_t begin,
7476 ogg_uint32_t *serial_list, int serial_n,
7477 int *serialno, ogg_int64_t *granpos){
7478 ogg_page og;
7479 ogg_int64_t end=begin;
7480 ogg_int64_t ret;
7482 ogg_int64_t prefoffset=-1;
7483 ogg_int64_t offset=-1;
7484 ogg_int64_t ret_serialno=-1;
7485 ogg_int64_t ret_gran=-1;
7487 while(offset==-1){
7488 begin-=CHUNKSIZE;
7489 if(begin<0)
7490 begin=0;
7492 ret=seek_helper_(vf, begin);
7493 if(ret)return(ret);
7495 while(vf.offset<end){
7496 ret=get_next_page_(vf, &og, end-vf.offset);
7497 if(ret==OV_EREAD)return(OV_EREAD);
7498 if(ret<0){
7499 break;
7500 }else{
7501 ret_serialno=ogg_page_serialno(&og);
7502 ret_gran=ogg_page_granulepos(&og);
7503 offset=ret;
7505 if(cast(ogg_uint32_t)ret_serialno == *serialno){
7506 prefoffset=ret;
7507 *granpos=ret_gran;
7510 if(!lookup_serialno_(cast(ogg_uint32_t)ret_serialno, serial_list, serial_n)){
7511 /* we fell off the end of the link, which means we seeked
7512 back too far and shouldn't have been looking in that link
7513 to begin with. If we found the preferred serial number,
7514 forget that we saw it. */
7515 prefoffset=-1;
7521 /* we're not interested in the page... just the serialno and granpos. */
7522 if(prefoffset>=0)return(prefoffset);
7524 *serialno = cast(int)ret_serialno;
7525 *granpos = ret_gran;
7526 return(offset);
7530 /* uses the local ogg_stream storage in vf; this is important for
7531 non-streaming input sources */
7532 private int fetch_headers_(OggVorbis_File *vf, vorbis_info *vi, vorbis_comment *vc,
7533 ogg_uint32_t **serialno_list, int *serialno_n,
7534 ogg_page *og_ptr){
7535 ogg_page og;
7536 ogg_packet op;
7537 int i, ret;
7538 int allbos=0;
7540 if(!og_ptr){
7541 ogg_int64_t llret=get_next_page_(vf, &og, CHUNKSIZE);
7542 if(llret==OV_EREAD)return(OV_EREAD);
7543 if(llret<0)return(OV_ENOTVORBIS);
7544 og_ptr=&og;
7547 vorbis_info_init(vi);
7548 vorbis_comment_init(vc);
7549 vf.ready_state=OPENED;
7551 /* extract the serialnos of all BOS pages + the first set of vorbis
7552 headers we see in the link */
7554 while(ogg_page_bos(og_ptr)){
7555 if(serialno_list){
7556 if(lookup_page_serialno_(og_ptr, *serialno_list, *serialno_n)){
7557 /* a dupe serialnumber in an initial header packet set == invalid stream */
7558 if(*serialno_list)ogg_free_(*serialno_list);
7559 *serialno_list=null;
7560 *serialno_n=0;
7561 ret=OV_EBADHEADER;
7562 goto bail_header;
7565 add_serialno_(og_ptr, serialno_list, serialno_n);
7568 if(vf.ready_state<STREAMSET){
7569 /* we don't have a vorbis stream in this link yet, so begin
7570 prospective stream setup. We need a stream to get packets */
7571 ogg_stream_reset_serialno(&vf.os, ogg_page_serialno(og_ptr));
7572 ogg_stream_pagein(&vf.os, og_ptr);
7574 if(ogg_stream_packetout(&vf.os, &op) > 0 &&
7575 vorbis_synthesis_idheader(&op)){
7576 /* vorbis header; continue setup */
7577 vf.ready_state=STREAMSET;
7578 if((ret=vorbis_synthesis_headerin(vi, vc, &op)) != 0){
7579 ret=OV_EBADHEADER;
7580 goto bail_header;
7585 /* get next page */
7587 ogg_int64_t llret=get_next_page_(vf, og_ptr, CHUNKSIZE);
7588 if(llret==OV_EREAD){
7589 ret=OV_EREAD;
7590 goto bail_header;
7592 if(llret<0){
7593 ret=OV_ENOTVORBIS;
7594 goto bail_header;
7597 /* if this page also belongs to our vorbis stream, submit it and break */
7598 if(vf.ready_state==STREAMSET &&
7599 vf.os.serialno == ogg_page_serialno(og_ptr)){
7600 ogg_stream_pagein(&vf.os, og_ptr);
7601 break;
7606 if(vf.ready_state!=STREAMSET){
7607 ret = OV_ENOTVORBIS;
7608 goto bail_header;
7611 while(1){
7613 i=0;
7614 while(i<2){ /* get a page loop */
7616 while(i<2){ /* get a packet loop */
7618 int result=ogg_stream_packetout(&vf.os, &op);
7619 if(result==0)break;
7620 if(result==-1){
7621 ret=OV_EBADHEADER;
7622 goto bail_header;
7625 if((ret=vorbis_synthesis_headerin(vi, vc, &op)) != 0)
7626 goto bail_header;
7628 i++;
7631 while(i<2){
7632 if(get_next_page_(vf, og_ptr, CHUNKSIZE)<0){
7633 ret=OV_EBADHEADER;
7634 goto bail_header;
7637 /* if this page belongs to the correct stream, go parse it */
7638 if(vf.os.serialno == ogg_page_serialno(og_ptr)){
7639 ogg_stream_pagein(&vf.os, og_ptr);
7640 break;
7643 /* if we never see the final vorbis headers before the link
7644 ends, abort */
7645 if(ogg_page_bos(og_ptr)){
7646 if(allbos){
7647 ret = OV_EBADHEADER;
7648 goto bail_header;
7649 }else
7650 allbos=1;
7653 /* otherwise, keep looking */
7657 return 0;
7660 bail_header:
7661 vorbis_info_clear(vi);
7662 vorbis_comment_clear(vc);
7663 vf.ready_state=OPENED;
7665 return ret;
7668 /* Starting from current cursor position, get initial PCM offset of
7669 next page. Consumes the page in the process without decoding
7670 audio, however this is only called during stream parsing upon
7671 seekable open. */
7672 private ogg_int64_t initial_pcmoffset_(OggVorbis_File *vf, vorbis_info *vi){
7673 ogg_page og;
7674 ogg_int64_t accumulated=0;
7675 trm_long lastblock=-1;
7676 int result;
7677 int serialno = vf.os.serialno;
7679 while(1){
7680 ogg_packet op;
7681 if(get_next_page_(vf, &og, -1)<0)
7682 break; /* should not be possible unless the file is truncated/mangled */
7684 if(ogg_page_bos(&og)) break;
7685 if(ogg_page_serialno(&og)!=serialno) continue;
7687 /* count blocksizes of all frames in the page */
7688 ogg_stream_pagein(&vf.os, &og);
7689 while((result=ogg_stream_packetout(&vf.os, &op)) != 0){
7690 if(result>0){ /* ignore holes */
7691 trm_long thisblock=vorbis_packet_blocksize(vi, &op);
7692 if(lastblock!=-1)
7693 accumulated+=(lastblock+thisblock)>>2;
7694 lastblock=thisblock;
7698 if(ogg_page_granulepos(&og)!=-1){
7699 /* pcm offset of last packet on the first audio page */
7700 accumulated= ogg_page_granulepos(&og)-accumulated;
7701 break;
7705 /* less than zero? This is a stream with samples trimmed off
7706 the beginning, a normal occurrence; set the offset to zero */
7707 if(accumulated<0)accumulated=0;
7709 return accumulated;
7712 /* finds each bitstream link one at a time using a bisection search
7713 (has to begin by knowing the offset of the lb's initial page).
7714 Recurses for each link so it can alloc the link storage after
7715 finding them all, then unroll and fill the cache at the same time */
7716 private int bisect_forward_serialno_(OggVorbis_File *vf,
7717 ogg_int64_t begin,
7718 ogg_int64_t searched,
7719 ogg_int64_t end,
7720 ogg_int64_t endgran,
7721 int endserial,
7722 ogg_uint32_t *currentno_list,
7723 int currentnos,
7724 trm_long m){
7725 ogg_int64_t pcmoffset;
7726 ogg_int64_t dataoffset=searched;
7727 ogg_int64_t endsearched=end;
7728 ogg_int64_t next=end;
7729 ogg_int64_t searchgran=-1;
7730 ogg_page og;
7731 ogg_int64_t ret, last;
7732 int serialno = vf.os.serialno;
7734 /* invariants:
7735 we have the headers and serialnos for the link beginning at 'begin'
7736 we have the offset and granpos of the last page in the file (potentially
7737 not a page we care about)
7740 /* Is the last page in our list of current serialnumbers? */
7741 if(lookup_serialno_(endserial, currentno_list, currentnos)){
7743 /* last page is in the starting serialno list, so we've bisected
7744 down to (or just started with) a single link. Now we need to
7745 find the last vorbis page belonging to the first vorbis stream
7746 for this link. */
7747 searched = end;
7748 while(endserial != serialno){
7749 endserial = serialno;
7750 searched=get_prev_page_serial_(vf, searched, currentno_list, currentnos, &endserial, &endgran);
7753 vf.links=m+1;
7754 if(vf.offsets)ogg_free_(vf.offsets);
7755 if(vf.serialnos)ogg_free_(vf.serialnos);
7756 if(vf.dataoffsets)ogg_free_(vf.dataoffsets);
7758 vf.offsets=cast(long*)ogg_malloc_((vf.links+1)*(*vf.offsets).sizeof);
7759 vf.vi=cast(vorbis_info*)ogg_realloc_(vf.vi, vf.links*(*vf.vi).sizeof);
7760 vf.vc=cast(vorbis_comment*)ogg_realloc_(vf.vc, vf.links*(*vf.vc).sizeof);
7761 vf.serialnos=cast(uint*)ogg_malloc_(vf.links*(*vf.serialnos).sizeof);
7762 vf.dataoffsets=cast(long*)ogg_malloc_(vf.links*(*vf.dataoffsets).sizeof);
7763 vf.pcmlengths=cast(long*)ogg_malloc_(vf.links*2*(*vf.pcmlengths).sizeof);
7765 vf.offsets[m+1]=end;
7766 vf.offsets[m]=begin;
7767 vf.pcmlengths[m*2+1]=(endgran<0?0:endgran);
7769 }else{
7771 /* last page is not in the starting stream's serial number list,
7772 so we have multiple links. Find where the stream that begins
7773 our bisection ends. */
7775 ogg_uint32_t *next_serialno_list=null;
7776 int next_serialnos=0;
7777 vorbis_info vi;
7778 vorbis_comment vc;
7779 int testserial = serialno+1;
7781 /* the below guards against garbage seperating the last and
7782 first pages of two links. */
7783 while(searched<endsearched){
7784 ogg_int64_t bisect;
7786 if(endsearched-searched<CHUNKSIZE){
7787 bisect=searched;
7788 }else{
7789 bisect=(searched+endsearched)/2;
7792 ret=seek_helper_(vf, bisect);
7793 if(ret)return cast(typeof(return))(ret);
7795 last=get_next_page_(vf, &og, -1);
7796 if(last==OV_EREAD)return(OV_EREAD);
7797 if(last<0 || !lookup_page_serialno_(&og, currentno_list, currentnos)){
7798 endsearched=bisect;
7799 if(last>=0)next=last;
7800 }else{
7801 searched=vf.offset;
7805 /* Bisection point found */
7806 /* for the time being, fetch end PCM offset the simple way */
7807 searched = next;
7808 while(testserial != serialno){
7809 testserial = serialno;
7810 searched = get_prev_page_serial_(vf, searched, currentno_list, currentnos, &testserial, &searchgran);
7813 ret=seek_helper_(vf, next);
7814 if(ret)return cast(typeof(return))(ret);
7816 ret=fetch_headers_(vf, &vi, &vc, &next_serialno_list, &next_serialnos, null);
7817 if(ret)return cast(typeof(return))(ret);
7818 serialno = vf.os.serialno;
7819 dataoffset = vf.offset;
7821 /* this will consume a page, however the next bisection always
7822 starts with a raw seek */
7823 pcmoffset = initial_pcmoffset_(vf, &vi);
7825 ret=bisect_forward_serialno_(vf, next, vf.offset, end, endgran, endserial,
7826 next_serialno_list, next_serialnos, m+1);
7827 if(ret)return cast(typeof(return))(ret);
7829 if(next_serialno_list)ogg_free_(next_serialno_list);
7831 vf.offsets[m+1]=next;
7832 vf.serialnos[m+1]=serialno;
7833 vf.dataoffsets[m+1]=dataoffset;
7835 vf.vi[m+1]=vi;
7836 vf.vc[m+1]=vc;
7838 vf.pcmlengths[m*2+1]=searchgran;
7839 vf.pcmlengths[m*2+2]=pcmoffset;
7840 vf.pcmlengths[m*2+3]-=pcmoffset;
7841 if(vf.pcmlengths[m*2+3]<0)vf.pcmlengths[m*2+3]=0;
7844 return(0);
7847 private int make_decode_ready_(OggVorbis_File *vf){
7848 if(vf.ready_state>STREAMSET)return 0;
7849 if(vf.ready_state<STREAMSET)return OV_EFAULT;
7850 if(vf.seekable){
7851 if(vorbis_synthesis_init(&vf.vd, vf.vi+vf.current_link))
7852 return OV_EBADLINK;
7853 }else{
7854 if(vorbis_synthesis_init(&vf.vd, vf.vi))
7855 return OV_EBADLINK;
7857 vorbis_block_init(&vf.vd, &vf.vb);
7858 vf.ready_state=INITSET;
7859 vf.bittrack=0;
7860 vf.samptrack=0;
7861 return 0;
7864 private int open_seekable2_ (OggVorbis_File* vf) {
7865 ogg_int64_t dataoffset = vf.dataoffsets[0], end, endgran = -1;
7866 int endserial = vf.os.serialno;
7867 int serialno = vf.os.serialno;
7869 /* we're partially open and have a first link header state in storage in vf */
7871 /* fetch initial PCM offset */
7872 ogg_int64_t pcmoffset = initial_pcmoffset_(vf, vf.vi);
7874 /* we can seek, so set out learning all about this file */
7875 static if (XoggTremorHasVFS) {
7876 vf.offset = vf.end = -1;
7877 if (vf.datasource.isOpen) {
7878 try {
7879 vf.datasource.seek(0, Seek.End);
7880 vf.offset = vf.end = vf.datasource.tell;
7881 } catch (Exception) {
7882 vf.offset = vf.end = -1;
7885 } else {
7886 if(vf.callbacks.seek_func !is null && vf.callbacks.tell_func !is null){
7887 vf.callbacks.seek_func(vf.datasource, 0, SEEK_END);
7888 vf.offset=vf.end=vf.callbacks.tell_func(vf.datasource);
7889 }else{
7890 vf.offset=vf.end=-1;
7894 /* If seek_func is implemented, tell_func must also be implemented */
7895 if(vf.end==-1) return(OV_EINVAL);
7897 /* Get the offset of the last page of the physical bitstream, or, if
7898 we're lucky the last vorbis page of this link as most OggVorbis
7899 files will contain a single logical bitstream */
7900 end=get_prev_page_serial_(vf, vf.end, vf.serialnos+2, vf.serialnos[1], &endserial, &endgran);
7901 if(end<0)return cast(typeof(return))(end);
7903 /* now determine bitstream structure recursively */
7904 if(bisect_forward_serialno_(vf, 0, dataoffset, end, endgran, endserial,
7905 vf.serialnos+2, vf.serialnos[1], 0)<0)return(OV_EREAD);
7907 vf.offsets[0]=0;
7908 vf.serialnos[0]=serialno;
7909 vf.dataoffsets[0]=dataoffset;
7910 vf.pcmlengths[0]=pcmoffset;
7911 vf.pcmlengths[1]-=pcmoffset;
7912 if(vf.pcmlengths[1]<0)vf.pcmlengths[1]=0;
7914 return(ov_raw_seek(vf, dataoffset));
7917 /* clear out the current logical bitstream decoder */
7918 private void decode_clear_(OggVorbis_File *vf){
7919 vorbis_dsp_clear(&vf.vd);
7920 vorbis_block_clear(&vf.vb);
7921 vf.ready_state=OPENED;
7924 /* fetch and process a packet. Handles the case where we're at a
7925 bitstream boundary and dumps the decoding machine. If the decoding
7926 machine is unloaded, it loads it. It also keeps pcm_offset up to
7927 date (seek and read both use this. seek uses a special hack with
7928 readp).
7930 return: <0) error, OV_HOLE (lost packet) or OV_EOF
7931 0) need more data (only if readp==0)
7932 1) got a packet
7935 private int fetch_and_process_packet_(OggVorbis_File *vf,
7936 ogg_packet *op_in,
7937 int readp,
7938 int spanp){
7939 ogg_page og;
7941 /* handle one packet. Try to fetch it from current stream state */
7942 /* extract packets from page */
7943 while(1){
7945 if(vf.ready_state==STREAMSET){
7946 int ret=make_decode_ready_(vf);
7947 if(ret<0)return ret;
7950 /* process a packet if we can. If the machine isn't loaded,
7951 neither is a page */
7952 if(vf.ready_state==INITSET){
7953 while(1) {
7954 ogg_packet op;
7955 ogg_packet *op_ptr=(op_in?op_in:&op);
7956 int result=ogg_stream_packetout(&vf.os, op_ptr);
7957 ogg_int64_t granulepos;
7959 op_in=null;
7960 if(result==-1)return(OV_HOLE); /* hole in the data. */
7961 if(result>0){
7962 /* got a packet. process it */
7963 granulepos=op_ptr.granulepos;
7964 if(!vorbis_synthesis(&vf.vb, op_ptr)){ /* lazy check for lazy
7965 header handling. The
7966 header packets aren't
7967 audio, so if/when we
7968 submit them,
7969 vorbis_synthesis will
7970 reject them */
7972 /* suck in the synthesis data and track bitrate */
7974 int oldsamples=vorbis_synthesis_pcmout(&vf.vd, null);
7975 /* for proper use of libvorbis within libvorbisfile,
7976 oldsamples will always be zero. */
7977 if(oldsamples)return(OV_EFAULT);
7979 vorbis_synthesis_blockin(&vf.vd, &vf.vb);
7980 vf.samptrack+=vorbis_synthesis_pcmout(&vf.vd, null);
7981 vf.bittrack+=op_ptr.bytes*8;
7984 /* update the pcm offset. */
7985 if(granulepos!=-1 && !op_ptr.e_o_s){
7986 int link=(vf.seekable?vf.current_link:0);
7987 int i, samples;
7989 /* this packet has a pcm_offset on it (the last packet
7990 completed on a page carries the offset) After processing
7991 (above), we know the pcm position of the *last* sample
7992 ready to be returned. Find the offset of the *first*
7994 As an aside, this trick is inaccurate if we begin
7995 reading anew right at the last page; the end-of-stream
7996 granulepos declares the last frame in the stream, and the
7997 last packet of the last page may be a partial frame.
7998 So, we need a previous granulepos from an in-sequence page
7999 to have a reference point. Thus the !op_ptr.e_o_s clause
8000 above */
8002 if(vf.seekable && link>0)
8003 granulepos-=vf.pcmlengths[link*2];
8004 if(granulepos<0)granulepos=0; /* actually, this
8005 shouldn't be possible
8006 here unless the stream
8007 is very broken */
8009 samples=vorbis_synthesis_pcmout(&vf.vd, null);
8011 granulepos-=samples;
8012 for(i=0;i<link;i++)
8013 granulepos+=vf.pcmlengths[i*2+1];
8014 vf.pcm_offset=granulepos;
8016 return(1);
8019 else
8020 break;
8024 if(vf.ready_state>=OPENED){
8025 ogg_int64_t ret;
8027 while(1){
8028 /* the loop is not strictly necessary, but there's no sense in
8029 doing the extra checks of the larger loop for the common
8030 case in a multiplexed bistream where the page is simply
8031 part of a different logical bitstream; keep reading until
8032 we get one with the correct serialno */
8034 if(!readp)return(0);
8035 if((ret=get_next_page_(vf, &og, -1))<0){
8036 return(OV_EOF); /* eof. leave unitialized */
8039 /* bitrate tracking; add the header's bytes here, the body bytes
8040 are done by packet above */
8041 vf.bittrack+=og.header_len*8;
8043 if(vf.ready_state==INITSET){
8044 if(vf.current_serialno!=ogg_page_serialno(&og)){
8046 /* two possibilities:
8047 1) our decoding just traversed a bitstream boundary
8048 2) another stream is multiplexed into this logical section */
8050 if(ogg_page_bos(&og)){
8051 /* boundary case */
8052 if(!spanp)
8053 return(OV_EOF);
8055 decode_clear_(vf);
8057 if(!vf.seekable){
8058 vorbis_info_clear(vf.vi);
8059 vorbis_comment_clear(vf.vc);
8061 break;
8063 }else
8064 continue; /* possibility #2 */
8068 break;
8072 /* Do we need to load a new machine before submitting the page? */
8073 /* This is different in the seekable and non-seekable cases.
8075 In the seekable case, we already have all the header
8076 information loaded and cached; we just initialize the machine
8077 with it and continue on our merry way.
8079 In the non-seekable (streaming) case, we'll only be at a
8080 boundary if we just left the previous logical bitstream and
8081 we're now nominally at the header of the next bitstream
8084 if(vf.ready_state!=INITSET){
8085 int link;
8087 if(vf.ready_state<STREAMSET){
8088 if(vf.seekable){
8089 ogg_uint32_t serialno = ogg_page_serialno(&og);
8091 /* match the serialno to bitstream section. We use this rather than
8092 offset positions to avoid problems near logical bitstream
8093 boundaries */
8095 for(link=0;link<vf.links;link++)
8096 if(vf.serialnos[link]==serialno)break;
8098 if(link==vf.links) continue; /* not the desired Vorbis
8099 bitstream section; keep
8100 trying */
8102 vf.current_serialno=serialno;
8103 vf.current_link=link;
8105 ogg_stream_reset_serialno(&vf.os, vf.current_serialno);
8106 vf.ready_state=STREAMSET;
8108 }else{
8109 /* we're streaming */
8110 /* fetch the three header packets, build the info struct */
8112 int ret=fetch_headers_(vf, vf.vi, vf.vc, null, null, &og);
8113 if(ret)return(ret);
8114 vf.current_serialno=vf.os.serialno;
8115 vf.current_link++;
8116 link=0;
8121 /* the buffered page is the data we want, and we're ready for it;
8122 add it to the stream state */
8123 ogg_stream_pagein(&vf.os, &og);
8128 static if (XoggTremorHasVFS) alias ov_callbacks_x = VFile; else alias ov_callbacks_x = ov_callbacks*;
8129 private int ov_open1_(void *f, OggVorbis_File *vf, const(char)* initial, trm_long ibytes, ov_callbacks_x callbacks) {
8130 static if (XoggTremorHasVFS) {
8131 int offsettest;
8132 try {
8133 callbacks.seek(0, Seek.Cur);
8134 offsettest = 0;
8135 } catch (Exception) {
8136 offsettest = -1;
8138 } else {
8139 int offsettest = (f !is null && callbacks.seek_func !is null ? callbacks.seek_func(f, 0, SEEK_CUR) : -1);
8141 ogg_uint32_t *serialno_list=null;
8142 int serialno_list_size=0;
8143 int ret;
8145 memset(vf, 0, (*vf).sizeof);
8146 static if (XoggTremorHasVFS) {
8147 vf.datasource = callbacks;
8148 } else {
8149 vf.datasource=f;
8150 vf.callbacks = *callbacks;
8153 /* init the framing state */
8154 ogg_sync_init(&vf.oy);
8156 /* perhaps some data was previously read into a buffer for testing
8157 against other stream types. Allow initialization from this
8158 previously read data (especially as we may be reading from a
8159 non-seekable stream) */
8160 if(initial){
8161 char *buffer=ogg_sync_buffer(&vf.oy, ibytes);
8162 memcpy(buffer, initial, ibytes);
8163 ogg_sync_wrote(&vf.oy, ibytes);
8166 /* can we seek? Stevens suggests the seek test was portable */
8167 if(offsettest!=-1)vf.seekable=1;
8169 /* No seeking yet; Set up a 'single' (current) logical bitstream
8170 entry for partial open */
8171 vf.links=1;
8172 vf.vi=cast(vorbis_info*)ogg_calloc_(vf.links, (*vf.vi).sizeof);
8173 vf.vc=cast(vorbis_comment*)ogg_calloc_(vf.links, (*vf.vc).sizeof);
8174 ogg_stream_init(&vf.os, -1); /* fill in the serialno later */
8176 /* Fetch all BOS pages, store the vorbis header and all seen serial
8177 numbers, load subsequent vorbis setup headers */
8178 if((ret=fetch_headers_(vf, vf.vi, vf.vc, &serialno_list, &serialno_list_size, null))<0){
8179 static if (XoggTremorHasVFS) vf.datasource = VFile.init; else vf.datasource = null;
8180 ov_clear(vf);
8181 }else{
8182 /* serial number list for first link needs to be held somewhere
8183 for second stage of seekable stream open; this saves having to
8184 seek/reread first link's serialnumber data then. */
8185 vf.serialnos=cast(uint*)ogg_calloc_(serialno_list_size+2, (*vf.serialnos).sizeof);
8186 vf.serialnos[0]=vf.current_serialno=vf.os.serialno;
8187 vf.serialnos[1]=serialno_list_size;
8188 memcpy(vf.serialnos+2, serialno_list, serialno_list_size*(*vf.serialnos).sizeof);
8190 vf.offsets=cast(long*)ogg_calloc_(1, (*vf.offsets).sizeof);
8191 vf.dataoffsets=cast(long*)ogg_calloc_(1, (*vf.dataoffsets).sizeof);
8192 vf.offsets[0]=0;
8193 vf.dataoffsets[0]=vf.offset;
8195 vf.ready_state=PARTOPEN;
8197 if(serialno_list)ogg_free_(serialno_list);
8198 return(ret);
8201 private int ov_open2_(OggVorbis_File *vf){
8202 if(vf.ready_state != PARTOPEN) return OV_EINVAL;
8203 vf.ready_state=OPENED;
8204 if(vf.seekable){
8205 int ret=open_seekable2_(vf);
8206 if(ret){
8207 static if (XoggTremorHasVFS) vf.datasource = VFile.init; else vf.datasource = null;
8208 ov_clear(vf);
8210 return(ret);
8211 }else
8212 vf.ready_state=STREAMSET;
8214 return 0;
8218 /// clear out the OggVorbis_File struct
8219 public int ov_clear (OggVorbis_File* vf) {
8220 if (vf !is null) {
8221 vorbis_block_clear(&vf.vb);
8222 vorbis_dsp_clear(&vf.vd);
8223 ogg_stream_clear(&vf.os);
8225 if (vf.vi && vf.links) {
8226 foreach (immutable i; 0..vf.links) {
8227 vorbis_info_clear(vf.vi+i);
8228 vorbis_comment_clear(vf.vc+i);
8230 ogg_free_(vf.vi);
8231 ogg_free_(vf.vc);
8233 if (vf.dataoffsets !is null) ogg_free_(vf.dataoffsets);
8234 if (vf.pcmlengths !is null) ogg_free_(vf.pcmlengths);
8235 if (vf.serialnos !is null) ogg_free_(vf.serialnos);
8236 if (vf.offsets !is null) ogg_free_(vf.offsets);
8237 ogg_sync_clear(&vf.oy);
8238 static if (XoggTremorHasVFS) {
8239 vf.datasource = VFile.init;
8240 } else {
8241 if (vf.datasource && vf.callbacks.close_func !is null) vf.callbacks.close_func(vf.datasource);
8243 memset(vf, 0, (*vf).sizeof);
8245 return 0;
8248 static if (XoggTremorHasVFS) {
8249 /* inspects the OggVorbis file and finds/documents all the logical
8250 bitstreams contained in it. Tries to be tolerant of logical
8251 bitstream sections that are truncated/woogie.
8253 return: -1: error
8254 0: OK
8256 private int ov_open_callbacks (VFile f, OggVorbis_File* vf, const(char)* initial, trm_long ibytes) {
8257 int ret = ov_open1_(null, vf, initial, ibytes, f);
8258 if (ret) return ret;
8259 return ov_open2_(vf);
8263 public int ov_open (VFile f, OggVorbis_File* vf, const(char)* initial, trm_long ibytes) {
8264 return ov_open_callbacks(f, vf, initial, ibytes);
8268 public int ov_fopen (VFile fl, OggVorbis_File* vf) {
8269 auto ret = ov_open(fl, vf, null, 0);
8270 if (ret) fl.close();
8271 return ret;
8274 /** Only partially open the vorbis file; test for Vorbisness, and load
8275 the headers for the first chain. Do not seek (although test for
8276 seekability). Use ov_test_open to finish opening the file, else
8277 ov_clear to close/free it. Same return codes as open. */
8278 public int ov_test (VFile f, OggVorbis_File* vf, const(char)* initial, trm_long ibytes) {
8279 return ov_open1_(null, vf, initial, ibytes, f);
8281 } else {
8282 /** inspects the OggVorbis file and finds/documents all the logical
8283 bitstreams contained in it. Tries to be tolerant of logical
8284 bitstream sections that are truncated/woogie.
8286 return: -1: error
8287 0: OK
8289 public int ov_open_callbacks(void *f, OggVorbis_File *vf, const(char)*initial, trm_long ibytes, ov_callbacks callbacks) {
8290 int ret=ov_open1_(f, vf, initial, ibytes, &callbacks);
8291 if(ret)return ret;
8292 return ov_open2_(vf);
8295 private void ov_setup_file_callbacks_ (ref ov_callbacks callbacks) {
8296 callbacks.read_func = /*usize*/ function (void *ptr, usize size, usize nmemb, void *datasource) {
8297 if (datasource is null) return -1;
8298 return cast(usize)fread(ptr, size, nmemb, cast(FILE*)datasource);
8300 callbacks.seek_func = /*int*/ function (void *datasource, ogg_int64_t offset, int whence) {
8301 if (datasource is null) return -1;
8302 return cast(int)fseek(cast(FILE*)datasource, cast(int)offset, whence);
8304 callbacks.close_func = /*int*/ function (void *datasource) {
8305 if (datasource !is null) return cast(int)fclose(cast(FILE*)datasource);
8306 return 0;
8308 callbacks.tell_func = /*trm_long*/ function (void *datasource) {
8309 if (datasource is null) return cast(trm_long)-1;
8310 return cast(trm_long)ftell(cast(FILE*)datasource);
8315 public int ov_open(FILE *f, OggVorbis_File *vf, const(char)* initial, trm_long ibytes){
8316 ov_callbacks callbacks;
8317 ov_setup_file_callbacks_(callbacks);
8318 return ov_open_callbacks(cast(void *)f, vf, initial, ibytes, callbacks);
8322 public int ov_fopen(const(char)[] path, OggVorbis_File *vf){
8323 import std.internal.cstring : tempCString;
8324 FILE* f = fopen(path.tempCString, "rb");
8325 if (f is null) return -1;
8326 auto ret = ov_open(f, vf, null, 0);
8327 if (ret) fclose(f);
8328 return ret;
8331 /** Only partially open the vorbis file; test for Vorbisness, and load
8332 the headers for the first chain. Do not seek (although test for
8333 seekability). Use ov_test_open to finish opening the file, else
8334 ov_clear to close/free it. Same return codes as open. */
8335 public int ov_test_callbacks(void *f, OggVorbis_File *vf, const(char)* initial, trm_long ibytes, ov_callbacks callbacks)
8337 return ov_open1_(f, vf, initial, ibytes, &callbacks);
8341 public int ov_test(FILE *f, OggVorbis_File *vf, const(char)* initial, trm_long ibytes){
8342 ov_callbacks callbacks;
8343 ov_setup_file_callbacks_(callbacks);
8344 return ov_test_callbacks(cast(void *)f, vf, initial, ibytes, callbacks);
8349 public int ov_test_open (OggVorbis_File* vf){
8350 if (vf.ready_state != PARTOPEN) return OV_EINVAL;
8351 return ov_open2_(vf);
8354 /// How many logical bitstreams in this physical bitstream?
8355 public trm_long ov_streams (OggVorbis_File* vf) {
8356 return vf.links;
8359 /// Is the FILE* associated with vf seekable?
8360 public trm_long ov_seekable (OggVorbis_File* vf) {
8361 return vf.seekable;
8364 /** returns the bitrate for a given logical bitstream or the entire
8365 physical bitstream. If the file is open for random access, it will
8366 find the *actual* average bitrate. If the file is streaming, it
8367 returns the nominal bitrate (if set) else the average of the
8368 upper/lower bounds (if set) else -1 (unset).
8370 If you want the actual bitrate field settings, get them from the
8371 vorbis_info structs */
8372 public trm_long ov_bitrate(OggVorbis_File *vf, int i=-1){
8373 if(vf.ready_state<OPENED)return(OV_EINVAL);
8374 if(i>=vf.links)return(OV_EINVAL);
8375 if(!vf.seekable && i!=0)return(ov_bitrate(vf, 0));
8376 if(i<0){
8377 ogg_int64_t bits=0;
8378 //int i;
8379 for(i=0;i<vf.links;i++)
8380 bits+=(vf.offsets[i+1]-vf.dataoffsets[i])*8;
8381 /* This once read: return(rint(bits/ov_time_total(vf, -1)));
8382 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
8383 * so this is slightly transformed to make it work.
8385 return cast(typeof(return))(bits*1000/ov_time_total(vf, -1));
8386 }else{
8387 if(vf.seekable){
8388 /* return the actual bitrate */
8389 return cast(typeof(return))((vf.offsets[i+1]-vf.dataoffsets[i])*8000/ov_time_total(vf, i));
8390 }else{
8391 /* return nominal if set */
8392 if(vf.vi[i].bitrate_nominal>0){
8393 return vf.vi[i].bitrate_nominal;
8394 }else{
8395 if(vf.vi[i].bitrate_upper>0){
8396 if(vf.vi[i].bitrate_lower>0){
8397 return (vf.vi[i].bitrate_upper+vf.vi[i].bitrate_lower)/2;
8398 }else{
8399 return vf.vi[i].bitrate_upper;
8402 return(OV_FALSE);
8408 /** returns the actual bitrate since last call. returns -1 if no
8409 additional data to offer since last call (or at beginning of stream),
8410 EINVAL if stream is only partially open
8412 public trm_long ov_bitrate_instant(OggVorbis_File *vf){
8413 int link=(vf.seekable?vf.current_link:0);
8414 trm_long ret;
8415 if(vf.ready_state<OPENED)return(OV_EINVAL);
8416 if(vf.samptrack==0)return(OV_FALSE);
8417 ret=cast(trm_long)(vf.bittrack/vf.samptrack*vf.vi[link].rate);
8418 vf.bittrack=0;
8419 vf.samptrack=0;
8420 return(ret);
8423 /// Guess
8424 public trm_long ov_serialnumber(OggVorbis_File *vf, int i){
8425 if(i>=vf.links)return(ov_serialnumber(vf, vf.links-1));
8426 if(!vf.seekable && i>=0)return(ov_serialnumber(vf, -1));
8427 if(i<0){
8428 return(vf.current_serialno);
8429 }else{
8430 return(vf.serialnos[i]);
8434 /** returns: total raw (compressed) length of content if i==-1
8435 raw (compressed) length of that logical bitstream for i==0 to n
8436 OV_EINVAL if the stream is not seekable (we can't know the length)
8437 or if stream is only partially open
8439 public ogg_int64_t ov_raw_total(OggVorbis_File *vf, int i=-1){
8440 if(vf.ready_state<OPENED)return(OV_EINVAL);
8441 if(!vf.seekable || i>=vf.links)return(OV_EINVAL);
8442 if(i<0){
8443 ogg_int64_t acc=0;
8444 //int i;
8445 for(i=0;i<vf.links;i++)
8446 acc+=ov_raw_total(vf, i);
8447 return(acc);
8448 }else{
8449 return(vf.offsets[i+1]-vf.offsets[i]);
8453 /* returns: total PCM length (samples) of content if i==-1 PCM length
8454 (samples) of that logical bitstream for i==0 to n
8455 OV_EINVAL if the stream is not seekable (we can't know the
8456 length) or only partially open
8458 public ogg_int64_t ov_pcm_total(OggVorbis_File *vf, int i=-1){
8459 if(vf.ready_state<OPENED)return(OV_EINVAL);
8460 if(!vf.seekable || i>=vf.links)return(OV_EINVAL);
8461 if(i<0){
8462 ogg_int64_t acc=0;
8463 //int i;
8464 for(i=0;i<vf.links;i++)
8465 acc+=ov_pcm_total(vf, i);
8466 return(acc);
8467 }else{
8468 return(vf.pcmlengths[i*2+1]);
8472 /** returns: total milliseconds of content if i==-1
8473 milliseconds in that logical bitstream for i==0 to n
8474 OV_EINVAL if the stream is not seekable (we can't know the
8475 length) or only partially open
8477 public ogg_int64_t ov_time_total(OggVorbis_File *vf, int i=-1){
8478 if(vf.ready_state<OPENED)return(OV_EINVAL);
8479 if(!vf.seekable || i>=vf.links)return(OV_EINVAL);
8480 if(i<0){
8481 ogg_int64_t acc=0;
8482 //int i;
8483 for(i=0;i<vf.links;i++)
8484 acc+=ov_time_total(vf, i);
8485 return(acc);
8486 }else{
8487 return((cast(ogg_int64_t)vf.pcmlengths[i*2+1])*1000/vf.vi[i].rate);
8491 /** seek to an offset relative to the *compressed* data. This also
8492 scans packets to update the PCM cursor. It will cross a logical
8493 bitstream boundary, but only if it can't get any packets out of the
8494 tail of the bitstream we seek to (so no surprises).
8496 returns zero on success, nonzero on failure */
8497 public int ov_raw_seek(OggVorbis_File *vf, ogg_int64_t pos){
8498 ogg_stream_state work_os;
8499 int ret;
8501 if(vf.ready_state<OPENED)return(OV_EINVAL);
8502 if(!vf.seekable)
8503 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
8505 if(pos<0 || pos>vf.end)return(OV_EINVAL);
8507 /* is the seek position outside our current link [if any]? */
8508 if(vf.ready_state>=STREAMSET){
8509 if(pos<vf.offsets[vf.current_link] || pos>=vf.offsets[vf.current_link+1])
8510 decode_clear_(vf); /* clear out stream state */
8513 /* don't yet clear out decoding machine (if it's initialized), in
8514 the case we're in the same link. Restart the decode lapping, and
8515 let fetch_and_process_packet_ deal with a potential bitstream
8516 boundary */
8517 vf.pcm_offset=-1;
8518 ogg_stream_reset_serialno(&vf.os,
8519 vf.current_serialno); /* must set serialno */
8520 vorbis_synthesis_restart(&vf.vd);
8522 ret=seek_helper_(vf, pos);
8523 if(ret)goto seek_error;
8525 /* we need to make sure the pcm_offset is set, but we don't want to
8526 advance the raw cursor past good packets just to get to the first
8527 with a granulepos. That's not equivalent behavior to beginning
8528 decoding as immediately after the seek position as possible.
8530 So, a hack. We use two stream states; a local scratch state and
8531 the shared vf.os stream state. We use the local state to
8532 scan, and the shared state as a buffer for later decode.
8534 Unfortuantely, on the last page we still advance to last packet
8535 because the granulepos on the last page is not necessarily on a
8536 packet boundary, and we need to make sure the granpos is
8537 correct.
8541 ogg_page og;
8542 ogg_packet op;
8543 int lastblock=0;
8544 int accblock=0;
8545 int thisblock=0;
8546 int lastflag=0;
8547 int firstflag=0;
8548 ogg_int64_t pagepos=-1;
8550 ogg_stream_init(&work_os, vf.current_serialno); /* get the memory ready */
8551 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
8552 return from not necessarily
8553 starting from the beginning */
8555 while(1){
8556 if(vf.ready_state>=STREAMSET){
8557 /* snarf/scan a packet if we can */
8558 int result=ogg_stream_packetout(&work_os, &op);
8560 if(result>0){
8562 if(vf.vi[vf.current_link].codec_setup){
8563 thisblock=vorbis_packet_blocksize(vf.vi+vf.current_link, &op);
8564 if(thisblock<0){
8565 ogg_stream_packetout(&vf.os, null);
8566 thisblock=0;
8567 }else{
8569 /* We can't get a guaranteed correct pcm position out of the
8570 last page in a stream because it might have a 'short'
8571 granpos, which can only be detected in the presence of a
8572 preceding page. However, if the last page is also the first
8573 page, the granpos rules of a first page take precedence. Not
8574 only that, but for first==last, the EOS page must be treated
8575 as if its a normal first page for the stream to open/play. */
8576 if(lastflag && !firstflag)
8577 ogg_stream_packetout(&vf.os, null);
8578 else
8579 if(lastblock)accblock+=(lastblock+thisblock)>>2;
8582 if(op.granulepos!=-1){
8583 int i, link=vf.current_link;
8584 ogg_int64_t granulepos=op.granulepos-vf.pcmlengths[link*2];
8585 if(granulepos<0)granulepos=0;
8587 for(i=0;i<link;i++)
8588 granulepos+=vf.pcmlengths[i*2+1];
8589 vf.pcm_offset=granulepos-accblock;
8590 if(vf.pcm_offset<0)vf.pcm_offset=0;
8591 break;
8593 lastblock=thisblock;
8594 continue;
8595 }else
8596 ogg_stream_packetout(&vf.os, null);
8600 if(!lastblock){
8601 pagepos=get_next_page_(vf, &og, -1);
8602 if(pagepos<0){
8603 vf.pcm_offset=ov_pcm_total(vf, -1);
8604 break;
8606 }else{
8607 /* huh? Bogus stream with packets but no granulepos */
8608 vf.pcm_offset=-1;
8609 break;
8612 /* has our decoding just traversed a bitstream boundary? */
8613 if(vf.ready_state>=STREAMSET){
8614 if(vf.current_serialno!=ogg_page_serialno(&og)){
8616 /* two possibilities:
8617 1) our decoding just traversed a bitstream boundary
8618 2) another stream is multiplexed into this logical section? */
8620 if(ogg_page_bos(&og)){
8621 /* we traversed */
8622 decode_clear_(vf); /* clear out stream state */
8623 ogg_stream_clear(&work_os);
8624 } /* else, do nothing; next loop will scoop another page */
8628 if(vf.ready_state<STREAMSET){
8629 int link;
8630 ogg_uint32_t serialno = ogg_page_serialno(&og);
8632 for(link=0;link<vf.links;link++)
8633 if(vf.serialnos[link]==serialno)break;
8635 if(link==vf.links) continue; /* not the desired Vorbis
8636 bitstream section; keep
8637 trying */
8638 vf.current_link=link;
8639 vf.current_serialno=serialno;
8640 ogg_stream_reset_serialno(&vf.os, serialno);
8641 ogg_stream_reset_serialno(&work_os, serialno);
8642 vf.ready_state=STREAMSET;
8643 firstflag=(pagepos<=vf.dataoffsets[link]);
8646 ogg_stream_pagein(&vf.os, &og);
8647 ogg_stream_pagein(&work_os, &og);
8648 lastflag=ogg_page_eos(&og);
8653 ogg_stream_clear(&work_os);
8654 vf.bittrack=0;
8655 vf.samptrack=0;
8656 return(0);
8658 seek_error:
8659 /* dump the machine so we're in a known state */
8660 vf.pcm_offset=-1;
8661 ogg_stream_clear(&work_os);
8662 decode_clear_(vf);
8663 return OV_EBADLINK;
8666 /* rescales the number x from the range of [0,from] to [0,to]
8667 x is in the range [0,from]
8668 from, to are in the range [1, 1<<62-1] */
8669 ogg_int64_t rescale64(ogg_int64_t x, ogg_int64_t from, ogg_int64_t to){
8670 ogg_int64_t frac=0;
8671 ogg_int64_t ret=0;
8672 int i;
8673 if(x >= from) return to;
8674 if(x <= 0) return 0;
8676 for(i=0;i<64;i++){
8677 if(x>=from){
8678 frac|=1;
8679 x-=from;
8681 x<<=1;
8682 frac<<=1;
8685 for(i=0;i<64;i++){
8686 if(frac & 1){
8687 ret+=to;
8689 frac>>=1;
8690 ret>>=1;
8693 return ret;
8696 /** Page granularity seek (faster than sample granularity because we
8697 don't do the last bit of decode to find a specific sample).
8699 Seek to the last [granule marked] page preceding the specified pos
8700 location, such that decoding past the returned point will quickly
8701 arrive at the requested position. */
8702 public int ov_pcm_seek_page(OggVorbis_File *vf, ogg_int64_t pos){
8703 int link=-1;
8704 ogg_int64_t result=0;
8705 ogg_int64_t total=ov_pcm_total(vf, -1);
8707 if(vf.ready_state<OPENED)return(OV_EINVAL);
8708 if(!vf.seekable)return(OV_ENOSEEK);
8710 if(pos<0 || pos>total)return(OV_EINVAL);
8712 /* which bitstream section does this pcm offset occur in? */
8713 for(link=vf.links-1;link>=0;link--){
8714 total-=vf.pcmlengths[link*2+1];
8715 if(pos>=total)break;
8718 /* Search within the logical bitstream for the page with the highest
8719 pcm_pos preceding pos. If we're looking for a position on the
8720 first page, bisection will halt without finding our position as
8721 it's before the first explicit granulepos fencepost. That case is
8722 handled separately below.
8724 There is a danger here; missing pages or incorrect frame number
8725 information in the bitstream could make our task impossible.
8726 Account for that (it would be an error condition) */
8728 /* new search algorithm originally by HB (Nicholas Vinen) */
8731 ogg_int64_t end=vf.offsets[link+1];
8732 ogg_int64_t begin=vf.dataoffsets[link];
8733 ogg_int64_t begintime = vf.pcmlengths[link*2];
8734 ogg_int64_t endtime = vf.pcmlengths[link*2+1]+begintime;
8735 ogg_int64_t target=pos-total+begintime;
8736 ogg_int64_t best=-1;
8737 int got_page=0;
8739 ogg_page og;
8741 /* if we have only one page, there will be no bisection. Grab the page here */
8742 if(begin==end){
8743 result=seek_helper_(vf, begin);
8744 if(result) goto seek_error;
8746 result=get_next_page_(vf, &og, 1);
8747 if(result<0) goto seek_error;
8749 got_page=1;
8752 /* bisection loop */
8753 while(begin<end){
8754 ogg_int64_t bisect;
8756 if(end-begin<CHUNKSIZE){
8757 bisect=begin;
8758 }else{
8759 /* take a (pretty decent) guess. */
8760 bisect=begin + rescale64(target-begintime,
8761 endtime-begintime,
8762 end-begin) - CHUNKSIZE;
8763 if(bisect<begin+CHUNKSIZE)
8764 bisect=begin;
8767 result=seek_helper_(vf, bisect);
8768 if(result) goto seek_error;
8770 /* read loop within the bisection loop */
8771 while(begin<end){
8772 result=get_next_page_(vf, &og, end-vf.offset);
8773 if(result==OV_EREAD) goto seek_error;
8774 if(result<0){
8775 /* there is no next page! */
8776 if(bisect<=begin+1)
8777 /* No bisection left to perform. We've either found the
8778 best candidate already or failed. Exit loop. */
8779 end=begin;
8780 else{
8781 /* We tried to load a fraction of the last page; back up a
8782 bit and try to get the whole last page */
8783 if(bisect==0) goto seek_error;
8784 bisect-=CHUNKSIZE;
8786 /* don't repeat/loop on a read we've already performed */
8787 if(bisect<=begin)bisect=begin+1;
8789 /* seek and continue bisection */
8790 result=seek_helper_(vf, bisect);
8791 if(result) goto seek_error;
8793 }else{
8794 ogg_int64_t granulepos;
8795 got_page=1;
8797 /* got a page. analyze it */
8798 /* only consider pages from primary vorbis stream */
8799 if(ogg_page_serialno(&og)!=vf.serialnos[link])
8800 continue;
8802 /* only consider pages with the granulepos set */
8803 granulepos=ogg_page_granulepos(&og);
8804 if(granulepos==-1)continue;
8806 if(granulepos<target){
8807 /* this page is a successful candidate! Set state */
8809 best=result; /* raw offset of packet with granulepos */
8810 begin=vf.offset; /* raw offset of next page */
8811 begintime=granulepos;
8813 /* if we're before our target but within a short distance,
8814 don't bisect; read forward */
8815 if(target-begintime>44100)break;
8817 bisect=begin; /* *not* begin + 1 as above */
8818 }else{
8820 /* This is one of our pages, but the granpos is
8821 post-target; it is not a bisection return
8822 candidate. (The only way we'd use it is if it's the
8823 first page in the stream; we handle that case later
8824 outside the bisection) */
8825 if(bisect<=begin+1){
8826 /* No bisection left to perform. We've either found the
8827 best candidate already or failed. Exit loop. */
8828 end=begin;
8829 }else{
8830 if(end==vf.offset){
8831 /* bisection read to the end; use the known page
8832 boundary (result) to update bisection, back up a
8833 little bit, and try again */
8834 end=result;
8835 bisect-=CHUNKSIZE;
8836 if(bisect<=begin)bisect=begin+1;
8837 result=seek_helper_(vf, bisect);
8838 if(result) goto seek_error;
8839 }else{
8840 /* Normal bisection */
8841 end=bisect;
8842 endtime=granulepos;
8843 break;
8851 /* Out of bisection: did it 'fail?' */
8852 if(best == -1){
8854 /* Check the 'looking for data in first page' special case;
8855 bisection would 'fail' because our search target was before the
8856 first PCM granule position fencepost. */
8858 if(got_page &&
8859 begin == vf.dataoffsets[link] &&
8860 ogg_page_serialno(&og)==vf.serialnos[link]){
8862 /* Yes, this is the beginning-of-stream case. We already have
8863 our page, right at the beginning of PCM data. Set state
8864 and return. */
8866 vf.pcm_offset=total;
8868 if(link!=vf.current_link){
8869 /* Different link; dump entire decode machine */
8870 decode_clear_(vf);
8872 vf.current_link=link;
8873 vf.current_serialno=vf.serialnos[link];
8874 vf.ready_state=STREAMSET;
8876 }else{
8877 vorbis_synthesis_restart(&vf.vd);
8880 ogg_stream_reset_serialno(&vf.os, vf.current_serialno);
8881 ogg_stream_pagein(&vf.os, &og);
8883 }else
8884 goto seek_error;
8886 }else{
8888 /* Bisection found our page. seek to it, update pcm offset. Easier case than
8889 raw_seek, don't keep packets preceding granulepos. */
8891 //ogg_page og;
8892 ogg_packet op;
8894 /* seek */
8895 result=seek_helper_(vf, best);
8896 vf.pcm_offset=-1;
8897 if(result) goto seek_error;
8898 result=get_next_page_(vf, &og, -1);
8899 if(result<0) goto seek_error;
8901 if(link!=vf.current_link){
8902 /* Different link; dump entire decode machine */
8903 decode_clear_(vf);
8905 vf.current_link=link;
8906 vf.current_serialno=vf.serialnos[link];
8907 vf.ready_state=STREAMSET;
8909 }else{
8910 vorbis_synthesis_restart(&vf.vd);
8913 ogg_stream_reset_serialno(&vf.os, vf.current_serialno);
8914 ogg_stream_pagein(&vf.os, &og);
8916 /* pull out all but last packet; the one with granulepos */
8917 while(1){
8918 result=ogg_stream_packetpeek(&vf.os, &op);
8919 if(result==0){
8920 /* No packet returned; we exited the bisection with 'best'
8921 pointing to a page with a granule position, so the packet
8922 finishing this page ('best') originated on a preceding
8923 page. Keep fetching previous pages until we get one with
8924 a granulepos or without the 'continued' flag set. Then
8925 just use raw_seek for simplicity. */
8926 /* Do not rewind past the beginning of link data; if we do,
8927 it's either a bug or a broken stream */
8928 result=best;
8929 while(result>vf.dataoffsets[link]){
8930 result=get_prev_page_(vf, result, &og);
8931 if(result<0) goto seek_error;
8932 if(ogg_page_serialno(&og)==vf.current_serialno &&
8933 (ogg_page_granulepos(&og)>-1 ||
8934 !ogg_page_continued(&og))){
8935 return ov_raw_seek(vf, result);
8939 if(result<0){
8940 result = OV_EBADPACKET;
8941 goto seek_error;
8943 if(op.granulepos!=-1){
8944 vf.pcm_offset=op.granulepos-vf.pcmlengths[vf.current_link*2];
8945 if(vf.pcm_offset<0)vf.pcm_offset=0;
8946 vf.pcm_offset+=total;
8947 break;
8948 }else
8949 result=ogg_stream_packetout(&vf.os, null);
8954 /* verify result */
8955 if(vf.pcm_offset>pos || pos>ov_pcm_total(vf, -1)){
8956 result=OV_EFAULT;
8957 goto seek_error;
8959 vf.bittrack=0;
8960 vf.samptrack=0;
8961 return(0);
8963 seek_error:
8964 /* dump machine so we're in a known state */
8965 vf.pcm_offset=-1;
8966 decode_clear_(vf);
8967 return cast(int)result;
8970 /** seek to a sample offset relative to the decompressed pcm stream
8971 returns zero on success, nonzero on failure */
8972 public int ov_pcm_seek(OggVorbis_File *vf, ogg_int64_t pos){
8973 int thisblock, lastblock=0;
8974 int ret=ov_pcm_seek_page(vf, pos);
8975 if(ret<0)return(ret);
8976 if((ret=make_decode_ready_(vf)) != 0)return ret;
8978 /* discard leading packets we don't need for the lapping of the
8979 position we want; don't decode them */
8981 while(1){
8982 ogg_packet op;
8983 ogg_page og;
8985 /*int*/ ret=ogg_stream_packetpeek(&vf.os, &op);
8986 if(ret>0){
8987 thisblock=vorbis_packet_blocksize(vf.vi+vf.current_link, &op);
8988 if(thisblock<0){
8989 ogg_stream_packetout(&vf.os, null);
8990 continue; /* non audio packet */
8992 if(lastblock)vf.pcm_offset+=(lastblock+thisblock)>>2;
8994 if(vf.pcm_offset+((thisblock+vorbis_info_blocksize(vf.vi, 1))>>2)>=pos)break;
8996 /* remove the packet from packet queue and track its granulepos */
8997 ogg_stream_packetout(&vf.os, null);
8998 vorbis_synthesis_trackonly(&vf.vb, &op); /* set up a vb with
8999 only tracking, no
9000 pcm_decode */
9001 vorbis_synthesis_blockin(&vf.vd, &vf.vb);
9003 /* end of logical stream case is hard, especially with exact
9004 length positioning. */
9006 if(op.granulepos>-1){
9007 int i;
9008 /* always believe the stream markers */
9009 vf.pcm_offset=op.granulepos-vf.pcmlengths[vf.current_link*2];
9010 if(vf.pcm_offset<0)vf.pcm_offset=0;
9011 for(i=0;i<vf.current_link;i++)
9012 vf.pcm_offset+=vf.pcmlengths[i*2+1];
9015 lastblock=thisblock;
9017 }else{
9018 if(ret<0 && ret!=OV_HOLE)break;
9020 /* suck in a new page */
9021 if(get_next_page_(vf, &og, -1)<0)break;
9022 if(ogg_page_bos(&og))decode_clear_(vf);
9024 if(vf.ready_state<STREAMSET){
9025 ogg_uint32_t serialno=ogg_page_serialno(&og);
9026 int link;
9028 for(link=0;link<vf.links;link++)
9029 if(vf.serialnos[link]==serialno)break;
9030 if(link==vf.links) continue;
9031 vf.current_link=link;
9033 vf.ready_state=STREAMSET;
9034 vf.current_serialno=ogg_page_serialno(&og);
9035 ogg_stream_reset_serialno(&vf.os, serialno);
9036 ret=make_decode_ready_(vf);
9037 if(ret)return ret;
9038 lastblock=0;
9041 ogg_stream_pagein(&vf.os, &og);
9045 vf.bittrack=0;
9046 vf.samptrack=0;
9047 /* discard samples until we reach the desired position. Crossing a
9048 logical bitstream boundary with abandon is OK. */
9049 while(vf.pcm_offset<pos){
9050 ogg_int64_t target=pos-vf.pcm_offset;
9051 trm_long samples=vorbis_synthesis_pcmout(&vf.vd, null);
9053 if(samples>target)samples=cast(trm_long)target;
9054 vorbis_synthesis_read(&vf.vd, samples);
9055 vf.pcm_offset+=samples;
9057 if(samples<target)
9058 if(fetch_and_process_packet_(vf, null, 1, 1)<=0)
9059 vf.pcm_offset=ov_pcm_total(vf, -1); /* eof */
9061 return 0;
9064 /** seek to a playback time relative to the decompressed pcm stream
9065 returns zero on success, nonzero on failure */
9066 public int ov_time_seek(OggVorbis_File *vf, ogg_int64_t milliseconds){
9067 /* translate time to PCM position and call ov_pcm_seek */
9069 int link=-1;
9070 ogg_int64_t pcm_total=0;
9071 ogg_int64_t time_total=0;
9073 if(vf.ready_state<OPENED)return(OV_EINVAL);
9074 if(!vf.seekable)return(OV_ENOSEEK);
9075 if(milliseconds<0)return(OV_EINVAL);
9077 /* which bitstream section does this time offset occur in? */
9078 for(link=0;link<vf.links;link++){
9079 ogg_int64_t addsec = ov_time_total(vf, link);
9080 if(milliseconds<time_total+addsec)break;
9081 time_total+=addsec;
9082 pcm_total+=vf.pcmlengths[link*2+1];
9085 if(link==vf.links)return(OV_EINVAL);
9087 /* enough information to convert time offset to pcm offset */
9089 ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf.vi[link].rate/1000;
9090 return(ov_pcm_seek(vf, target));
9094 /** page-granularity version of ov_time_seek
9095 returns zero on success, nonzero on failure */
9096 public int ov_time_seek_page(OggVorbis_File *vf, ogg_int64_t milliseconds){
9097 /* translate time to PCM position and call ov_pcm_seek */
9099 int link=-1;
9100 ogg_int64_t pcm_total=0;
9101 ogg_int64_t time_total=0;
9103 if(vf.ready_state<OPENED)return(OV_EINVAL);
9104 if(!vf.seekable)return(OV_ENOSEEK);
9105 if(milliseconds<0)return(OV_EINVAL);
9107 /* which bitstream section does this time offset occur in? */
9108 for(link=0;link<vf.links;link++){
9109 ogg_int64_t addsec = ov_time_total(vf, link);
9110 if(milliseconds<time_total+addsec)break;
9111 time_total+=addsec;
9112 pcm_total+=vf.pcmlengths[link*2+1];
9115 if(link==vf.links)return(OV_EINVAL);
9117 /* enough information to convert time offset to pcm offset */
9119 ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf.vi[link].rate/1000;
9120 return(ov_pcm_seek_page(vf, target));
9124 /** tell the current stream offset cursor. Note that seek followed by
9125 tell will likely not give the set offset due to caching */
9126 public ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
9127 if(vf.ready_state<OPENED)return(OV_EINVAL);
9128 return(vf.offset);
9131 /// return PCM offset (sample) of next PCM sample to be read
9132 public ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
9133 if(vf.ready_state<OPENED)return(OV_EINVAL);
9134 return(vf.pcm_offset);
9137 /// return time offset (milliseconds) of next PCM sample to be read
9138 public ogg_int64_t ov_time_tell(OggVorbis_File *vf){
9139 int link=0;
9140 ogg_int64_t pcm_total=0;
9141 ogg_int64_t time_total=0;
9143 if(vf.ready_state<OPENED)return(OV_EINVAL);
9144 if(vf.seekable){
9145 pcm_total=ov_pcm_total(vf, -1);
9146 time_total=ov_time_total(vf, -1);
9148 /* which bitstream section does this time offset occur in? */
9149 for(link=vf.links-1;link>=0;link--){
9150 pcm_total-=vf.pcmlengths[link*2+1];
9151 time_total-=ov_time_total(vf, link);
9152 if(vf.pcm_offset>=pcm_total)break;
9156 return(time_total+(1000*vf.pcm_offset-pcm_total)/vf.vi[link].rate);
9159 /** link: -1: return the vorbis_info struct for the bitstream section
9160 currently being decoded
9161 0-n: to request information for a specific bitstream section
9163 In the case of a non-seekable bitstream, any call returns the
9164 current bitstream. null in the case that the machine is not
9165 initialized */
9166 public vorbis_info *ov_info(OggVorbis_File *vf, int link=-1){
9167 if(vf.seekable){
9168 if(link<0)
9169 if(vf.ready_state>=STREAMSET)
9170 return vf.vi+vf.current_link;
9171 else
9172 return vf.vi;
9173 else
9174 if(link>=vf.links)
9175 return null;
9176 else
9177 return vf.vi+link;
9178 }else{
9179 return vf.vi;
9183 /* grr, strong typing, grr, no templates/inheritence, grr */
9185 public vorbis_comment *ov_comment(OggVorbis_File *vf, int link=-1){
9186 if(vf.seekable){
9187 if(link<0)
9188 if(vf.ready_state>=STREAMSET)
9189 return vf.vc+vf.current_link;
9190 else
9191 return vf.vc;
9192 else
9193 if(link>=vf.links)
9194 return null;
9195 else
9196 return vf.vc+link;
9197 }else{
9198 return vf.vc;
9202 /** read data from ogg file
9204 up to this point, everything could more or less hide the multiple
9205 logical bitstream nature of chaining from the toplevel application
9206 if the toplevel application didn't particularly care. However, at
9207 the point that we actually read audio back, the multiple-section
9208 nature must surface: Multiple bitstream sections do not necessarily
9209 have to have the same number of channels or sampling rate.
9211 ov_read returns the sequential logical bitstream number currently
9212 being decoded along with the PCM data in order that the toplevel
9213 application can take action on channel/sample rate changes. This
9214 number will be incremented even for streamed (non-seekable) streams
9215 (for seekable streams, it represents the actual logical bitstream
9216 index within the physical bitstream. Note that the accessor
9217 functions above are aware of this dichotomy).
9219 input values:
9220 buffer: a buffer to hold packed PCM data for return
9221 bytes_req: the byte length requested to be placed into buffer
9223 return values:
9224 <0: error/hole in data (OV_HOLE), partial open (OV_EINVAL)
9225 0: EOF
9226 >0: number of bytes of PCM actually returned. The
9227 below works on a packet-by-packet basis, so the
9228 return length is not related to the 'length' passed
9229 in, just guaranteed to fit.
9231 *bitstream: set to the logical bitstream number */
9232 public trm_long ov_read(OggVorbis_File *vf, ubyte *buffer, int bytes_req, int *bitstream){
9233 int i, j;
9235 ogg_int32_t **pcm;
9236 trm_long samples;
9238 if(vf.ready_state<OPENED)return(OV_EINVAL);
9240 while(1){
9241 if(vf.ready_state==INITSET){
9242 samples=vorbis_synthesis_pcmout(&vf.vd, &pcm);
9243 if(samples)break;
9246 /* suck in another packet */
9248 int ret=fetch_and_process_packet_(vf, null, 1, 1);
9249 if(ret==OV_EOF)
9250 return(0);
9251 if(ret<=0)
9252 return(ret);
9257 if(samples>0){
9259 /* yay! proceed to pack data into the byte buffer */
9261 trm_long channels=ov_info(vf, -1).channels;
9263 if(samples>(bytes_req/(2*channels)))
9264 samples=bytes_req/(2*channels);
9266 for(i=0;i<channels;i++) { /* It's faster in this order */
9267 ogg_int32_t *src=pcm[i];
9268 short *dest=(cast(short *)buffer)+i;
9269 for(j=0;j<samples;j++) {
9270 *dest=cast(short)CLIP_TO_15(src[j]>>9);
9271 dest+=channels;
9275 vorbis_synthesis_read(&vf.vd, samples);
9276 vf.pcm_offset+=samples;
9277 if(bitstream)*bitstream=vf.current_link;
9278 return(samples*2*channels);
9279 }else{
9280 return(samples);
9285 // ////////////////////////////////////////////////////////////////////////// //
9286 private:
9287 static immutable trm_ulong[33] mask=
9288 [0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
9289 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
9290 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
9291 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
9292 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
9293 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
9294 0x3fffffff,0x7fffffff,0xffffffff ];
9296 static immutable uint[256] crc_lookup = (){
9297 // helper to initialize lookup for direct-table CRC (illustrative; we use the static init below)
9298 static uint ogg_crc_entry_ (uint index) /*nothrow @trusted @nogc*/ {
9299 uint r = index<<24;
9300 foreach (immutable _; 0..8) {
9301 if (r&0x80000000U) {
9302 r = (r<<1)^0x04c11db7;
9303 /* The same as the ethernet generator
9304 polynomial, although we use an
9305 unreflected alg and an init/final
9306 of 0, not 0xffffffff */
9307 } else {
9308 r <<= 1;
9311 return (r&0xffffffffU);
9313 uint[256] res;
9314 foreach (immutable idx, ref uint v; res[]) v = ogg_crc_entry_(cast(uint)idx);
9315 return res;
9316 }();
9318 struct ogg_iovec_t {
9319 void *iov_base;
9320 usize iov_len;
9323 struct oggpack_buffer {
9324 trm_long endbyte;
9325 int endbit;
9327 ubyte *buffer;
9328 ubyte *ptr;
9329 trm_long storage;
9332 /* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
9334 struct ogg_page {
9335 ubyte *header;
9336 trm_long header_len;
9337 ubyte *body_;
9338 trm_long body_len;
9341 /* ogg_stream_state contains the current encode/decode state of a logical
9342 Ogg bitstream **********************************************************/
9343 struct ogg_stream_state {
9344 ubyte *body_data; /* bytes from packet bodies */
9345 trm_long body_storage; /* storage elements allocated */
9346 trm_long body_fill; /* elements stored; fill mark */
9347 trm_long body_returned; /* elements of fill returned */
9350 int *lacing_vals; /* The values that will go to the segment table */
9351 ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
9352 this way, but it is simple coupled to the
9353 lacing fifo */
9354 trm_long lacing_storage;
9355 trm_long lacing_fill;
9356 trm_long lacing_packet;
9357 trm_long lacing_returned;
9359 ubyte[282] header; /* working space for header encode */
9360 int header_fill;
9362 int e_o_s; /* set when we have buffered the last packet in the
9363 logical bitstream */
9364 int b_o_s; /* set after we've written the initial page
9365 of a logical bitstream */
9366 trm_long serialno;
9367 trm_long pageno;
9368 ogg_int64_t packetno; /* sequence number for decode; the framing
9369 knows where there's a hole in the data,
9370 but we need coupling so that the codec
9371 (which is in a separate abstraction
9372 layer) also knows about the gap */
9373 ogg_int64_t granulepos;
9377 /* ogg_packet is used to encapsulate the data and metadata belonging
9378 to a single raw Ogg/Vorbis packet *************************************/
9379 struct ogg_packet {
9380 ubyte *packet;
9381 trm_long bytes;
9382 trm_long b_o_s;
9383 trm_long e_o_s;
9385 ogg_int64_t granulepos;
9387 ogg_int64_t packetno; /* sequence number for decode; the framing
9388 knows where there's a hole in the data,
9389 but we need coupling so that the codec
9390 (which is in a separate abstraction
9391 layer) also knows about the gap */
9394 struct ogg_sync_state {
9395 ubyte *data;
9396 int storage;
9397 int fill;
9398 int returned;
9400 int unsynced;
9401 int headerbytes;
9402 int bodybytes;
9406 /* bits <= 32 */
9407 trm_long oggpack_read(oggpack_buffer *b, int bits) nothrow @trusted @nogc {
9408 trm_long ret;
9409 trm_ulong m;
9411 if(bits<0 || bits>32) goto err;
9412 m=mask[bits];
9413 bits+=b.endbit;
9415 if(b.endbyte >= b.storage-4){
9416 /* not the main path */
9417 if(b.endbyte > b.storage-((bits+7)>>3)) goto overflow;
9418 /* special case to avoid reading b.ptr[0], which might be past the end of
9419 the buffer; also skips some useless accounting */
9420 else if(!bits)return(0L);
9423 ret=b.ptr[0]>>b.endbit;
9424 if(bits>8){
9425 ret|=b.ptr[1]<<(8-b.endbit);
9426 if(bits>16){
9427 ret|=b.ptr[2]<<(16-b.endbit);
9428 if(bits>24){
9429 ret|=b.ptr[3]<<(24-b.endbit);
9430 if(bits>32 && b.endbit){
9431 ret|=b.ptr[4]<<(32-b.endbit);
9436 ret&=m;
9437 b.ptr+=bits/8;
9438 b.endbyte+=bits/8;
9439 b.endbit=bits&7;
9440 return ret;
9442 overflow:
9443 err:
9444 b.ptr=null;
9445 b.endbyte=b.storage;
9446 b.endbit=1;
9447 return -1L;
9451 trm_long oggpack_bytes(oggpack_buffer *b) /*nothrow @trusted @nogc*/ {
9452 return(b.endbyte+(b.endbit+7)/8);
9455 /* Read in bits without advancing the bitptr; bits <= 32 */
9456 trm_long oggpack_look(oggpack_buffer *b, int bits) nothrow @trusted @nogc {
9457 trm_ulong ret;
9458 trm_ulong m;
9460 if(bits<0 || bits>32) return -1;
9461 m=mask[bits];
9462 bits+=b.endbit;
9464 if(b.endbyte >= b.storage-4){
9465 /* not the main path */
9466 if(b.endbyte > b.storage-((bits+7)>>3)) return -1;
9467 /* special case to avoid reading b.ptr[0], which might be past the end of
9468 the buffer; also skips some useless accounting */
9469 else if(!bits)return(0L);
9472 ret=b.ptr[0]>>b.endbit;
9473 if(bits>8){
9474 ret|=b.ptr[1]<<(8-b.endbit);
9475 if(bits>16){
9476 ret|=b.ptr[2]<<(16-b.endbit);
9477 if(bits>24){
9478 ret|=b.ptr[3]<<(24-b.endbit);
9479 if(bits>32 && b.endbit)
9480 ret|=b.ptr[4]<<(32-b.endbit);
9484 return(m&ret);
9487 void oggpack_adv(oggpack_buffer *b, int bits) nothrow @trusted @nogc {
9488 bits+=b.endbit;
9490 if(b.endbyte > b.storage-((bits+7)>>3)) goto overflow;
9492 b.ptr+=bits/8;
9493 b.endbyte+=bits/8;
9494 b.endbit=bits&7;
9495 return;
9497 overflow:
9498 b.ptr=null;
9499 b.endbyte=b.storage;
9500 b.endbit=1;
9503 void oggpack_readinit(oggpack_buffer *b, ubyte *buf, int bytes) /*nothrow @trusted @nogc*/ {
9504 memset(b, 0, (*b).sizeof);
9505 b.buffer=b.ptr=buf;
9506 b.storage=bytes;
9509 char *ogg_sync_buffer(ogg_sync_state *oy, trm_long size) /*nothrow @trusted @nogc*/ {
9510 if(ogg_sync_check(oy)) return null;
9512 /* first, clear out any space that has been previously returned */
9513 if(oy.returned){
9514 oy.fill-=oy.returned;
9515 if(oy.fill>0)
9516 memmove(oy.data, oy.data+oy.returned, oy.fill);
9517 oy.returned=0;
9520 if(size>oy.storage-oy.fill){
9521 /* We need to extend the internal buffer */
9522 trm_long newsize=size+oy.fill+4096; /* an extra page to be nice */
9523 void *ret;
9525 if(oy.data)
9526 ret=ogg_realloc_(oy.data, newsize);
9527 else
9528 ret=ogg_malloc_(newsize);
9529 if(!ret){
9530 ogg_sync_clear(oy);
9531 return null;
9533 oy.data=cast(ubyte*)ret;
9534 oy.storage=newsize;
9537 /* expose a segment at least as large as requested at the fill mark */
9538 return(cast(char *)oy.data+oy.fill);
9541 int ogg_sync_wrote(ogg_sync_state *oy, trm_long bytes) /*nothrow @trusted @nogc*/ {
9542 if(ogg_sync_check(oy))return -1;
9543 if(oy.fill+bytes>oy.storage)return -1;
9544 oy.fill+=bytes;
9545 return(0);
9548 /* clear things to an initial state. Good to call, eg, before seeking */
9549 int ogg_sync_reset(ogg_sync_state *oy) /*nothrow @trusted @nogc*/ {
9550 if(ogg_sync_check(oy))return -1;
9552 oy.fill=0;
9553 oy.returned=0;
9554 oy.unsynced=0;
9555 oy.headerbytes=0;
9556 oy.bodybytes=0;
9557 return(0);
9560 trm_long ogg_sync_pageseek(ogg_sync_state *oy, ogg_page *og) /*nothrow @trusted @nogc*/ {
9561 ubyte *page=oy.data+oy.returned;
9562 ubyte *next;
9563 trm_long bytes=oy.fill-oy.returned;
9565 if(ogg_sync_check(oy))return 0;
9567 if(oy.headerbytes==0){
9568 int headerbytes, i;
9569 if(bytes<27)return(0); /* not enough for a header */
9571 /* verify capture pattern */
9572 if(memcmp(page, "OggS".ptr, 4))goto sync_fail;
9574 headerbytes=page[26]+27;
9575 if(bytes<headerbytes)return(0); /* not enough for header + seg table */
9577 /* count up body length in the segment table */
9579 for(i=0;i<page[26];i++)
9580 oy.bodybytes+=page[27+i];
9581 oy.headerbytes=headerbytes;
9584 if(oy.bodybytes+oy.headerbytes>bytes)return(0);
9586 /* The whole test page is buffered. Verify the checksum */
9588 /* Grab the checksum bytes, set the header field to zero */
9589 char[4] chksum = 0;
9590 ogg_page log;
9592 memcpy(chksum.ptr, page+22, 4);
9593 memset(page+22, 0, 4);
9595 /* set up a temp page struct and recompute the checksum */
9596 log.header=page;
9597 log.header_len=oy.headerbytes;
9598 log.body_=page+oy.headerbytes;
9599 log.body_len=oy.bodybytes;
9600 ogg_page_checksum_set(&log);
9602 /* Compare */
9603 if(memcmp(chksum.ptr, page+22, 4)){
9604 /* D'oh. Mismatch! Corrupt page (or miscapture and not a page
9605 at all) */
9606 /* replace the computed checksum with the one actually read in */
9607 memcpy(page+22, chksum.ptr, 4);
9609 /* Bad checksum. Lose sync */
9610 goto sync_fail;
9614 /* yes, have a whole page all ready to go */
9616 /*ubyte* */page=oy.data+oy.returned;
9617 //trm_long bytes;
9619 if(og){
9620 og.header=page;
9621 og.header_len=oy.headerbytes;
9622 og.body_=page+oy.headerbytes;
9623 og.body_len=oy.bodybytes;
9626 oy.unsynced=0;
9627 oy.returned+=(bytes=oy.headerbytes+oy.bodybytes);
9628 oy.headerbytes=0;
9629 oy.bodybytes=0;
9630 return(bytes);
9633 sync_fail:
9635 oy.headerbytes=0;
9636 oy.bodybytes=0;
9638 /* search for possible capture */
9639 next=cast(ubyte*)memchr(page+1, 'O', bytes-1);
9640 if(!next)
9641 next=oy.data+oy.fill;
9643 oy.returned=cast(int)(next-oy.data);
9644 return(cast(trm_long)-(next-page));
9647 int ogg_page_version(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9648 return(cast(int)(og.header[4]));
9651 trm_long ogg_page_pageno(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9652 return(og.header[18] |
9653 (og.header[19]<<8) |
9654 (og.header[20]<<16) |
9655 (og.header[21]<<24));
9658 int ogg_page_serialno(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9659 return(og.header[14] |
9660 (og.header[15]<<8) |
9661 (og.header[16]<<16) |
9662 (og.header[17]<<24));
9665 ogg_int64_t ogg_page_granulepos(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9666 const(ubyte)* page=og.header;
9667 ogg_int64_t granulepos=page[13]&(0xff);
9668 granulepos= (granulepos<<8)|(page[12]&0xff);
9669 granulepos= (granulepos<<8)|(page[11]&0xff);
9670 granulepos= (granulepos<<8)|(page[10]&0xff);
9671 granulepos= (granulepos<<8)|(page[9]&0xff);
9672 granulepos= (granulepos<<8)|(page[8]&0xff);
9673 granulepos= (granulepos<<8)|(page[7]&0xff);
9674 granulepos= (granulepos<<8)|(page[6]&0xff);
9675 return(granulepos);
9678 int ogg_page_continued(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9679 return(cast(int)(og.header[5]&0x01));
9682 int ogg_page_bos(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9683 return(cast(int)(og.header[5]&0x02));
9686 int ogg_page_eos(const ogg_page *og) /*nothrow @trusted @nogc*/ {
9687 return(cast(int)(og.header[5]&0x04));
9690 int ogg_stream_reset_serialno(ogg_stream_state *os, int serialno) /*nothrow @trusted @nogc*/ {
9691 if(ogg_stream_check(os)) return -1;
9692 ogg_stream_reset(os);
9693 os.serialno=serialno;
9694 return(0);
9697 /* add the incoming page to the stream state; we decompose the page into packet segments here as well. */
9699 int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og) /*nothrow @trusted @nogc*/ {
9700 ubyte *header=og.header;
9701 ubyte *body_=og.body_;
9702 trm_long bodysize=og.body_len;
9703 int segptr=0;
9705 int ver=ogg_page_version(og);
9706 int continued=ogg_page_continued(og);
9707 int bos=ogg_page_bos(og);
9708 int eos=ogg_page_eos(og);
9709 ogg_int64_t granulepos=ogg_page_granulepos(og);
9710 int serialno=ogg_page_serialno(og);
9711 trm_long pageno=ogg_page_pageno(og);
9712 int segments=header[26];
9714 if(ogg_stream_check(os)) return -1;
9716 /* clean up 'returned data' */
9718 trm_long lr=os.lacing_returned;
9719 trm_long br=os.body_returned;
9721 /* body data */
9722 if(br){
9723 os.body_fill-=br;
9724 if(os.body_fill)
9725 memmove(os.body_data, os.body_data+br, os.body_fill);
9726 os.body_returned=0;
9729 if(lr){
9730 /* segment table */
9731 if(os.lacing_fill-lr){
9732 memmove(os.lacing_vals, os.lacing_vals+lr,
9733 (os.lacing_fill-lr)*(*os.lacing_vals).sizeof);
9734 memmove(os.granule_vals, os.granule_vals+lr,
9735 (os.lacing_fill-lr)*(*os.granule_vals).sizeof);
9737 os.lacing_fill-=lr;
9738 os.lacing_packet-=lr;
9739 os.lacing_returned=0;
9743 /* check the serial number */
9744 if(serialno!=os.serialno)return(-1);
9745 if(ver>0)return(-1);
9747 if(os_lacing_expand_(os, segments+1)) return -1;
9749 /* are we in sequence? */
9750 if(pageno!=os.pageno){
9751 int i;
9753 /* unroll previous partial packet (if any) */
9754 for(i=os.lacing_packet;i<os.lacing_fill;i++)
9755 os.body_fill-=os.lacing_vals[i]&0xff;
9756 os.lacing_fill=os.lacing_packet;
9758 /* make a note of dropped data in segment table */
9759 if(os.pageno!=-1){
9760 os.lacing_vals[os.lacing_fill++]=0x400;
9761 os.lacing_packet++;
9765 /* are we a 'continued packet' page? If so, we may need to skip
9766 some segments */
9767 if(continued){
9768 if(os.lacing_fill<1 ||
9769 os.lacing_vals[os.lacing_fill-1]==0x400){
9770 bos=0;
9771 for(;segptr<segments;segptr++){
9772 int val=header[27+segptr];
9773 body_+=val;
9774 bodysize-=val;
9775 if(val<255){
9776 segptr++;
9777 break;
9783 if(bodysize){
9784 if(os_body_expand_(os, bodysize)) return -1;
9785 memcpy(os.body_data+os.body_fill, body_, bodysize);
9786 os.body_fill+=bodysize;
9790 int saved=-1;
9791 while(segptr<segments){
9792 int val=header[27+segptr];
9793 os.lacing_vals[os.lacing_fill]=val;
9794 os.granule_vals[os.lacing_fill]=-1;
9796 if(bos){
9797 os.lacing_vals[os.lacing_fill]|=0x100;
9798 bos=0;
9801 if(val<255)saved=os.lacing_fill;
9803 os.lacing_fill++;
9804 segptr++;
9806 if(val<255)os.lacing_packet=os.lacing_fill;
9809 /* set the granulepos on the last granuleval of the last full packet */
9810 if(saved!=-1){
9811 os.granule_vals[saved]=granulepos;
9816 if(eos){
9817 os.e_o_s=1;
9818 if(os.lacing_fill>0)
9819 os.lacing_vals[os.lacing_fill-1]|=0x200;
9822 os.pageno=pageno+1;
9824 return(0);
9827 int ogg_stream_packetout(ogg_stream_state *os, ogg_packet *op) /*nothrow @trusted @nogc*/ {
9828 if(ogg_stream_check(os)) return 0;
9829 return packetout_(os, op, 1);
9832 /* initialize the struct to a known state */
9833 int ogg_sync_init(ogg_sync_state *oy) /*nothrow @trusted @nogc*/ {
9834 if(oy){
9835 oy.storage = -1; /* used as a readiness flag */
9836 memset(oy, 0, (*oy).sizeof);
9838 return(0);
9841 /* init the encode/decode logical stream state */
9843 int ogg_stream_init(ogg_stream_state *os, int serialno) /*nothrow @trusted @nogc*/ {
9844 if(os){
9845 memset(os, 0, (*os).sizeof);
9846 os.body_storage=16*1024;
9847 os.lacing_storage=1024;
9849 os.body_data=cast(ubyte*)ogg_malloc_(os.body_storage*(*os.body_data).sizeof);
9850 os.lacing_vals=cast(int*)ogg_malloc_(os.lacing_storage*(*os.lacing_vals).sizeof);
9851 os.granule_vals=cast(long*)ogg_malloc_(os.lacing_storage*(*os.granule_vals).sizeof);
9853 if(!os.body_data || !os.lacing_vals || !os.granule_vals){
9854 ogg_stream_clear(os);
9855 return -1;
9858 os.serialno=serialno;
9860 return(0);
9862 return(-1);
9865 /* clear_ does not free os, only the non-flat storage within */
9866 int ogg_stream_clear(ogg_stream_state *os) /*nothrow @trusted @nogc*/ {
9867 if(os){
9868 if(os.body_data)ogg_free_(os.body_data);
9869 if(os.lacing_vals)ogg_free_(os.lacing_vals);
9870 if(os.granule_vals)ogg_free_(os.granule_vals);
9872 memset(os, 0, (*os).sizeof);
9874 return(0);
9877 /* clear non-flat storage within */
9878 int ogg_sync_clear(ogg_sync_state *oy) /*nothrow @trusted @nogc*/ {
9879 if(oy){
9880 if(oy.data)ogg_free_(oy.data);
9881 memset(oy, 0, (*oy).sizeof);
9883 return(0);
9886 int ogg_stream_reset(ogg_stream_state *os) /*nothrow @trusted @nogc*/ {
9887 if(ogg_stream_check(os)) return -1;
9889 os.body_fill=0;
9890 os.body_returned=0;
9892 os.lacing_fill=0;
9893 os.lacing_packet=0;
9894 os.lacing_returned=0;
9896 os.header_fill=0;
9898 os.e_o_s=0;
9899 os.b_o_s=0;
9900 os.pageno=-1;
9901 os.packetno=0;
9902 os.granulepos=0;
9904 return(0);
9907 int ogg_stream_packetpeek(ogg_stream_state *os, ogg_packet *op) /*nothrow @trusted @nogc*/ {
9908 if(ogg_stream_check(os)) return 0;
9909 return packetout_(os, op, 0);
9912 int ogg_sync_check(ogg_sync_state *oy) /*nothrow @trusted @nogc*/ {
9913 if(oy.storage<0) return -1;
9914 return 0;
9917 void ogg_page_checksum_set(ogg_page *og) /*nothrow @trusted @nogc*/ {
9918 if(og){
9919 ogg_uint32_t crc_reg=0;
9920 int i;
9922 /* safety; needed for API behavior, but not framing code */
9923 og.header[22]=0;
9924 og.header[23]=0;
9925 og.header[24]=0;
9926 og.header[25]=0;
9928 for(i=0;i<og.header_len;i++)
9929 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og.header[i]];
9930 for(i=0;i<og.body_len;i++)
9931 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og.body_[i]];
9933 og.header[22]=cast(ubyte)(crc_reg&0xff);
9934 og.header[23]=cast(ubyte)((crc_reg>>8)&0xff);
9935 og.header[24]=cast(ubyte)((crc_reg>>16)&0xff);
9936 og.header[25]=cast(ubyte)((crc_reg>>24)&0xff);
9940 /* async/delayed error detection for the ogg_stream_state */
9941 int ogg_stream_check(ogg_stream_state *os) /*nothrow @trusted @nogc*/ {
9942 if(!os || !os.body_data) return -1;
9943 return 0;
9946 private int packetout_(ogg_stream_state *os, ogg_packet *op, int adv) /*nothrow @trusted @nogc*/ {
9948 /* The last part of decode. We have the stream broken into packet
9949 segments. Now we need to group them into packets (or return the
9950 out of sync markers) */
9952 int ptr=os.lacing_returned;
9954 if(os.lacing_packet<=ptr)return(0);
9956 if(os.lacing_vals[ptr]&0x400){
9957 /* we need to tell the codec there's a gap; it might need to
9958 handle previous packet dependencies. */
9959 os.lacing_returned++;
9960 os.packetno++;
9961 return(-1);
9964 if(!op && !adv)return(1); /* just using peek as an inexpensive way
9965 to ask if there's a whole packet
9966 waiting */
9968 /* Gather the whole packet. We'll have no holes or a partial packet */
9970 int size=os.lacing_vals[ptr]&0xff;
9971 trm_long bytes=size;
9972 int eos=os.lacing_vals[ptr]&0x200; /* last packet of the stream? */
9973 int bos=os.lacing_vals[ptr]&0x100; /* first packet of the stream? */
9975 while(size==255){
9976 int val=os.lacing_vals[++ptr];
9977 size=val&0xff;
9978 if(val&0x200)eos=0x200;
9979 bytes+=size;
9982 if(op){
9983 op.e_o_s=eos;
9984 op.b_o_s=bos;
9985 op.packet=os.body_data+os.body_returned;
9986 op.packetno=os.packetno;
9987 op.granulepos=os.granule_vals[ptr];
9988 op.bytes=bytes;
9991 if(adv){
9992 os.body_returned+=bytes;
9993 os.lacing_returned=ptr+1;
9994 os.packetno++;
9997 return(1);
10000 private int os_lacing_expand_(ogg_stream_state *os, trm_long needed) /*nothrow @trusted @nogc*/ {
10001 if(os.lacing_storage-needed<=os.lacing_fill){
10002 trm_long lacing_storage;
10003 void *ret;
10004 if(os.lacing_storage>LONG_MAX-needed){
10005 ogg_stream_clear(os);
10006 return -1;
10008 lacing_storage=os.lacing_storage+needed;
10009 if(lacing_storage<LONG_MAX-32)lacing_storage+=32;
10010 ret=ogg_realloc_(os.lacing_vals, lacing_storage*(*os.lacing_vals).sizeof);
10011 if(!ret){
10012 ogg_stream_clear(os);
10013 return -1;
10015 os.lacing_vals=cast(int*)ret;
10016 ret=ogg_realloc_(os.granule_vals, lacing_storage*
10017 (*os.granule_vals).sizeof);
10018 if(!ret){
10019 ogg_stream_clear(os);
10020 return -1;
10022 os.granule_vals=cast(long*)ret;
10023 os.lacing_storage=lacing_storage;
10025 return 0;
10028 private int os_body_expand_(ogg_stream_state *os, trm_long needed) /*nothrow @trusted @nogc*/ {
10029 if(os.body_storage-needed<=os.body_fill){
10030 trm_long body_storage;
10031 void *ret;
10032 if(os.body_storage>LONG_MAX-needed){
10033 ogg_stream_clear(os);
10034 return -1;
10036 body_storage=os.body_storage+needed;
10037 if(body_storage<LONG_MAX-1024)body_storage+=1024;
10038 ret=ogg_realloc_(os.body_data, body_storage*(*os.body_data).sizeof);
10039 if(!ret){
10040 ogg_stream_clear(os);
10041 return -1;
10043 os.body_storage=body_storage;
10044 os.body_data=cast(ubyte*)ret;
10046 return 0;