diff options
author | waker <wakeroid@gmail.com> | 2013-01-12 20:15:42 +0100 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2013-01-12 20:17:42 +0100 |
commit | 8192c8dd8e565b37811ea2dcbd70d49b56f28883 (patch) | |
tree | 4fe4479ac7f596409e5df4c41470a922903bfd9d | |
parent | 8c92d931ce7f001ffaccc535e025ec1a2e7d0c30 (diff) | |
parent | 94e2ef5704b74ebca17d9add9b6c3587514123e2 (diff) |
Merge branch 'wmaplug' into devel
Conflicts:
configure.ac
plugins/flac/flac.c
27 files changed, 11412 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac index de044900..014d2a66 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ AC_INIT([deadbeef], [devel]) AC_CONFIG_HEADER(config.h) AM_INIT_AUTOMAKE([1.11 dist-bzip2]) -AM_SILENT_RULES([yes]) +dnl AM_SILENT_RULES([yes]) AM_MAINTAINER_MODE() AC_USE_SYSTEM_EXTENSIONS @@ -111,7 +111,8 @@ AC_ARG_ENABLE(psf, [AS_HELP_STRING([--enable-psf ], [build AOSDK-based AC_ARG_ENABLE(mono2stereo, [AS_HELP_STRING([--enable-mono2stereo ], [build mono2stereo DSP plugin (default: auto)])], [enable_mono2stereo=$enableval], [enable_mono2stereo=yes]) AC_ARG_ENABLE(shellexecui, [AS_HELP_STRING([--enable-shellexecui ], [build shellexec GTK UI plugin (default: auto)])], [enable_shellexecui=$enableval], [enable_shellexecui=yes]) AC_ARG_ENABLE(alac, [AS_HELP_STRING([--enable-alac ], [build ALAC plugin (default: auto)])], [enable_alac=$enableval], [enable_alac=yes]) -AC_ARG_ENABLE(abstract_socket, [AS_HELP_STRING([--enable-abstract-socket ], [use abstract socket (default: enabled)])], [enable_abstract_socket=$enableval], [enable_abstract_socket=yes]) +AC_ARG_ENABLE(wma, [AS_HELP_STRING([--enable-wma ], [build WMA plugin (default: auto)])], [enable_wma=$enableval], [enable_wma=yes]) +AC_ARG_ENABLE(abstract_socket, [AS_HELP_STRING([--enable-abstract-socket ], [use abstract UNIX socket for IPC (default: disabled)])], [enable_abstract_socket=$enableval], [enable_abstract_socket=no]) AS_IF([test "${enable_staticlink}" != "no"], [ AC_DEFINE_UNQUOTED([STATICLINK], [1], [Define if building static version]) @@ -610,7 +611,11 @@ AS_IF([test "${enable_alac}" != "no"], [ HAVE_ALAC=yes ]) -PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shellexec plugins/dsp_libsrc plugins/m3u plugins/vfs_zip plugins/converter plugins/dumb plugins/shn plugins/ao plugins/mono2stereo plugins/shellexecui plugins/alac plugins/medialib" +AS_IF([test "${enable_wma}" != "no"], [ + HAVE_WMA=yes +]) + +PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shellexec plugins/dsp_libsrc plugins/m3u plugins/vfs_zip plugins/converter plugins/dumb plugins/shn plugins/ao plugins/mono2stereo plugins/shellexecui plugins/alac plugins/medialib plugins/wma" AM_CONDITIONAL(HAVE_VORBIS, test "x$HAVE_VORBISPLUGIN" = "xyes") AM_CONDITIONAL(HAVE_FLAC, test "x$HAVE_FLACPLUGIN" = "xyes") @@ -660,6 +665,7 @@ AM_CONDITIONAL(HAVE_SHELLEXECUI, test "x$HAVE_SHELLEXECUI" = "xyes") AM_CONDITIONAL(HAVE_SM, test "x$HAVE_SM" = "xyes") AM_CONDITIONAL(HAVE_ICE, test "x$HAVE_ICE" = "xyes") AM_CONDITIONAL(HAVE_ALAC, test "x$HAVE_ALAC" = "xyes") +AM_CONDITIONAL(HAVE_WMA, test "x$HAVE_WMA" = "xyes") AM_CONDITIONAL(STATICLINK, test "x$STATICLINK" = "xyes") AM_CONDITIONAL(PORTABLE, test "x$PORTABLE" = "xyes") AM_CONDITIONAL(PORTABLE_FULL, test "x$PORTABLE_FULL" = "xyes") @@ -732,6 +738,7 @@ PRINT_PLUGIN_INFO([shn],[SHN plugin based on xmms-shn],[test "x$HAVE_SHN" = "xye PRINT_PLUGIN_INFO([mono2stereo],[mono2stereo DSP plugin],[test "x$HAVE_MONO2STEREO" = "xyes"]) PRINT_PLUGIN_INFO([shellexecui],[GTK user interface for configuring shellexec plugin],[test "x$HAVE_SHELLEXECUI" = "xyes"]) PRINT_PLUGIN_INFO([alac],[ALAC plugin],[test "x$HAVE_ALAC" = "xyes"]) +PRINT_PLUGIN_INFO([wma],[WMA plugin],[test "x$HAVE_WMA" = "xyes"]) echo @@ -780,6 +787,7 @@ plugins/shn/Makefile plugins/mono2stereo/Makefile plugins/shellexecui/Makefile plugins/alac/Makefile +plugins/wma/Makefile intl/Makefile po/Makefile.in deadbeef.desktop diff --git a/plugins/gme/cgme.c b/plugins/gme/cgme.c index 773b3736..8c428444 100644 --- a/plugins/gme/cgme.c +++ b/plugins/gme/cgme.c @@ -436,6 +436,8 @@ cgme_mutevoice (int voice, int mute) { static int cgme_start (void) { + conf_fadeout = deadbeef->conf_get_int ("gme.fadeout", 10); + conf_loopcount = deadbeef->conf_get_int ("gme.loopcount", 2); return 0; } diff --git a/plugins/wma/Makefile.am b/plugins/wma/Makefile.am new file mode 100644 index 00000000..0d6d1eb7 --- /dev/null +++ b/plugins/wma/Makefile.am @@ -0,0 +1,46 @@ +if HAVE_WMA +wmadir = $(libdir)/$(PACKAGE) +wmapath=@top_srcdir@/plugins/wma +pkglib_LTLIBRARIES = wma.la +wma_la_SOURCES = wma_plugin.c\ + asfheader.c\ + libasf/asf.c\ + libasf/asf.h\ + libwma/wmafixed.c\ + libwma/wmadeci.c\ + libwma/fft-ffmpeg.c\ + libwma/mdct_lookup.c\ + libwma/mdct.c\ + libwma/ffmpeg_bitstream.c\ + libwma/asm_arm.h\ + libwma/fft-ffmpeg_arm.h\ + libwma/types.h\ + libwma/codeclib_misc.h\ + libwma/fft.h\ + libwma/wmadata.h\ + libwma/ffmpeg_get_bits.h\ + libwma/mdct.h\ + libwma/wmadec.h\ + libwma/ffmpeg_intreadwrite.h\ + libwma/mdct_lookup.h\ + libwma/wmafixed.h + +# libwma-ff/wma.c\ +# libwma-ff/wmadec.c\ +# libwma-ff/wma_common.c\ +# libwma-ff/bitstream.c\ +# libwma-ff/mathematics.c\ +# libwma-ff/mdct.c\ +# libwma-ff/fft.c\ +# libwma-ff/aactab.c + + + + +wma_la_LDFLAGS = -module + +wma_la_LIBADD = $(LDADD) +AM_CFLAGS = $(CFLAGS) -std=c99 -I$(wmapath) +endif + + diff --git a/plugins/wma/asfheader.c b/plugins/wma/asfheader.c new file mode 100644 index 00000000..95dd0299 --- /dev/null +++ b/plugins/wma/asfheader.c @@ -0,0 +1,814 @@ +// this file is a modified version for deadbeef player +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <inttypes.h> +#include <unistd.h> +#include "../../deadbeef.h" + +#include <libasf/asf.h> + +#define MIN(x,y) ((x)<(y)?(x):(y)) +#define MAX(x,y) ((x)>(y)?(x):(y)) + +//#define trace(...) { fprintf (stderr, __VA_ARGS__); } +#define trace(fmt,...) +#define DEBUGF trace + +extern DB_functions_t *deadbeef; + +enum { + AFMT_WMAPRO = 1, + AFMT_WMAVOICE = 2, +}; + +static inline uint16_t swap16(uint16_t value) + /* + result[15..8] = value[ 7..0]; + result[ 7..0] = value[15..8]; + */ +{ + return (value >> 8) | (value << 8); +} + + +static inline uint32_t swap32(uint32_t value) + /* + result[31..24] = value[ 7.. 0]; + result[23..16] = value[15.. 8]; + result[15.. 8] = value[23..16]; + result[ 7.. 0] = value[31..24]; + */ +{ + uint32_t hi = swap16(value >> 16); + uint32_t lo = swap16(value & 0xffff); + return (lo << 16) | hi; +} + +#if WORDS_BIGENDIAN +#define read_uint16be(fd,buf) deadbeef->fread((buf), 2, 1, (fd)) +#define read_uint32be(fd,buf) deadbeef->fread((buf), 4, 1, (fd)) +#define read_uint64be(fd,buf) deadbeef->fread((buf), 8, 1, (fd)) +int read_uint16le(DB_FILE *fd, uint16_t* buf); +int read_uint32le(DB_FILE *fd, uint32_t* buf); +int read_uint64le(DB_FILE *fd, uint64_t* buf); +#define letoh16(x) swap16(x) +#define letoh32(x) swap32(x) +#define htole16(x) swap16(x) +#define htole32(x) swap32(x) +#define betoh16(x) (x) +#define betoh32(x) (x) +#define htobe16(x) (x) +#define htobe32(x) (x) +#define swap_odd_even_be32(x) swap_odd_even32(x) +#define swap_odd_even_le32(x) (x) +#else +#define letoh16(x) (x) +#define letoh32(x) (x) +#define htole16(x) (x) +#define htole32(x) (x) +#define betoh16(x) swap16(x) +#define betoh32(x) swap32(x) +//#define htobe16(x) swap16(x) +//#define htobe32(x) swap32(x) +#define swap_odd_even_be32(x) (x) +#define swap_odd_even_le32(x) swap_odd_even32(x) +int read_uint16be(DB_FILE *fd, uint16_t* buf); +int read_uint32be(DB_FILE *fd, uint32_t* buf); +int read_uint64be(DB_FILE *fd, uint64_t* buf); +#define read_uint16le(fd,buf) deadbeef->fread((buf), 2, 1, (fd)) +#define read_uint32le(fd,buf) deadbeef->fread((buf), 4, 1, (fd)) +#define read_uint64le(fd,buf) deadbeef->fread((buf), 8, 1, (fd)) +#endif + + +#if !WORDS_BIGENDIAN +/* Read an unsigned 16-bit integer from a big-endian file. */ +int read_uint16be(DB_FILE *fd, uint16_t* buf) +{ + size_t n; + + n = deadbeef->fread(buf, 1, 2, fd); + *buf = betoh16(*buf); + return n; +} +/* Read an unsigned 32-bit integer from a big-endian file. */ +int read_uint32be(DB_FILE *fd, uint32_t* buf) +{ + size_t n; + + n = deadbeef->fread(buf, 1, 4, fd); + *buf = betoh32(*buf); + return n; +} +/* Read an unsigned 64-bit integer from a big-endian file. */ +int read_uint64be(DB_FILE *fd, uint64_t* buf) +{ + size_t n; + uint8_t data[8]; + int i; + + n = deadbeef->fread(data, 1, 8, fd); + + for (i=0, *buf=0; i<=7; i++) { + *buf <<= 8; + *buf |= data[i]; + } + return n; +} +#else +/* Read unsigned integers from a little-endian file. */ +int read_uint16le(DB_FILE *fd, uint16_t* buf) +{ + size_t n; + + n = deadbeef->fread((char*) buf, 1, 2, fd); + *buf = letoh16(*buf); + return n; +} +int read_uint32le(DB_FILE *fd, uint32_t* buf) +{ + size_t n; + + n = deadbeef->fread(buf, 1, 4, fd); + *buf = letoh32(*buf); + return n; +} +int read_uint64le(DB_FILE *fd, uint64_t* buf) +{ + size_t n; + uint8_t data[8]; + int i; + + n = deadbeef->fread(data, 1, 8, fd); + + for (i=7, *buf=0; i>=0; i--) { + *buf <<= 8; + *buf |= data[i]; + } + + return n; +} +#endif + +/* TODO: Just read the GUIDs into a 16-byte array, and use memcmp to compare */ +struct guid_s { + uint32_t v1; + uint16_t v2; + uint16_t v3; + uint8_t v4[8]; +}; +typedef struct guid_s guid_t; + +struct asf_object_s { + guid_t guid; + uint64_t size; + uint64_t datalen; +}; +typedef struct asf_object_s asf_object_t; + +static const guid_t asf_guid_null = +{0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +/* top level object guids */ + +static const guid_t asf_guid_header = +{0x75B22630, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}}; + +static const guid_t asf_guid_data = +{0x75B22636, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}}; + +static const guid_t asf_guid_index = +{0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}}; + +/* header level object guids */ + +static const guid_t asf_guid_file_properties = +{0x8cabdca1, 0xa947, 0x11cf, {0x8E, 0xe4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}}; + +static const guid_t asf_guid_stream_properties = +{0xB7DC0791, 0xA9B7, 0x11CF, {0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}}; + +static const guid_t asf_guid_content_description = +{0x75B22633, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}}; + +static const guid_t asf_guid_extended_content_description = +{0xD2D0A440, 0xE307, 0x11D2, {0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50}}; + +static const guid_t asf_guid_content_encryption = +{0x2211b3fb, 0xbd23, 0x11d2, {0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e}}; + +static const guid_t asf_guid_extended_content_encryption = +{0x298ae614, 0x2622, 0x4c17, {0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c}}; + +/* stream type guids */ + +static const guid_t asf_guid_stream_type_audio = +{0xF8699E40, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}}; + +static int asf_guid_match(const guid_t *guid1, const guid_t *guid2) +{ + if((guid1->v1 != guid2->v1) || + (guid1->v2 != guid2->v2) || + (guid1->v3 != guid2->v3) || + (memcmp(guid1->v4, guid2->v4, 8))) { + return 0; + } + + return 1; +} + +/* Read the 16 byte GUID from a file */ +static void asf_readGUID(DB_FILE *fd, guid_t* guid) +{ + read_uint32le(fd, &guid->v1); + read_uint16le(fd, &guid->v2); + read_uint16le(fd, &guid->v3); + deadbeef->fread(guid->v4, 8, 1, fd); +} + +static void asf_read_object_header(asf_object_t *obj, DB_FILE *fd) +{ + asf_readGUID(fd, &obj->guid); + read_uint64le(fd, &obj->size); + obj->datalen = 0; +} + +/* Parse an integer from the extended content object - we always + convert to an int, regardless of native format. +*/ +static int asf_intdecode(DB_FILE *fd, int type, int length) +{ + uint16_t tmp16; + uint32_t tmp32; + uint64_t tmp64; + + if (type == 3) { + read_uint32le(fd, &tmp32); + deadbeef->fseek(fd,length - 4,SEEK_CUR); + return (int)tmp32; + } else if (type == 4) { + read_uint64le(fd, &tmp64); + deadbeef->fseek(fd,length - 8,SEEK_CUR); + return (int)tmp64; + } else if (type == 5) { + read_uint16le(fd, &tmp16); + deadbeef->fseek(fd,length - 2,SEEK_CUR); + return (int)tmp16; + } + + return 0; +} + +/* Decode a LE utf16 string from a disk buffer into a fixed-sized + utf8 buffer. +*/ +#define MASK 0xC0 /* 11000000 */ +#define COMP 0x80 /* 10x */ + +static const unsigned char utf8comp[6] = +{ + 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC +}; + +/* Encode a UCS value as UTF-8 and return a pointer after this UTF-8 char. */ +unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8) +{ + int tail = 0; + + if (ucs > 0x7F) + while (ucs >> (5*tail + 6)) + tail++; + + *utf8++ = (ucs >> (6*tail)) | utf8comp[tail]; + while (tail--) + *utf8++ = ((ucs >> (6*tail)) & (MASK ^ 0xFF)) | COMP; + + return utf8; +} + + +static void asf_utf16LEdecode(DB_FILE *fd, + uint16_t utf16bytes, + unsigned char **utf8, + int* utf8bytes + ) +{ + unsigned long ucs; + int n; + unsigned char utf16buf[256]; + unsigned char* utf16 = utf16buf; + unsigned char* newutf8; + + n = deadbeef->fread(utf16buf, 1, MIN(sizeof(utf16buf), utf16bytes), fd); + utf16bytes -= n; + + while (n > 0) { + /* Check for a surrogate pair */ + if (utf16[1] >= 0xD8 && utf16[1] < 0xE0) { + if (n < 4) { + /* Run out of utf16 bytes, read some more */ + utf16buf[0] = utf16[0]; + utf16buf[1] = utf16[1]; + + n = deadbeef->fread(utf16buf + 2, 1, MIN(sizeof(utf16buf)-2, utf16bytes), fd); + utf16 = utf16buf; + utf16bytes -= n; + n += 2; + } + + if (n < 4) { + /* Truncated utf16 string, abort */ + break; + } + ucs = 0x10000 + ((utf16[0] << 10) | ((utf16[1] - 0xD8) << 18) + | utf16[2] | ((utf16[3] - 0xDC) << 8)); + utf16 += 4; + n -= 4; + } else { + ucs = (utf16[0] | (utf16[1] << 8)); + utf16 += 2; + n -= 2; + } + + if (*utf8bytes > 6) { + newutf8 = utf8encode(ucs, *utf8); + *utf8bytes -= (newutf8 - *utf8); + *utf8 += (newutf8 - *utf8); + } + + /* We have run out of utf16 bytes, read more if available */ + if ((n == 0) && (utf16bytes > 0)) { + n = deadbeef->fread(utf16buf, 1, MIN(sizeof(utf16buf), utf16bytes), fd); + utf16 = utf16buf; + utf16bytes -= n; + } + } + + *utf8[0] = 0; + --*utf8bytes; + + if (utf16bytes > 0) { + /* Skip any remaining bytes */ + deadbeef->fseek(fd, utf16bytes, SEEK_CUR); + } + return; +} + +static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t *it) +{ + asf_object_t current; + asf_object_t header; + uint64_t datalen; + int i; + int fileprop = 0; + uint64_t play_duration; + uint16_t flags; + uint32_t subobjects; + uint8_t utf8buf[512]; + int codectype = 0; + unsigned char id3buffer[2048]; + unsigned char *id3buf = id3buffer; + int id3buf_remaining = sizeof(id3buffer); + + asf_read_object_header((asf_object_t *) &header, fd); + + DEBUGF("header.size=%d\n",(int)header.size); + if (header.size < 30) { + /* invalid size for header object */ + return ASF_ERROR_OBJECT_SIZE; + } + + read_uint32le(fd, &subobjects); + + /* Two reserved bytes - do we need to read them? */ + deadbeef->fseek(fd, 2, SEEK_CUR); + + DEBUGF("Read header - size=%d, subobjects=%d\n",(int)header.size, (int)subobjects); + + if (subobjects > 0) { + header.datalen = header.size - 30; + + /* TODO: Check that we have datalen bytes left in the file */ + datalen = header.datalen; + + for (i=0; i<(int)subobjects; i++) { + DEBUGF("Parsing header object %d - datalen=%d\n",i,(int)datalen); + if (datalen < 24) { + DEBUGF("not enough data for reading object\n"); + break; + } + + asf_read_object_header(¤t, fd); + + if (current.size > datalen || current.size < 24) { + DEBUGF("invalid object size - current.size=%d, datalen=%d\n",(int)current.size,(int)datalen); + break; + } + + if (asf_guid_match(¤t.guid, &asf_guid_file_properties)) { + if (current.size < 104) + return ASF_ERROR_OBJECT_SIZE; + + if (fileprop) { + /* multiple file properties objects not allowed */ + return ASF_ERROR_INVALID_OBJECT; + } + + fileprop = 1; + + /* Get the number of logical packets - uint64_t at offset 32 + * (Big endian byte order) */ + deadbeef->fseek(fd, 32, SEEK_CUR); + read_uint64le(fd, &wfx->numpackets); + read_uint64le(fd, &wfx->play_duration); + read_uint64le(fd, &wfx->send_duration); + read_uint64le(fd, &wfx->preroll); + read_uint32le(fd, &wfx->flags); + +// DEBUGF("****** length = %lld\n", wfx->play_duration); + + /* Read the packet size - uint32_t at offset 68 */ +// deadbeef->fseek(fd, 20, SEEK_CUR); + read_uint32le(fd, &wfx->packet_size); + read_uint32le(fd, &wfx->max_packet_size); + + /* Skip bytes remaining in object */ + deadbeef->fseek(fd, current.size - 24 - 72 - 4, SEEK_CUR); + } else if (asf_guid_match(¤t.guid, &asf_guid_stream_properties)) { + guid_t guid; + uint32_t propdatalen; + + if (current.size < 78) + return ASF_ERROR_OBJECT_SIZE; + +#if 0 + asf_byteio_getGUID(&guid, current->data); + datalen = asf_byteio_getDWLE(current->data + 40); + flags = asf_byteio_getWLE(current->data + 48); +#endif + + asf_readGUID(fd, &guid); + + deadbeef->fseek(fd, 24, SEEK_CUR); + read_uint32le(fd, &propdatalen); + deadbeef->fseek(fd, 4, SEEK_CUR); + read_uint16le(fd, &flags); + + if (!asf_guid_match(&guid, &asf_guid_stream_type_audio)) { + DEBUGF("Found stream properties for non audio stream, skipping\n"); + deadbeef->fseek(fd,current.size - 24 - 50,SEEK_CUR); + } else if (wfx->audiostream == -1) { + deadbeef->fseek(fd, 4, SEEK_CUR); + DEBUGF("Found stream properties for audio stream %d\n",flags&0x7f); + + if (propdatalen < 18) { + return ASF_ERROR_INVALID_LENGTH; + } + +#if 0 + if (asf_byteio_getWLE(data + 16) > datalen - 16) { + return ASF_ERROR_INVALID_LENGTH; + } +#endif + read_uint16le(fd, &wfx->codec_id); + read_uint16le(fd, &wfx->channels); + read_uint32le(fd, &wfx->rate); + read_uint32le(fd, &wfx->bitrate); + wfx->bitrate *= 8; + read_uint16le(fd, &wfx->blockalign); + read_uint16le(fd, &wfx->bitspersample); + read_uint16le(fd, &wfx->datalen); + + if (wfx->codec_id == ASF_CODEC_ID_WMAV1) { + deadbeef->fread(wfx->data, 4, 1, fd); + deadbeef->fseek(fd,current.size - 24 - 72 - 4,SEEK_CUR); + wfx->audiostream = flags&0x7f; + } else if (wfx->codec_id == ASF_CODEC_ID_WMAV2) { + deadbeef->fread(wfx->data, 6, 1, fd); + deadbeef->fseek(fd,current.size - 24 - 72 - 6,SEEK_CUR); + wfx->audiostream = flags&0x7f; + } else if (wfx->codec_id == ASF_CODEC_ID_WMAPRO) { + /* wma pro decoder needs the extra-data */ + deadbeef->fread(wfx->data, wfx->datalen, 1, fd); + deadbeef->fseek(fd,current.size - 24 - 72 - wfx->datalen,SEEK_CUR); + wfx->audiostream = flags&0x7f; + /* Correct codectype to redirect playback to the proper .codec */ + codectype = AFMT_WMAPRO; + } else if (wfx->codec_id == ASF_CODEC_ID_WMAVOICE) { + deadbeef->fread(wfx->data, wfx->datalen, 1, fd); + deadbeef->fseek(fd,current.size - 24 - 72 - wfx->datalen,SEEK_CUR); + wfx->audiostream = flags&0x7f; + codectype = AFMT_WMAVOICE; + } else { + trace("Unsupported WMA codec (Lossless, Voice, etc)\n"); + deadbeef->fseek(fd,current.size - 24 - 72,SEEK_CUR); + } + } + } else if (it && asf_guid_match(¤t.guid, &asf_guid_content_description)) { + /* Object contains five 16-bit string lengths, followed by the five strings: + title, artist, copyright, description, rating + */ + uint16_t strlength[5]; + int i; + + DEBUGF("Found GUID_CONTENT_DESCRIPTION - size=%d\n",(int)(current.size - 24)); + + /* Read the 5 string lengths - number of bytes included trailing zero */ + for (i=0; i<5; i++) { + read_uint16le(fd, &strlength[i]); + DEBUGF("strlength = %u\n",strlength[i]); + } + + if (strlength[0] > 0) { /* 0 - Title */ + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, strlength[0], &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "title", s); + } + + if (strlength[1] > 0) { /* 1 - Artist */ + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, strlength[1], &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "artist", s); + } + + deadbeef->fseek(fd, strlength[2], SEEK_CUR); /* 2 - copyright */ + + if (strlength[3] > 0) { /* 3 - description */ + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, strlength[3], &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "comment", s); + } + + deadbeef->fseek(fd, strlength[4], SEEK_CUR); /* 4 - rating */ + } else if (it && asf_guid_match(¤t.guid, &asf_guid_extended_content_description)) { + uint16_t count; + int i; + int bytesleft = current.size - 24; + DEBUGF("Found GUID_EXTENDED_CONTENT_DESCRIPTION\n"); + + read_uint16le(fd, &count); + bytesleft -= 2; + DEBUGF("extended metadata count = %u\n",count); + + for (i=0; i < count; i++) { + uint16_t length, type; + unsigned char* utf8 = utf8buf; + int utf8length = 512; + + read_uint16le(fd, &length); + asf_utf16LEdecode(fd, length, &utf8, &utf8length); + bytesleft -= 2 + length; + + read_uint16le(fd, &type); + read_uint16le(fd, &length); + trace ("ext md id: %s\n", utf8buf); + + if (!strcmp("WM/TrackNumber",utf8buf)) { + if (type == 0) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "track", s); + } else if ((type >=2) && (type <= 5)) { + int tracknum = asf_intdecode(fd, type, length); + char n[100]; + snprintf (n, sizeof (n), "%d", tracknum); + deadbeef->pl_append_meta (it, "track", n); + } else { + deadbeef->fseek(fd, length, SEEK_CUR); + } + } else if (!strcmp("TotalTracks",utf8buf)) { + if (type == 0) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "numtracks", s); + } else if ((type >=2) && (type <= 5)) { + int tracknum = asf_intdecode(fd, type, length); + char n[100]; + snprintf (n, sizeof (n), "%d", tracknum); + deadbeef->pl_append_meta (it, "numtracks", n); + } else { + deadbeef->fseek(fd, length, SEEK_CUR); + } + } else if (!strcmp("WM/PartOfSet",utf8buf)) { + if (type == 0) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "disc", s); + } else if ((type >=2) && (type <= 5)) { + int tracknum = asf_intdecode(fd, type, length); + char n[100]; + snprintf (n, sizeof (n), "%d", tracknum); + deadbeef->pl_append_meta (it, "disc", n); + } else { + deadbeef->fseek(fd, length, SEEK_CUR); + } + } else if ((!strcmp("WM/Genre", utf8buf)) && (type == 0)) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "genre", s); + } else if ((!strcmp("WM/AlbumTitle", utf8buf)) && (type == 0)) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "album", s); + } else if ((!strcmp("WM/AlbumArtist", utf8buf)) && (type == 0)) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "albumartist", s); + } else if ((!strcmp("WM/Composer", utf8buf)) && (type == 0)) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "composer", s); + } else if (!strcmp("WM/Year", utf8buf)) { + if (type == 0) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "year", s); + } else if ((type >=2) && (type <= 5)) { + int year = asf_intdecode(fd, type, length); + char n[100]; + snprintf (n, sizeof (n), "%d", year); + deadbeef->pl_append_meta (it, "year", n); + } else { + deadbeef->fseek(fd, length, SEEK_CUR); + } + } else if (!strncmp("replaygain_", utf8buf, 11)) { + char *s = utf8buf; + char *value = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + // parse_replaygain(utf8buf, value, id3); + if (!strncasecmp (s, "replaygain_album_gain", 21)) { + deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMGAIN, atof (value)); + } + else if (!strncasecmp (s, "replaygain_album_peak", 21)) { + deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_ALBUMPEAK, atof (value)); + } + else if (!strncasecmp (s, "replaygain_track_gain", 21)) { + deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKGAIN, atof (value)); + } + else if (!strncasecmp (s, "replaygain_track_peak", 21)) { + deadbeef->pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (value)); + } + } else if (!strcmp("MusicBrainz/Track Id", utf8buf)) { + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, "MusicBrainzId", s); +#ifdef HAVE_ALBUMART + } else if (!strcmp("WM/Picture", utf8buf)) { + uint32_t datalength, strlength; + /* Expected is either "01 00 xx xx 03 yy yy yy yy" or + * "03 yy yy yy yy". xx is the size of the WM/Picture + * container in bytes. yy equals the raw data length of + * the embedded image. */ + deadbeef->fseek(fd, -4, SEEK_CUR); + deadbeef->fread(&type, 1, 1, fd); + if (type == 1) { + deadbeef->fseek(fd, 3, SEEK_CUR); + deadbeef->fread(&type, 1, 1, fd); + /* In case the parsing will fail in the next step we + * might at least be able to skip the whole section. */ + datalength = length - 1; + } + if (type == 3) { + /* Read the raw data length of the embedded image. */ + read_uint32le(fd, &datalength); + + /* Reset utf8 buffer */ + utf8 = utf8buf; + utf8length = 512; + + /* Gather the album art format, this string has a + * double zero-termination. */ + asf_utf16LEdecode(fd, 32, &utf8, &utf8length); + strlength = (strlen(utf8buf) + 2) * 2; + deadbeef->fseek(fd, strlength-32, SEEK_CUR); + if (!strcmp("image/jpeg", utf8buf)) { + id3->albumart.type = AA_TYPE_JPG; + } else if (!strcmp("image/jpg", utf8buf)) { + /* image/jpg is technically invalid, + * but it does occur in the wild */ + id3->albumart.type = AA_TYPE_JPG; + } else if (!strcmp("image/png", utf8buf)) { + id3->albumart.type = AA_TYPE_PNG; + } else { + id3->albumart.type = AA_TYPE_UNKNOWN; + } + + /* Set the album art size and position. */ + if (id3->albumart.type != AA_TYPE_UNKNOWN) { + id3->albumart.pos = deadbeef->fseek(fd, 0, SEEK_CUR); + id3->albumart.size = datalength; + id3->has_embedded_albumart = true; + } + } + + deadbeef->fseek(fd, datalength, SEEK_CUR); +#endif + } else { + if (type == 0) { // FIXME: custom fields -- after others work + unsigned char *s = id3buf; + asf_utf16LEdecode(fd, length, &id3buf, &id3buf_remaining); + deadbeef->pl_append_meta (it, utf8buf, s); + } + else { + deadbeef->fseek(fd, length, SEEK_CUR); + } + } + bytesleft -= 4 + length; + } + + deadbeef->fseek(fd, bytesleft, SEEK_CUR); + } else if (asf_guid_match(¤t.guid, &asf_guid_content_encryption) + || asf_guid_match(¤t.guid, &asf_guid_extended_content_encryption)) { + DEBUGF("File is encrypted\n"); + return ASF_ERROR_ENCRYPTED; + } else { + DEBUGF("Skipping %d bytes of object\n",(int)(current.size - 24)); + deadbeef->fseek(fd,current.size - 24,SEEK_CUR); + } + + DEBUGF("Parsed object - size = %d\n",(int)current.size); + datalen -= current.size; + } + + if (i != (int)subobjects || datalen != 0) { + DEBUGF("header data doesn't match given subobject count\n"); + return ASF_ERROR_INVALID_VALUE; + } + + DEBUGF("%d subobjects read successfully\n", i); + } + +#if 0 + tmp = asf_parse_header_validate(file, &header); + if (tmp < 0) { + /* header read ok but doesn't validate correctly */ + return tmp; + } +#endif + + DEBUGF("header validated correctly\n"); + + return 0; +} + +int get_asf_metadata(DB_FILE *fd, DB_playItem_t *it, asf_waveformatex_t *wfx, int64_t *first_frame_offset) +{ + int res; + asf_object_t obj; + + wfx->audiostream = -1; + + res = asf_parse_header(fd, wfx, it); + + if (res < 0) { + DEBUGF("ASF: parsing error - %d\n",res); + return 0; + } + + if (wfx->audiostream == -1) { + DEBUGF("ASF: No WMA streams found\n"); + return 0; + } + + asf_read_object_header(&obj, fd); + + if (!asf_guid_match(&obj.guid, &asf_guid_data)) { + DEBUGF("ASF: No data object found\n"); + return 0; + } + + /* Store the current file position - no need to parse the header + again in the codec. The +26 skips the rest of the data object + header. + */ + *first_frame_offset = deadbeef->ftell(fd) + 26; + + return 1; +} diff --git a/plugins/wma/libasf/asf.c b/plugins/wma/libasf/asf.c new file mode 100644 index 00000000..fd71a2b5 --- /dev/null +++ b/plugins/wma/libasf/asf.c @@ -0,0 +1,456 @@ +// this file is a modified version for deadbeef player +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * ASF parsing code based on libasf by Juho Vähä-Herttua + * http://code.google.com/p/libasf/ libasf itself was based on the ASF + * parser in VLC - http://www.videolan.org/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include <inttypes.h> +#include <stdlib.h> +#include <string.h> +#include "asf.h" +#include "../../deadbeef.h" +extern DB_functions_t *deadbeef; +#define trace(...) { fprintf (stderr, __VA_ARGS__); } +//#define trace(fmt,...) +#define DEBUGF trace + +/* Read an unaligned 32-bit little endian long from buffer. */ +static unsigned long get_long_le(void* buf) +{ + unsigned char* p = (unsigned char*) buf; + + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +/* Read an unaligned 16-bit little endian short from buffer. */ +static unsigned short get_short_le(void* buf) +{ + unsigned char* p = (unsigned char*) buf; + + return p[0] | (p[1] << 8); +} + +#define GETLEN2b(bits) (((bits) == 0x03) ? 4 : bits) + +#define GETVALUE2b(bits, data) \ + (((bits) != 0x03) ? ((bits) != 0x02) ? ((bits) != 0x01) ? \ + 0 : *(data) : get_short_le(data) : get_long_le(data)) + +int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlength, + asf_waveformatex_t* wfx, DB_FILE *fp) +{ + uint8_t *audiobuf_mem = *audiobuf; + uint8_t tmp8, packet_flags, packet_property; + int stream_id; + int ec_length, opaque_data, ec_length_type; + int datalen; + uint8_t data[18]; + uint8_t* datap; + uint32_t length; + uint32_t padding_length; + /* rockbox: comment 'set but unused' variables + uint32_t send_time; + uint16_t duration; + uint32_t media_object_number; + uint32_t media_object_offset; + */ + uint16_t payload_count; + int payload_length_type; + uint32_t payload_hdrlen; + int payload_datalen; + int multiple; + uint32_t replicated_length; + uint32_t bytesread = 0; + uint8_t* buf; + size_t bufsize; + int i; + /*DEBUGF("Reading new packet at %d bytes ", (int)ci->curpos);*/ + + if (deadbeef->fread (&tmp8, 1, 1, fp) == 0) { + return ASF_ERROR_EOF; + } + bytesread++; + + /* TODO: We need a better way to detect endofstream */ + if (tmp8 != 0x82) { + DEBUGF("Read failed: packet did not sync\n"); + return -1; + } + + + if (tmp8 & 0x80) { + ec_length = tmp8 & 0x0f; + opaque_data = (tmp8 >> 4) & 0x01; + ec_length_type = (tmp8 >> 5) & 0x03; + + if (ec_length_type != 0x00 || opaque_data != 0 || ec_length != 0x02) { + DEBUGF("incorrect error correction flags\n"); + return ASF_ERROR_INVALID_VALUE; + } + + /* Skip ec_data */ + deadbeef->fseek(fp, ec_length, SEEK_CUR); + bytesread += ec_length; + } else { + ec_length = 0; + } + + if (deadbeef->fread(&packet_flags, 1, 1, fp) == 0) { return ASF_ERROR_EOF; } + if (deadbeef->fread(&packet_property, 1, 1, fp) == 0) { return ASF_ERROR_EOF; } + bytesread += 2; + + datalen = GETLEN2b((packet_flags >> 1) & 0x03) + + GETLEN2b((packet_flags >> 3) & 0x03) + + GETLEN2b((packet_flags >> 5) & 0x03) + 6; + +#if 0 + if (datalen > sizeof(data)) { + DEBUGF("Unexpectedly long datalen in data - %d\n",datalen); + return ASF_ERROR_OUTOFMEM; + } +#endif + + if (deadbeef->fread (data, datalen, 1, fp) == 0) { + return ASF_ERROR_EOF; + } + + bytesread += datalen; + + datap = data; + length = GETVALUE2b((packet_flags >> 5) & 0x03, datap); + datap += GETLEN2b((packet_flags >> 5) & 0x03); + /* sequence value is not used */ + GETVALUE2b((packet_flags >> 1) & 0x03, datap); + datap += GETLEN2b((packet_flags >> 1) & 0x03); + padding_length = GETVALUE2b((packet_flags >> 3) & 0x03, datap); + datap += GETLEN2b((packet_flags >> 3) & 0x03); + /* send_time = get_long_le(datap); */ + datap += 4; + /* duration = get_short_le(datap); */ + datap += 2; + /*DEBUGF("and duration %d ms\n", duration);*/ + + /* this is really idiotic, packet length can (and often will) be + * undefined and we just have to use the header packet size as the size + * value */ + if (!((packet_flags >> 5) & 0x03)) { + length = wfx->packet_size; + } + + /* this is also really idiotic, if packet length is smaller than packet + * size, we need to manually add the additional bytes into padding length + */ + if (length < wfx->packet_size) { + padding_length += wfx->packet_size - length; + length = wfx->packet_size; + } + + if (length > wfx->packet_size) { + DEBUGF("packet with too big length value\n"); + return ASF_ERROR_INVALID_LENGTH; + } + + /* check if we have multiple payloads */ + if (packet_flags & 0x01) { + if (deadbeef->fread(&tmp8, 1, 1, fp) == 0) { + return ASF_ERROR_EOF; + } + payload_count = tmp8 & 0x3f; + payload_length_type = (tmp8 >> 6) & 0x03; + bytesread++; + } else { + payload_count = 1; + payload_length_type = 0x02; /* not used */ + } + + if (length < bytesread) { + DEBUGF("header exceeded packet size, invalid file - length=%d, bytesread=%d\n",(int)length,(int)bytesread); + /* FIXME: should this be checked earlier? */ + return ASF_ERROR_INVALID_LENGTH; + } + + + /* We now parse the individual payloads, and move all payloads + belonging to our audio stream to a contiguous block, starting at + the location of the first payload. + */ + + *audiobuf = NULL; + *audiobufsize = 0; + *packetlength = length - bytesread; + + buf = audiobuf_mem; + int64_t ret = deadbeef->fread (buf, 1, length-bytesread, fp); +#define MIN(x,y) ((x)<(y)) ? (x) : (y) + if (ret >= 0) { + bufsize = MIN((size_t)ret, length); + } + else { + bufsize = 0; + } + if (bufsize == 0) { + buf = NULL; + } + + bufsize = length; + datap = buf; + +#define ASF_MAX_REQUEST (1L<<15) /* 32KB */ + if (bufsize != length && length >= ASF_MAX_REQUEST) { + /* This should only happen with packets larger than 32KB (the + guard buffer size). All the streams I've seen have + relatively small packets less than about 8KB), but I don't + know what is expected. + */ + DEBUGF("Could not read packet (requested %d bytes, received %d), curpos=%d, aborting\n", + (int)length,(int)bufsize,(int)deadbeef->ftell(fp)); + return -1; + } + + for (i=0; i<payload_count; i++) { + stream_id = datap[0]&0x7f; + datap++; + bytesread++; + + payload_hdrlen = GETLEN2b(packet_property & 0x03) + + GETLEN2b((packet_property >> 2) & 0x03) + + GETLEN2b((packet_property >> 4) & 0x03); + + //DEBUGF("payload_hdrlen = %d\n",payload_hdrlen); +#if 0 + /* TODO */ + if (payload_hdrlen > size) { + return ASF_ERROR_INVALID_LENGTH; + } +#endif + if (payload_hdrlen > sizeof(data)) { + DEBUGF("Unexpectedly long datalen in data - %d\n",datalen); + return ASF_ERROR_OUTOFMEM; + } + + bytesread += payload_hdrlen; + /* media_object_number = GETVALUE2b((packet_property >> 4) & 0x03, datap); */ + datap += GETLEN2b((packet_property >> 4) & 0x03); + /* media_object_offset = GETVALUE2b((packet_property >> 2) & 0x03, datap); */ + datap += GETLEN2b((packet_property >> 2) & 0x03); + replicated_length = GETVALUE2b(packet_property & 0x03, datap); + datap += GETLEN2b(packet_property & 0x03); + + /* TODO: Validate replicated_length */ + /* TODO: Is the content of this important for us? */ + datap += replicated_length; + bytesread += replicated_length; + + multiple = packet_flags & 0x01; + + + if (multiple) { + int x; + + x = GETLEN2b(payload_length_type); + + if (x != 2) { + /* in multiple payloads datalen should be a word */ + return ASF_ERROR_INVALID_VALUE; + } + +#if 0 + if (skip + tmp > datalen) { + /* not enough data */ + return ASF_ERROR_INVALID_LENGTH; + } +#endif + payload_datalen = GETVALUE2b(payload_length_type, datap); + datap += x; + bytesread += x; + } else { + payload_datalen = length - bytesread - padding_length; + } + + if (replicated_length==1) + datap++; + + if (stream_id == wfx->audiostream) + { + if (*audiobuf == NULL) { + /* The first payload can stay where it is */ + *audiobuf = datap; + *audiobufsize = payload_datalen; + } else { + /* The second and subsequent payloads in this packet + that belong to the audio stream need to be moved to be + contiguous with the first payload. + */ + memmove(*audiobuf + *audiobufsize, datap, payload_datalen); + *audiobufsize += payload_datalen; + } + } + datap += payload_datalen; + bytesread += payload_datalen; + } + + if (*audiobuf != NULL) + return 1; + else + return 0; +} + + +int asf_get_timestamp(int *duration, DB_FILE *fp) +{ + uint8_t tmp8, packet_flags, packet_property; + int ec_length, opaque_data, ec_length_type; + int datalen; + uint8_t data[18]; + uint8_t* datap; + /* rockbox: comment 'set but unused' variables + uint32_t length; + uint32_t padding_length; + */ + uint32_t send_time; + static int packet_count = 0; + + uint32_t bytesread = 0; + packet_count++; + if (deadbeef->fread(&tmp8, 1, 1, fp) == 0) { + DEBUGF("ASF ERROR (EOF?)\n"); + return ASF_ERROR_EOF; + } + bytesread++; + + /* TODO: We need a better way to detect endofstream */ + if (tmp8 != 0x82) { + DEBUGF("Get timestamp: Detected end of stream\n"); + return ASF_ERROR_EOF; + } + + + if (tmp8 & 0x80) { + ec_length = tmp8 & 0x0f; + opaque_data = (tmp8 >> 4) & 0x01; + ec_length_type = (tmp8 >> 5) & 0x03; + + if (ec_length_type != 0x00 || opaque_data != 0 || ec_length != 0x02) { + DEBUGF("incorrect error correction flags\n"); + return ASF_ERROR_INVALID_VALUE; + } + + /* Skip ec_data */ + deadbeef->fseek (fp, ec_length, SEEK_CUR); + bytesread += ec_length; + } else { + ec_length = 0; + } + + if (deadbeef->fread(&packet_flags, 1, 1, fp) == 0) { + DEBUGF("Detected end of stream 2\n"); + return ASF_ERROR_EOF; + } + + if (deadbeef->fread(&packet_property, 1, 1, fp) == 0) { + DEBUGF("Detected end of stream3\n"); + return ASF_ERROR_EOF; + } + bytesread += 2; + + datalen = GETLEN2b((packet_flags >> 1) & 0x03) + + GETLEN2b((packet_flags >> 3) & 0x03) + + GETLEN2b((packet_flags >> 5) & 0x03) + 6; + + if (deadbeef->fread(data, datalen, 1, fp) == 0) { + DEBUGF("Detected end of stream4\n"); + return ASF_ERROR_EOF; + } + + bytesread += datalen; + + datap = data; + /* length = GETVALUE2b((packet_flags >> 5) & 0x03, datap); */ + datap += GETLEN2b((packet_flags >> 5) & 0x03); + + /* sequence value is not used */ + GETVALUE2b((packet_flags >> 1) & 0x03, datap); + datap += GETLEN2b((packet_flags >> 1) & 0x03); + /* padding_length = GETVALUE2b((packet_flags >> 3) & 0x03, datap); */ + datap += GETLEN2b((packet_flags >> 3) & 0x03); + send_time = get_long_le(datap); + datap += 4; + *duration = get_short_le(datap); + + /*the asf_get_timestamp function advances us 12-13 bytes past the packet start, + need to undo this here so that we stay synced with the packet*/ + deadbeef->fseek(fp, -bytesread, SEEK_CUR); + + return send_time; +} + +/*entry point for seeks*/ +int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_offset) +{ + int time, duration, delta, temp, count=0; + + /*estimate packet number from bitrate*/ + int initial_packet = deadbeef->ftell (fp)/wfx->packet_size; + int packet_num = (((int64_t)ms)*(wfx->bitrate>>3))/wfx->packet_size/1000; + int last_packet = deadbeef->fgetlength (fp) / wfx->packet_size; + + if (packet_num > last_packet) { + packet_num = last_packet; + } + + /*calculate byte address of the start of that packet*/ + int packet_offset = packet_num*wfx->packet_size; + + /*seek to estimated packet*/ + deadbeef->fseek (fp, first_frame_offset+packet_offset, SEEK_SET); + temp = ms; + while (1) + { + /*for very large files it can be difficult and unimportant to find the exact packet*/ + count++; + + /*check the time stamp of our packet*/ + time = asf_get_timestamp(&duration, fp); + DEBUGF("seeked to %d ms with duration %d\n", time, duration); + + if (time < 0) { + /*unknown error, try to recover*/ + DEBUGF("UKNOWN SEEK ERROR\n"); + deadbeef->fseek (fp, first_frame_offset+initial_packet*wfx->packet_size, SEEK_SET); + /*seek failed so return time stamp of the initial packet*/ + return asf_get_timestamp(&duration, fp); + } + + if ((time+duration>=ms && time<=ms) || count > 10) { + /*DEBUGF("Found our packet! Now at %d packet\n", packet_num);*/ + return time; + } else { + /*seek again*/ + delta = ms-time; + /*estimate new packet number from bitrate and our current position*/ + temp += delta; + packet_num = ((temp/1000)*(wfx->bitrate>>3) - (wfx->packet_size>>1))/wfx->packet_size; //round down! + packet_offset = packet_num*wfx->packet_size; + deadbeef->fseek (fp, first_frame_offset+packet_offset, SEEK_SET); + } + } +} diff --git a/plugins/wma/libasf/asf.h b/plugins/wma/libasf/asf.h new file mode 100644 index 00000000..cb96fed2 --- /dev/null +++ b/plugins/wma/libasf/asf.h @@ -0,0 +1,54 @@ +#ifndef _ASF_H +#define _ASF_H + +#include <inttypes.h> +#include "../../deadbeef.h" + +/* ASF codec IDs */ +#define ASF_CODEC_ID_WMAV1 0x160 +#define ASF_CODEC_ID_WMAV2 0x161 +#define ASF_CODEC_ID_WMAPRO 0x162 +#define ASF_CODEC_ID_WMAVOICE 0x00A + +enum asf_error_e { + ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ + ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */ + ASF_ERROR_EOF = -3, /* unexpected end of file */ + ASF_ERROR_IO = -4, /* error reading or writing to file */ + ASF_ERROR_INVALID_LENGTH = -5, /* length value conflict in input data */ + ASF_ERROR_INVALID_VALUE = -6, /* other value conflict in input data */ + ASF_ERROR_INVALID_OBJECT = -7, /* ASF object missing or in wrong place */ + ASF_ERROR_OBJECT_SIZE = -8, /* invalid ASF object size (too small) */ + ASF_ERROR_SEEKABLE = -9, /* file not seekable */ + ASF_ERROR_SEEK = -10, /* file is seekable but seeking failed */ + ASF_ERROR_ENCRYPTED = -11 /* file is encrypted */ +}; + +struct asf_waveformatex_s { + uint32_t packet_size; + uint32_t max_packet_size; + int audiostream; + uint16_t codec_id; + uint16_t channels; + uint32_t rate; + uint32_t bitrate; + uint16_t blockalign; + uint16_t bitspersample; + uint16_t datalen; + uint64_t numpackets; + uint8_t data[46]; + uint64_t play_duration; + uint64_t send_duration; + uint64_t preroll; + uint32_t flags; +}; +typedef struct asf_waveformatex_s asf_waveformatex_t; + +int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlength, + asf_waveformatex_t* wfx, DB_FILE *fp); + +int asf_get_timestamp(int *duration, DB_FILE *fp); + +int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_offset); + +#endif /* _ASF_H */ diff --git a/plugins/wma/libwma/asm_arm.h b/plugins/wma/libwma/asm_arm.h new file mode 100644 index 00000000..8e5d0e68 --- /dev/null +++ b/plugins/wma/libwma/asm_arm.h @@ -0,0 +1,292 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: arm7 and later wide math functions + + ********************************************************************/ +#ifdef CPU_ARM + +#define INCL_OPTIMIZED_MULT32 +#if ARM_ARCH >= 6 +static inline int32_t MULT32(int32_t x, int32_t y) { + int32_t hi; + asm volatile("smmul %[hi], %[x], %[y] \n\t" + : [hi] "=&r" (hi) + : [x] "r" (x), [y] "r" (y) ); + return(hi); +} +#else +static inline int32_t MULT32(int32_t x, int32_t y) { + int32_t lo, hi; + asm volatile("smull\t%0, %1, %2, %3 \n\t" + : "=&r"(lo),"=&r"(hi) + : "r"(x),"r"(y) ); + return(hi); +} +#endif + +#define INCL_OPTIMIZED_MULT31 +static inline int32_t MULT31(int32_t x, int32_t y) { + return MULT32(x,y)<<1; +} + +#define INCL_OPTIMIZED_MULT31_SHIFT15 +static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) { + int32_t lo,hi; + asm volatile("smull %0, %1, %2, %3\n\t" + "movs %0, %0, lsr #15\n\t" + "adc %1, %0, %1, lsl #17\n\t" + : "=&r"(lo),"=&r"(hi) + : "r"(x),"r"(y) + : "cc" ); + return(hi); +} + +#define INCL_OPTIMIZED_MULT31_SHIFT16 +static inline int32_t MULT31_SHIFT16(int32_t x, int32_t y) { + int32_t lo,hi; + asm volatile("smull %0, %1, %2, %3\n\t" + "movs %0, %0, lsr #16\n\t" + "adc %1, %0, %1, lsl #16\n\t" + : "=&r"(lo),"=&r"(hi) + : "r"(x),"r"(y) + : "cc" ); + return(hi); +} + +#define INCL_OPTIMIZED_XPROD32 +#define XPROD32(a, b, t, v, x, y) \ +{ \ + int32_t l; \ + asm("smull %0, %1, %3, %5\n\t" \ + "rsb %2, %6, #0\n\t" \ + "smlal %0, %1, %4, %6\n\t" \ + "smull %0, %2, %3, %2\n\t" \ + "smlal %0, %2, %4, %5" \ + : "=&r" (l), "=&r" (x), "=&r" (y) \ + : "r" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) ); \ +} + +#define INCL_OPTIMIZED_XPROD31_R +#define INCL_OPTIMIZED_XNPROD31_R +#if ARM_ARCH >= 6 +/* These may yield slightly different result from the macros below + because only the high 32 bits of the multiplications are accumulated while + the below macros use a 64 bit accumulator that is truncated to 32 bits.*/ +#define XPROD31_R(_a, _b, _t, _v, _x, _y)\ +{\ + int32_t x1, y1;\ + asm("smmul %[x1], %[t], %[a] \n\t"\ + "smmul %[y1], %[t], %[b] \n\t"\ + "smmla %[x1], %[v], %[b], %[x1] \n\t"\ + "smmls %[y1], %[v], %[a], %[y1] \n\t"\ + : [x1] "=&r" (x1), [y1] "=&r" (y1)\ + : [a] "r" (_a), [b] "r" (_b), [t] "r" (_t), [v] "r" (_v) );\ + _x = x1 << 1;\ + _y = y1 << 1;\ +} + +#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\ +{\ + int32_t x1, y1;\ + asm("smmul %[x1], %[t], %[a] \n\t"\ + "smmul %[y1], %[t], %[b] \n\t"\ + "smmls %[x1], %[v], %[b], %[x1] \n\t"\ + "smmla %[y1], %[v], %[a], %[y1] \n\t"\ + : [x1] "=&r" (x1), [y1] "=&r" (y1)\ + : [a] "r" (_a), [b] "r" (_b), [t] "r" (_t), [v] "r" (_v) );\ + _x = x1 << 1;\ + _y = y1 << 1;\ +} +#else +#define XPROD31_R(_a, _b, _t, _v, _x, _y)\ +{\ + int32_t x1, y1, l;\ + asm("smull %0, %1, %5, %3\n\t"\ + "rsb %2, %3, #0\n\t"\ + "smlal %0, %1, %6, %4\n\t"\ + "smull %0, %2, %6, %2\n\t"\ + "smlal %0, %2, %5, %4"\ + : "=&r" (l), "=&r" (x1), "=&r" (y1)\ + : "r" (_a), "r" (_b), "r" (_t), "r" (_v) );\ + _x = x1 << 1;\ + _y = y1 << 1;\ +} + +#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\ +{\ + int32_t x1, y1, l;\ + asm("smull %0, %1, %5, %3\n\t"\ + "rsb %2, %4, #0\n\t"\ + "smlal %0, %1, %6, %2\n\t"\ + "smull %0, %2, %5, %4\n\t"\ + "smlal %0, %2, %6, %3"\ + : "=&r" (l), "=&r" (x1), "=&r" (y1)\ + : "r" (_a), "r" (_b), "r" (_t), "r" (_v) );\ + _x = x1 << 1;\ + _y = y1 << 1;\ +} +#endif + +#define INCL_OPTIMIZED_XPROD31 +static inline void XPROD31(int32_t a, int32_t b, + int32_t t, int32_t v, + int32_t *x, int32_t *y) +{ + int32_t _x1, _y1; + XPROD31_R(a, b, t, v, _x1, _y1); + *x = _x1; + *y = _y1; +} + +#define INCL_OPTIMIZED_XNPROD31 +static inline void XNPROD31(int32_t a, int32_t b, + int32_t t, int32_t v, + int32_t *x, int32_t *y) +{ + int32_t _x1, _y1; + XNPROD31_R(a, b, t, v, _x1, _y1); + *x = _x1; + *y = _y1; +} + + +#ifndef _V_VECT_OPS +#define _V_VECT_OPS + +/* asm versions of vector operations for block.c, window.c */ +static inline +void vect_add(int32_t *x, const int32_t *y, int n) +{ + while (n>=4) { + asm volatile ("ldmia %[x], {r0, r1, r2, r3};" + "ldmia %[y]!, {r4, r5, r6, r7};" + "add r0, r0, r4;" + "add r1, r1, r5;" + "add r2, r2, r6;" + "add r3, r3, r7;" + "stmia %[x]!, {r0, r1, r2, r3};" + : [x] "+r" (x), [y] "+r" (y) + : : "r0", "r1", "r2", "r3", + "r4", "r5", "r6", "r7", + "memory"); + n -= 4; + } + /* add final elements */ + while (n>0) { + *x++ += *y++; + n--; + } +} + +static inline +void vect_copy(int32_t *x, const int32_t *y, int n) +{ + while (n>=4) { + asm volatile ("ldmia %[y]!, {r0, r1, r2, r3};" + "stmia %[x]!, {r0, r1, r2, r3};" + : [x] "+r" (x), [y] "+r" (y) + : : "r0", "r1", "r2", "r3", + "memory"); + n -= 4; + } + /* copy final elements */ + while (n>0) { + *x++ = *y++; + n--; + } +} + +static inline +void vect_mult_fw(int32_t *data, const int32_t *window, int n) +{ + while (n>=4) { + asm volatile ("ldmia %[d], {r0, r1, r2, r3};" + "ldmia %[w]!, {r4, r5, r6, r7};" + "smull r8, r9, r0, r4;" + "mov r0, r9, lsl #1;" + "smull r8, r9, r1, r5;" + "mov r1, r9, lsl #1;" + "smull r8, r9, r2, r6;" + "mov r2, r9, lsl #1;" + "smull r8, r9, r3, r7;" + "mov r3, r9, lsl #1;" + "stmia %[d]!, {r0, r1, r2, r3};" + : [d] "+r" (data), [w] "+r" (window) + : : "r0", "r1", "r2", "r3", + "r4", "r5", "r6", "r7", "r8", "r9", + "memory" ); + n -= 4; + } + while(n>0) { + *data = MULT31(*data, *window); + data++; + window++; + n--; + } +} + +static inline +void vect_mult_bw(int32_t *data, const int32_t *window, int n) +{ + while (n>=4) { + asm volatile ("ldmia %[d], {r0, r1, r2, r3};" + "ldmda %[w]!, {r4, r5, r6, r7};" + "smull r8, r9, r0, r7;" + "mov r0, r9, lsl #1;" + "smull r8, r9, r1, r6;" + "mov r1, r9, lsl #1;" + "smull r8, r9, r2, r5;" + "mov r2, r9, lsl #1;" + "smull r8, r9, r3, r4;" + "mov r3, r9, lsl #1;" + "stmia %[d]!, {r0, r1, r2, r3};" + : [d] "+r" (data), [w] "+r" (window) + : : "r0", "r1", "r2", "r3", + "r4", "r5", "r6", "r7", "r8", "r9", + "memory" ); + n -= 4; + } + while(n>0) { + *data = MULT31(*data, *window); + data++; + window--; + n--; + } +} + +#endif + +/* not used anymore */ +/* +#ifndef _V_CLIP_MATH +#define _V_CLIP_MATH + +static inline int32_t CLIP_TO_15(int32_t x) { + int tmp; + asm volatile("subs %1, %0, #32768\n\t" + "movpl %0, #0x7f00\n\t" + "orrpl %0, %0, #0xff\n" + "adds %1, %0, #32768\n\t" + "movmi %0, #0x8000" + : "+r"(x),"=r"(tmp) + : + : "cc"); + return(x); +} + +#endif +*/ + +#endif + diff --git a/plugins/wma/libwma/codeclib_misc.h b/plugins/wma/libwma/codeclib_misc.h new file mode 100644 index 00000000..bc82b9c3 --- /dev/null +++ b/plugins/wma/libwma/codeclib_misc.h @@ -0,0 +1,319 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: miscellaneous math and prototypes + + ********************************************************************/ + +#ifndef _CODECLIB_MISC_H_ +#define _CODECLIB_MISC_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdint.h> +#include "asm_arm.h" + +#ifndef _LOW_ACCURACY_ +/* 64 bit multiply */ + +#if WORDS_BIGENDIAN +#define ROCKBOX_BIG_ENDIAN 1 +#else +#define ROCKBOX_LITTLE_ENDIAN 1 +#endif + +#ifdef ROCKBOX_LITTLE_ENDIAN +union magic { + struct { + int32_t lo; + int32_t hi; + } halves; + int64_t whole; +}; +#elif defined(ROCKBOX_BIG_ENDIAN) +union magic { + struct { + int32_t hi; + int32_t lo; + } halves; + int64_t whole; +}; +#endif + +#ifndef INCL_OPTIMIZED_MULT32 +#define INCL_OPTIMIZED_MULT32 +static inline int32_t MULT32(int32_t x, int32_t y) { + union magic magic; + magic.whole = (int64_t)x * y; + return magic.halves.hi; +} +#endif + +#ifndef INCL_OPTIMIZED_MULT31 +#define INCL_OPTIMIZED_MULT31 +static inline int32_t MULT31(int32_t x, int32_t y) { + return MULT32(x,y)<<1; +} +#endif + +#ifndef INCL_OPTIMIZED_MULT31_SHIFT15 +#define INCL_OPTIMIZED_MULT31_SHIFT15 +static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) { + union magic magic; + magic.whole = (int64_t)x * y; + return ((uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17); +} +#endif + +#ifndef INCL_OPTIMIZED_MULT31_SHIFT16 +#define INCL_OPTIMIZED_MULT31_SHIFT16 +static inline int32_t MULT31_SHIFT16(int32_t x, int32_t y) { + union magic magic; + magic.whole = (int64_t)x * y; + return ((uint32_t)(magic.halves.lo)>>16) | ((magic.halves.hi)<<16); +} +#endif + +#else +/* Rockbox: unused */ +#if 0 +/* 32 bit multiply, more portable but less accurate */ + +/* + * Note: Precision is biased towards the first argument therefore ordering + * is important. Shift values were chosen for the best sound quality after + * many listening tests. + */ + +/* + * For MULT32 and MULT31: The second argument is always a lookup table + * value already preshifted from 31 to 8 bits. We therefore take the + * opportunity to save on text space and use unsigned char for those + * tables in this case. + */ + +static inline int32_t MULT32(int32_t x, int32_t y) { + return (x >> 9) * y; /* y preshifted >>23 */ +} + +static inline int32_t MULT31(int32_t x, int32_t y) { + return (x >> 8) * y; /* y preshifted >>23 */ +} + +static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) { + return (x >> 6) * y; /* y preshifted >>9 */ +} +#endif +#endif + +/* + * The XPROD functions are meant to optimize the cross products found all + * over the place in mdct.c by forcing memory operation ordering to avoid + * unnecessary register reloads as soon as memory is being written to. + * However this is only beneficial on CPUs with a sane number of general + * purpose registers which exclude the Intel x86. On Intel, better let the + * compiler actually reload registers directly from original memory by using + * macros. + */ + +#ifndef INCL_OPTIMIZED_XPROD32 +#define INCL_OPTIMIZED_XPROD32 +/* replaced XPROD32 with a macro to avoid memory reference + _x, _y are the results (must be l-values) */ +#define XPROD32(_a, _b, _t, _v, _x, _y) \ + { (_x)=MULT32(_a,_t)+MULT32(_b,_v); \ + (_y)=MULT32(_b,_t)-MULT32(_a,_v); } +#endif + +/* Rockbox: Unused */ +/* +#ifdef __i386__ + +#define XPROD31(_a, _b, _t, _v, _x, _y) \ + { *(_x)=MULT31(_a,_t)+MULT31(_b,_v); \ + *(_y)=MULT31(_b,_t)-MULT31(_a,_v); } +#define XNPROD31(_a, _b, _t, _v, _x, _y) \ + { *(_x)=MULT31(_a,_t)-MULT31(_b,_v); \ + *(_y)=MULT31(_b,_t)+MULT31(_a,_v); } + +#else +*/ + +#ifndef INCL_OPTIMIZED_XPROD31 +#define INCL_OPTIMIZED_XPROD31 +static inline void XPROD31(int32_t a, int32_t b, + int32_t t, int32_t v, + int32_t *x, int32_t *y) +{ + *x = MULT31(a, t) + MULT31(b, v); + *y = MULT31(b, t) - MULT31(a, v); +} +#endif + +#ifndef INCL_OPTIMIZED_XNPROD31 +#define INCL_OPTIMIZED_XNPROD31 +static inline void XNPROD31(int32_t a, int32_t b, + int32_t t, int32_t v, + int32_t *x, int32_t *y) +{ + *x = MULT31(a, t) - MULT31(b, v); + *y = MULT31(b, t) + MULT31(a, v); +} +#endif +/*#endif*/ + +#ifndef INCL_OPTIMIZED_XPROD31_R +#define INCL_OPTIMIZED_XPROD31_R +#define XPROD31_R(_a, _b, _t, _v, _x, _y)\ +{\ + _x = MULT31(_a, _t) + MULT31(_b, _v);\ + _y = MULT31(_b, _t) - MULT31(_a, _v);\ +} +#endif + +#ifndef INCL_OPTIMIZED_XNPROD31_R +#define INCL_OPTIMIZED_XNPROD31_R +#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\ +{\ + _x = MULT31(_a, _t) - MULT31(_b, _v);\ + _y = MULT31(_b, _t) + MULT31(_a, _v);\ +} +#endif + +#ifndef _V_VECT_OPS +#define _V_VECT_OPS + +static inline +void vect_add(int32_t *x, const int32_t *y, int n) +{ + while (n>0) { + *x++ += *y++; + n--; + } +} + +static inline +void vect_copy(int32_t *x, const int32_t *y, int n) +{ + while (n>0) { + *x++ = *y++; + n--; + } +} + +static inline +void vect_mult_fw(int32_t *data, const int32_t *window, int n) +{ + while(n>0) { + *data = MULT31(*data, *window); + data++; + window++; + n--; + } +} + +static inline +void vect_mult_bw(int32_t *data, const int32_t *window, int n) +{ + while(n>0) { + *data = MULT31(*data, *window); + data++; + window--; + n--; + } +} +#endif + +/* not used anymore */ +/* +#ifndef _V_CLIP_MATH +#define _V_CLIP_MATH + +static inline int32_t CLIP_TO_15(int32_t x) { + int ret=x; + ret-= ((x<=32767)-1)&(x-32767); + ret-= ((x>=-32768)-1)&(x+32768); + return(ret); +} + +#endif +*/ +static inline int32_t VFLOAT_MULT(int32_t a,int32_t ap, + int32_t b,int32_t bp, + int32_t *p){ + if(a && b){ +#ifndef _LOW_ACCURACY_ + *p=ap+bp+32; + return MULT32(a,b); +#else + *p=ap+bp+31; + return (a>>15)*(b>>16); +#endif + }else + return 0; +} + +/*static inline int32_t VFLOAT_MULTI(int32_t a,int32_t ap, + int32_t i, + int32_t *p){ + + int ip=_ilog(abs(i))-31; + return VFLOAT_MULT(a,ap,i<<-ip,ip,p); +} +*/ +static inline int32_t VFLOAT_ADD(int32_t a,int32_t ap, + int32_t b,int32_t bp, + int32_t *p){ + + if(!a){ + *p=bp; + return b; + }else if(!b){ + *p=ap; + return a; + } + + /* yes, this can leak a bit. */ + if(ap>bp){ + int shift=ap-bp+1; + *p=ap+1; + a>>=1; + if(shift<32){ + b=(b+(1<<(shift-1)))>>shift; + }else{ + b=0; + } + }else{ + int shift=bp-ap+1; + *p=bp+1; + b>>=1; + if(shift<32){ + a=(a+(1<<(shift-1)))>>shift; + }else{ + a=0; + } + } + + a+=b; + if((a&0xc0000000)==0xc0000000 || + (a&0xc0000000)==0){ + a<<=1; + (*p)--; + } + return(a); +} + +#endif + diff --git a/plugins/wma/libwma/ffmpeg_bitstream.c b/plugins/wma/libwma/ffmpeg_bitstream.c new file mode 100644 index 00000000..9adf9a45 --- /dev/null +++ b/plugins/wma/libwma/ffmpeg_bitstream.c @@ -0,0 +1,356 @@ +/* + * Common bit i/o utils + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2010 Loren Merritt + * + * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bitstream api. + */ + +//#include "avcodec.h" +#include "ffmpeg_get_bits.h" +#include "ffmpeg_intreadwrite.h" + +#define av_log(...) + +#ifdef ROCKBOX +#undef DEBUGF +#define DEBUGF(...) +#endif +#define trace(...) { fprintf (stderr, __VA_ARGS__); } +//#define trace(fmt,...) +#define DEBUGF trace + +const uint8_t ff_log2_run[32]={ + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9,10,11,12,13,14,15 +}; + +#if 0 // unused in rockbox +void align_put_bits(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + put_bits(s,( - s->index) & 7,0); +#else + put_bits(s,s->bit_left & 7,0); +#endif +} + +void ff_put_string(PutBitContext *pb, const char *string, int terminate_string) +{ + while(*string){ + put_bits(pb, 8, *string); + string++; + } + if(terminate_string) + put_bits(pb, 8, 0); +} +#endif + + +/* VLC decoding */ + +//#define DEBUG_VLC + +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} + + +static int alloc_table(VLC *vlc, int size, int use_static) +{ + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + if(use_static) + { + DEBUGF("init_vlc() used with too little memory : table_size > allocated_memory\n"); + return -1; + } +// abort(); //cant do anything, init_vlc() is used with too little memory +// vlc->table_allocated += (1 << vlc->bits); +// vlc->table = av_realloc(vlc->table, +// sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + if (!vlc->table) + return -1; + } + return index; +} + +/* +static av_always_inline uint32_t bitswap_32(uint32_t x) { + return av_reverse[x&0xFF]<<24 + | av_reverse[(x>>8)&0xFF]<<16 + | av_reverse[(x>>16)&0xFF]<<8 + | av_reverse[x>>24]; +} +*/ + +typedef struct { + uint8_t bits; + uint16_t symbol; + /** codeword, with the first bit-to-be-read in the msb + * (even if intended for a little-endian bitstream reader) */ + uint32_t code; +} __attribute__((__packed__)) VLCcode; /* packed to save space */ + +static int compare_vlcspec(const void *a, const void *b) +{ + const VLCcode *sa=a, *sb=b; + return (sa->code >> 1) - (sb->code >> 1); +} + +/** + * Build VLC decoding tables suitable for use with get_vlc(). + * + * @param vlc the context to be initted + * + * @param table_nb_bits max length of vlc codes to store directly in this table + * (Longer codes are delegated to subtables.) + * + * @param nb_codes number of elements in codes[] + * + * @param codes descriptions of the vlc codes + * These must be ordered such that codes going into the same subtable are contiguous. + * Sorting by VLCcode.code is sufficient, though not necessary. + */ +static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, + VLCcode *codes, int flags) +{ + int table_size, table_index, index, symbol, subtable_bits; + int i, j, k, n, nb, inc; + uint32_t code, code_prefix; + VLC_TYPE (*table)[2]; + + table_size = 1 << table_nb_bits; + table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC); +#ifdef DEBUG_VLC + av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d\n", + table_index, table_size); +#endif + if (table_index < 0) + return -1; + table = &vlc->table[table_index]; + + for (i = 0; i < table_size; i++) { + table[i][1] = 0; //bits + table[i][0] = -1; //codes + } + + /* first pass: map codes and compute auxillary table sizes */ + for (i = 0; i < nb_codes; i++) { + n = codes[i].bits; + code = codes[i].code; + symbol = codes[i].symbol; +#if defined(DEBUG_VLC) && 0 + av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code); +#endif + if (n <= table_nb_bits) { + /* no need to add another table */ + j = code >> (32 - table_nb_bits); + nb = 1 << (table_nb_bits - n); + inc = 1; +/* if (flags & INIT_VLC_LE) { + j = bitswap_32(code); + inc = 1 << n; + } */ + for (k = 0; k < nb; k++) { +#ifdef DEBUG_VLC + av_log(NULL, AV_LOG_DEBUG, "%4x: code=%d n=%d\n", + j, i, n); +#endif + if (table[j][1] /*bits*/ != 0) { + av_log(NULL, AV_LOG_ERROR, "incorrect codes\n"); + return -1; + } + table[j][1] = n; //bits + table[j][0] = symbol; + j += inc; + } + } else { + /* fill auxiliary table recursively */ + n -= table_nb_bits; + code_prefix = code >> (32 - table_nb_bits); + subtable_bits = n; + codes[i].bits = n; + codes[i].code = code << table_nb_bits; + for (k = i+1; k < nb_codes; k++) { + n = codes[k].bits - table_nb_bits; + if (n <= 0) + break; + code = codes[k].code; + if (code >> (32 - table_nb_bits) != code_prefix) + break; + codes[k].bits = n; + codes[k].code = code << table_nb_bits; + subtable_bits = FFMAX(subtable_bits, n); + } + subtable_bits = FFMIN(subtable_bits, table_nb_bits); + j = /*(flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) :*/ code_prefix; + table[j][1] = -subtable_bits; +#ifdef DEBUG_VLC + av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n", + j, codes[i].bits + table_nb_bits); +#endif + index = build_table(vlc, subtable_bits, k-i, codes+i, flags); + if (index < 0) + return -1; + /* note: realloc has been done, so reload tables */ + table = &vlc->table[table_index]; + table[j][0] = index; //code + i = k-1; + } + } + return table_index; +} + + +/* Build VLC decoding tables suitable for use with get_vlc(). + + 'nb_bits' set thee decoding table size (2^nb_bits) entries. The + bigger it is, the faster is the decoding. But it should not be too + big to save memory and L1 cache. '9' is a good compromise. + + 'nb_codes' : number of vlcs codes + + 'bits' : table which gives the size (in bits) of each vlc code. + + 'codes' : table which gives the bit pattern of of each vlc code. + + 'symbols' : table which gives the values to be returned from get_vlc(). + + 'xxx_wrap' : give the number of bytes between each entry of the + 'bits' or 'codes' tables. + + 'xxx_size' : gives the number of bytes of each entry of the 'bits' + or 'codes' tables. + + 'wrap' and 'size' allows to use any memory configuration and types + (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. + + 'use_static' should be set to 1 for tables, which should be freed + with av_free_static(), 0 if free_vlc() will be used. +*/ + +/* Rockbox: support for INIT_VLC_LE is currently disabled since none of our + codecs use it, there's a LUT based bit reverse function for this commented + out above (bitswap_32) and an inline asm version in libtremor/codebook.c + if we ever want this */ + +static VLCcode buf[1336+1]; /* worst case is wma, which has one table with 1336 entries */ + +int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, + int flags) +{ + if (nb_codes+1 > (int)(sizeof (buf)/ sizeof (VLCcode))) + { + DEBUGF("Table is larger than temp buffer!\n"); + return -1; + } + + int i, j, ret; + + vlc->bits = nb_bits; + if(flags & INIT_VLC_USE_NEW_STATIC){ + if(vlc->table_size && vlc->table_size == vlc->table_allocated){ + return 0; + }else if(vlc->table_size){ + DEBUGF("fatal error, we are called on a partially initialized table\n"); + return -1; +// abort(); // fatal error, we are called on a partially initialized table + } + }else { + vlc->table = NULL; + vlc->table_allocated = 0; + vlc->table_size = 0; + } + +#ifdef DEBUG_VLC + av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes); +#endif + +// buf = av_malloc((nb_codes+1)*sizeof(VLCcode)); + +// assert(symbols_size <= 2 || !symbols); + j = 0; +#define COPY(condition)\ + for (i = 0; i < nb_codes; i++) {\ + GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);\ + if (!(condition))\ + continue;\ + GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);\ +/* if (flags & INIT_VLC_LE)*/\ +/* buf[j].code = bitswap_32(buf[j].code);*/\ +/* else*/\ + buf[j].code <<= 32 - buf[j].bits;\ + if (symbols)\ + GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size)\ + else\ + buf[j].symbol = i;\ + j++;\ + } + COPY(buf[j].bits > nb_bits); + // qsort is the slowest part of init_vlc, and could probably be improved or avoided + qsort(buf, j, sizeof(VLCcode), compare_vlcspec); + COPY(buf[j].bits && buf[j].bits <= nb_bits); + nb_codes = j; + + ret = build_table(vlc, nb_bits, nb_codes, buf, flags); + +// av_free(buf); + if (ret < 0) { +// av_freep(&vlc->table); + return -1; + } + if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated) { + av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated); + } + return 0; +} + +/* not used in rockbox +void free_vlc(VLC *vlc) +{ + av_freep(&vlc->table); +} +*/ + diff --git a/plugins/wma/libwma/ffmpeg_get_bits.h b/plugins/wma/libwma/ffmpeg_get_bits.h new file mode 100644 index 00000000..6561afa4 --- /dev/null +++ b/plugins/wma/libwma/ffmpeg_get_bits.h @@ -0,0 +1,746 @@ +/* + * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * bitstream reader API header. + */ + +#ifndef AVCODEC_GET_BITS_H +#define AVCODEC_GET_BITS_H + +//#include <stdint.h> +//#include <stdlib.h> +#include "platform.h" +#include "ffmpeg_intreadwrite.h" +//#include <assert.h> +//#include "libavutil/bswap.h" +//#include "libavutil/common.h" +//#include "libavutil/intreadwrite.h" +//#include "libavutil/log.h" +//#include "mathops.h" + +/* rockbox' optimised inline functions */ +#ifndef bswap_16 +#define bswap_16(x) swap16(x) +#endif +#ifndef bswap_32 +#define bswap_32(x) swap32(x) +#endif + +#ifdef ROCKBOX_BIG_ENDIAN +#define be2me_16(x) (x) +#define be2me_32(x) (x) +#define le2me_16(x) bswap_16(x) +#define le2me_32(x) bswap_32(x) +#else +#define be2me_16(x) bswap_16(x) +#define be2me_32(x) bswap_32(x) +#define le2me_16(x) (x) +#define le2me_32(x) (x) +#endif + +#define av_const __attribute__((const)) +#define av_always_inline inline __attribute__((always_inline)) + +/* The following is taken from mathops.h */ + +#ifndef sign_extend +static inline av_const int sign_extend(int val, unsigned bits) +{ + return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits); +} +#endif + +#ifndef NEG_SSR32 +# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) +#endif + +#ifndef NEG_USR32 +# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) +#endif + +/* these 2 are from libavutil/common.h */ + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) + +#if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) +# define ALT_BITSTREAM_READER +#endif + +/* +#if !defined(LIBMPEG2_BITSTREAM_READER) && !defined(A32_BITSTREAM_READER) && !defined(ALT_BITSTREAM_READER) +# if ARCH_ARM && !HAVE_FAST_UNALIGNED +# define A32_BITSTREAM_READER +# else +*/ +# define ALT_BITSTREAM_READER +/* +//#define LIBMPEG2_BITSTREAM_READER +//#define A32_BITSTREAM_READER +# endif +#endif +*/ + +/* bit input */ +/* buffer, buffer_end and size_in_bits must be present and used by every reader */ +typedef struct GetBitContext { + const uint8_t *buffer, *buffer_end; +#ifdef ALT_BITSTREAM_READER + int index; +#elif defined LIBMPEG2_BITSTREAM_READER + uint8_t *buffer_ptr; + uint32_t cache; + int bit_count; +#elif defined A32_BITSTREAM_READER + uint32_t *buffer_ptr; + uint32_t cache0; + uint32_t cache1; + int bit_count; +#endif + int size_in_bits; +} GetBitContext; + +#define VLC_TYPE int16_t + +typedef struct VLC { + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} VLC; + +typedef struct RL_VLC_ELEM { + int16_t level; + int8_t len; + uint8_t run; +} RL_VLC_ELEM; + +/* Bitstream reader API docs: +name + arbitrary name which is used as prefix for the internal variables + +gb + getbitcontext + +OPEN_READER(name, gb) + loads gb into local variables + +CLOSE_READER(name, gb) + stores local vars in gb + +UPDATE_CACHE(name, gb) + refills the internal cache from the bitstream + after this call at least MIN_CACHE_BITS will be available, + +GET_CACHE(name, gb) + will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit) + +SHOW_UBITS(name, gb, num) + will return the next num bits + +SHOW_SBITS(name, gb, num) + will return the next num bits and do sign extension + +SKIP_BITS(name, gb, num) + will skip over the next num bits + note, this is equivalent to SKIP_CACHE; SKIP_COUNTER + +SKIP_CACHE(name, gb, num) + will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER) + +SKIP_COUNTER(name, gb, num) + will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS) + +LAST_SKIP_CACHE(name, gb, num) + will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing + +LAST_SKIP_BITS(name, gb, num) + is equivalent to LAST_SKIP_CACHE; SKIP_COUNTER + +for examples see get_bits, show_bits, skip_bits, get_vlc +*/ + +#ifdef ALT_BITSTREAM_READER +# define MIN_CACHE_BITS 25 + + +/* ROCKBOX: work around "set but not used" warning */ +# define OPEN_READER(name, gb)\ + unsigned int name##_index= (gb)->index;\ + int name##_cache __attribute__((unused)) = 0;\ + +# define CLOSE_READER(name, gb)\ + (gb)->index= name##_index;\ + +# ifdef ALT_BITSTREAM_READER_LE +# define UPDATE_CACHE(name, gb)\ + name##_cache= AV_RL32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache >>= (num); +# else +# define UPDATE_CACHE(name, gb)\ + name##_cache= AV_RB32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num); +# endif + +// FIXME name? +# define SKIP_COUNTER(name, gb, num)\ + name##_index += (num);\ + +# define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +# define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) +# define LAST_SKIP_CACHE(name, gb, num) ; + +# ifdef ALT_BITSTREAM_READER_LE +# define SHOW_UBITS(name, gb, num)\ + zero_extend(name##_cache, num) + +# define SHOW_SBITS(name, gb, num)\ + sign_extend(name##_cache, num) +# else +# define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) +# endif + +# define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static inline int get_bits_count(const GetBitContext *s){ + return s->index; +} + +static inline void skip_bits_long(GetBitContext *s, int n){ + s->index += n; +} + +#elif defined LIBMPEG2_BITSTREAM_READER +//libmpeg2 like reader + +# define MIN_CACHE_BITS 17 + +# define OPEN_READER(name, gb)\ + int name##_bit_count=(gb)->bit_count;\ + int name##_cache= (gb)->cache;\ + uint8_t * name##_buffer_ptr=(gb)->buffer_ptr;\ + +# define CLOSE_READER(name, gb)\ + (gb)->bit_count= name##_bit_count;\ + (gb)->cache= name##_cache;\ + (gb)->buffer_ptr= name##_buffer_ptr;\ + +# define UPDATE_CACHE(name, gb)\ + if(name##_bit_count >= 0){\ + name##_cache+= AV_RB16(name##_buffer_ptr) << name##_bit_count; \ + name##_buffer_ptr+=2;\ + name##_bit_count-= 16;\ + }\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num);\ + +# define SKIP_COUNTER(name, gb, num)\ + name##_bit_count += (num);\ + +# define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num) +# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num) + +# define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) + +# define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static inline int get_bits_count(const GetBitContext *s){ + return (s->buffer_ptr - s->buffer)*8 - 16 + s->bit_count; +} + +static inline void skip_bits_long(GetBitContext *s, int n){ + OPEN_READER(re, s) + re_bit_count += n; + re_buffer_ptr += 2*(re_bit_count>>4); + re_bit_count &= 15; + re_cache = ((re_buffer_ptr[-2]<<8) + re_buffer_ptr[-1]) << (16+re_bit_count); + UPDATE_CACHE(re, s) + CLOSE_READER(re, s) +} + +#elif defined A32_BITSTREAM_READER + +# define MIN_CACHE_BITS 32 + +# define OPEN_READER(name, gb)\ + int name##_bit_count=(gb)->bit_count;\ + uint32_t name##_cache0= (gb)->cache0;\ + uint32_t name##_cache1= (gb)->cache1;\ + uint32_t * name##_buffer_ptr=(gb)->buffer_ptr;\ + +# define CLOSE_READER(name, gb)\ + (gb)->bit_count= name##_bit_count;\ + (gb)->cache0= name##_cache0;\ + (gb)->cache1= name##_cache1;\ + (gb)->buffer_ptr= name##_buffer_ptr;\ + +# define UPDATE_CACHE(name, gb)\ + if(name##_bit_count > 0){\ + const uint32_t next= av_be2ne32( *name##_buffer_ptr );\ + name##_cache0 |= NEG_USR32(next,name##_bit_count);\ + name##_cache1 |= next<<name##_bit_count;\ + name##_buffer_ptr++;\ + name##_bit_count-= 32;\ + }\ + +#if ARCH_X86 +# define SKIP_CACHE(name, gb, num)\ + __asm__(\ + "shldl %2, %1, %0 \n\t"\ + "shll %2, %1 \n\t"\ + : "+r" (name##_cache0), "+r" (name##_cache1)\ + : "Ic" ((uint8_t)(num))\ + ); +#else +# define SKIP_CACHE(name, gb, num)\ + name##_cache0 <<= (num);\ + name##_cache0 |= NEG_USR32(name##_cache1,num);\ + name##_cache1 <<= (num); +#endif + +# define SKIP_COUNTER(name, gb, num)\ + name##_bit_count += (num);\ + +# define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num) +# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num) + +# define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache0, num) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache0, num) + +# define GET_CACHE(name, gb)\ + (name##_cache0) + +static inline int get_bits_count(const GetBitContext *s){ + return ((uint8_t*)s->buffer_ptr - s->buffer)*8 - 32 + s->bit_count; +} + +static inline void skip_bits_long(GetBitContext *s, int n){ + OPEN_READER(re, s) + re_bit_count += n; + re_buffer_ptr += re_bit_count>>5; + re_bit_count &= 31; + re_cache0 = av_be2ne32( re_buffer_ptr[-1] ) << re_bit_count; + re_cache1 = 0; + UPDATE_CACHE(re, s) + CLOSE_READER(re, s) +} + +#endif + +/** + * read mpeg1 dc style vlc (sign bit + mantisse with no MSB). + * if MSB not set it is negative + * @param n length in bits + * @author BERO + */ +static inline int get_xbits(GetBitContext *s, int n){ + register int sign; + register int32_t cache; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + cache = GET_CACHE(re,s); + sign=(~cache)>>31; + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; +} + +static inline int get_sbits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_SBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +/** + * reads 1-17 bits. + * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't + */ +static inline unsigned int get_bits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +/** + * shows 1-17 bits. + * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't + */ +static inline unsigned int show_bits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); +// CLOSE_READER(re, s) + return tmp; +} + +static inline void skip_bits(GetBitContext *s, int n){ + //Note gcc seems to optimize this to s->index+=n for the ALT_READER :)) + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) +} + +static inline unsigned int get_bits1(GetBitContext *s){ +#ifdef ALT_BITSTREAM_READER + unsigned int index= s->index; + uint8_t result= s->buffer[ index>>3 ]; +#ifdef ALT_BITSTREAM_READER_LE + result>>= (index&0x07); + result&= 1; +#else + result<<= (index&0x07); + result>>= 8 - 1; +#endif + index++; + s->index= index; + + return result; +#else + return get_bits(s, 1); +#endif +} + +static inline unsigned int show_bits1(GetBitContext *s){ + return show_bits(s, 1); +} + +static inline void skip_bits1(GetBitContext *s){ + skip_bits(s, 1); +} + +/** + * reads 0-32 bits. + */ +static inline unsigned int get_bits_long(GetBitContext *s, int n){ + if(n<=MIN_CACHE_BITS) return get_bits(s, n); + else{ +#ifdef ALT_BITSTREAM_READER_LE + int ret= get_bits(s, 16); + return ret | (get_bits(s, n-16) << 16); +#else + int ret= get_bits(s, 16) << (n-16); + return ret | get_bits(s, n-16); +#endif + } +} + +/** + * reads 0-32 bits as a signed integer. + */ +static inline int get_sbits_long(GetBitContext *s, int n) { + return sign_extend(get_bits_long(s, n), n); +} + +/** + * shows 0-32 bits. + */ +static inline unsigned int show_bits_long(GetBitContext *s, int n){ + if(n<=MIN_CACHE_BITS) return show_bits(s, n); + else{ + GetBitContext gb= *s; + return get_bits_long(&gb, n); + } +} + +/* not used +static inline int check_marker(GetBitContext *s, const char *msg) +{ + int bit= get_bits1(s); + if(!bit) + av_log(NULL, AV_LOG_INFO, "Marker bit missing %s\n", msg); + + return bit; +} +*/ + +/** + * init GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits + * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + * + * While GetBitContext stores the buffer size, for performance reasons you are + * responsible for checking for the buffer end yourself (take advantage of the padding)! + */ +static inline void init_get_bits(GetBitContext *s, + const uint8_t *buffer, int bit_size) +{ + int buffer_size= (bit_size+7)>>3; + if(buffer_size < 0 || bit_size < 0) { + buffer_size = bit_size = 0; + buffer = NULL; + } + + s->buffer= buffer; + s->size_in_bits= bit_size; + s->buffer_end= buffer + buffer_size; +#ifdef ALT_BITSTREAM_READER + s->index=0; +#elif defined LIBMPEG2_BITSTREAM_READER + s->buffer_ptr = (uint8_t*)((intptr_t)buffer&(~1)); + s->bit_count = 16 + 8*((intptr_t)buffer&1); + skip_bits_long(s, 0); +#elif defined A32_BITSTREAM_READER + s->buffer_ptr = (uint32_t*)((intptr_t)buffer&(~3)); + s->bit_count = 32 + 8*((intptr_t)buffer&3); + skip_bits_long(s, 0); +#endif +} + +static inline void align_get_bits(GetBitContext *s) +{ + int n= (-get_bits_count(s)) & 7; + if(n) skip_bits(s, n); +} + +#define init_vlc(vlc, nb_bits, nb_codes,\ + bits, bits_wrap, bits_size,\ + codes, codes_wrap, codes_size,\ + flags)\ + init_vlc_sparse(vlc, nb_bits, nb_codes,\ + bits, bits_wrap, bits_size,\ + codes, codes_wrap, codes_size,\ + NULL, 0, 0, flags) + +int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, + int flags); +#define INIT_VLC_LE 2 +#define INIT_VLC_USE_NEW_STATIC 4 +void free_vlc(VLC *vlc); + +#define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size, attr)\ +{\ + static VLC_TYPE table[static_size][2] attr;\ + (vlc)->table= table;\ + (vlc)->table_allocated= static_size;\ + init_vlc(vlc, bits, a,b,c,d,e,f,g, INIT_VLC_USE_NEW_STATIC);\ +} + + +/** + * + * If the vlc code is invalid and max_depth=1, then no bits will be removed. + * If the vlc code is invalid and max_depth>1, then the number of bits removed + * is undefined. + */ +#define GET_VLC(code, name, gb, table, bits, max_depth)\ +{\ + int n, nb_bits;\ + unsigned int index;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + code = table[index][0];\ + n = table[index][1];\ +\ + if(max_depth > 1 && n < 0){\ + LAST_SKIP_BITS(name, gb, bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + if(max_depth > 2 && n < 0){\ + LAST_SKIP_BITS(name, gb, nb_bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + }\ + }\ + SKIP_BITS(name, gb, n)\ +} + +#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update)\ +{\ + int n, nb_bits;\ + unsigned int index;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + level = table[index].level;\ + n = table[index].len;\ +\ + if(max_depth > 1 && n < 0){\ + SKIP_BITS(name, gb, bits)\ + if(need_update){\ + UPDATE_CACHE(name, gb)\ + }\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + level;\ + level = table[index].level;\ + n = table[index].len;\ + }\ + run= table[index].run;\ + SKIP_BITS(name, gb, n)\ +} + + +/** + * parses a vlc code, faster then get_vlc() + * @param bits is the number of bits which will be read at once, must be + * identical to nb_bits in init_vlc() + * @param max_depth is the number of times bits bits must be read to completely + * read the longest vlc code + * = (max_vlc_length + bits - 1) / bits + */ +static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], + int bits, int max_depth) +{ + int code; + + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + + GET_VLC(code, re, s, table, bits, max_depth) + + CLOSE_READER(re, s) + return code; +} + +//#define TRACE + +#ifdef TRACE +static inline void print_bin(int bits, int n){ + int i; + + for(i=n-1; i>=0; i--){ + av_log(NULL, AV_LOG_DEBUG, "%d", (bits>>i)&1); + } + for(i=n; i<24; i++) + av_log(NULL, AV_LOG_DEBUG, " "); +} + +static inline int get_bits_trace(GetBitContext *s, int n, char *file, const char *func, int line){ + int r= get_bits(s, n); + + print_bin(r, n); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line); + return r; +} +static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int r= get_vlc2(s, table, bits, max_depth); + int len= get_bits_count(s) - pos; + int bits2= show>>(24-len); + + print_bin(bits2, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line); + return r; +} +static inline int get_xbits_trace(GetBitContext *s, int n, char *file, const char *func, int line){ + int show= show_bits(s, n); + int r= get_xbits(s, n); + + print_bin(show, n); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line); + return r; +} + +#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__) + +#define tprintf(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__) + +#else //TRACE +#define tprintf(p, ...) {} +#endif + +static inline int decode012(GetBitContext *gb){ + int n; + n = get_bits1(gb); + if (n == 0) + return 0; + else + return get_bits1(gb) + 1; +} + +static inline int decode210(GetBitContext *gb){ + if (get_bits1(gb)) + return 0; + else + return 2 - get_bits1(gb); +} + +static inline int get_bits_left(GetBitContext *gb) +{ + return gb->size_in_bits - get_bits_count(gb); +} + +#endif /* AVCODEC_GET_BITS_H */ diff --git a/plugins/wma/libwma/ffmpeg_intreadwrite.h b/plugins/wma/libwma/ffmpeg_intreadwrite.h new file mode 100644 index 00000000..24f03292 --- /dev/null +++ b/plugins/wma/libwma/ffmpeg_intreadwrite.h @@ -0,0 +1,484 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTREADWRITE_H +#define AVUTIL_INTREADWRITE_H + +#include <stdint.h> +/* + * Arch-specific headers can provide any combination of + * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros. + * Preprocessor symbols must be defined, even if these are implemented + * as inline functions. + */ + +/* + * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers. + */ +#define HAVE_BIGENDIAN 0 +#if HAVE_BIGENDIAN + +# if defined(AV_RN16) && !defined(AV_RB16) +# define AV_RB16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RB16) +# define AV_RN16(p) AV_RB16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WB16) +# define AV_WB16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WB16) +# define AV_WN16(p, v) AV_WB16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RB24) +# define AV_RB24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RB24) +# define AV_RN24(p) AV_RB24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WB24) +# define AV_WB24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WB24) +# define AV_WN24(p, v) AV_WB24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RB32) +# define AV_RB32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RB32) +# define AV_RN32(p) AV_RB32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WB32) +# define AV_WB32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WB32) +# define AV_WN32(p, v) AV_WB32(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RB64) +# define AV_RB64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RB64) +# define AV_RN64(p) AV_RB64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WB64) +# define AV_WB64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WB64) +# define AV_WN64(p, v) AV_WB64(p, v) +# endif + +#else /* HAVE_BIGENDIAN */ + +# if defined(AV_RN16) && !defined(AV_RL16) +# define AV_RL16(p) AV_RN16(p) +# elif !defined(AV_RN16) && defined(AV_RL16) +# define AV_RN16(p) AV_RL16(p) +# endif + +# if defined(AV_WN16) && !defined(AV_WL16) +# define AV_WL16(p, v) AV_WN16(p, v) +# elif !defined(AV_WN16) && defined(AV_WL16) +# define AV_WN16(p, v) AV_WL16(p, v) +# endif + +# if defined(AV_RN24) && !defined(AV_RL24) +# define AV_RL24(p) AV_RN24(p) +# elif !defined(AV_RN24) && defined(AV_RL24) +# define AV_RN24(p) AV_RL24(p) +# endif + +# if defined(AV_WN24) && !defined(AV_WL24) +# define AV_WL24(p, v) AV_WN24(p, v) +# elif !defined(AV_WN24) && defined(AV_WL24) +# define AV_WN24(p, v) AV_WL24(p, v) +# endif + +# if defined(AV_RN32) && !defined(AV_RL32) +# define AV_RL32(p) AV_RN32(p) +# elif !defined(AV_RN32) && defined(AV_RL32) +# define AV_RN32(p) AV_RL32(p) +# endif + +# if defined(AV_WN32) && !defined(AV_WL32) +# define AV_WL32(p, v) AV_WN32(p, v) +# elif !defined(AV_WN32) && defined(AV_WL32) +# define AV_WN32(p, v) AV_WL32(p, v) +# endif + +# if defined(AV_RN64) && !defined(AV_RL64) +# define AV_RL64(p) AV_RN64(p) +# elif !defined(AV_RN64) && defined(AV_RL64) +# define AV_RN64(p) AV_RL64(p) +# endif + +# if defined(AV_WN64) && !defined(AV_WL64) +# define AV_WL64(p, v) AV_WN64(p, v) +# elif !defined(AV_WN64) && defined(AV_WL64) +# define AV_WN64(p, v) AV_WL64(p, v) +# endif + +#endif /* !HAVE_BIGENDIAN */ + +#define HAVE_ATTRIBUTE_PACKED 0 +#define HAVE_FAST_UNALIGNED 0 +/* + * Define AV_[RW]N helper macros to simplify definitions not provided + * by per-arch headers. + */ + +#if HAVE_ATTRIBUTE_PACKED + +union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; +union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; +union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; + +# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) +# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) + +#elif defined(__DECC) + +# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) +# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) + +#elif HAVE_FAST_UNALIGNED + +# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) +# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#else + +#ifndef AV_RB16 +# define AV_RB16(x) \ + ((((const uint8_t*)(x))[0] << 8) | \ + ((const uint8_t*)(x))[1]) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, d) do { \ + ((uint8_t*)(p))[1] = (d); \ + ((uint8_t*)(p))[0] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RL16 +# define AV_RL16(x) \ + ((((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + } while(0) +#endif + +#ifndef AV_RB32 +/* Coldfire and ARMv6 and above support unaligned long reads */ +#if defined CPU_COLDFIRE || (defined CPU_ARM && ARM_ARCH >= 6) +#define AV_RB32(x) (htobe32(*(const uint32_t*)(x))) +#else +# define AV_RB32(x) \ + ((((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) +#endif +#endif +#ifndef AV_WB32 +# define AV_WB32(p, d) do { \ + ((uint8_t*)(p))[3] = (d); \ + ((uint8_t*)(p))[2] = (d)>>8; \ + ((uint8_t*)(p))[1] = (d)>>16; \ + ((uint8_t*)(p))[0] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RL32 +# define AV_RL32(x) \ + ((((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + } while(0) +#endif + +#ifndef AV_RB64 +# define AV_RB64(x) \ + (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ + (uint64_t)((const uint8_t*)(x))[7]) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, d) do { \ + ((uint8_t*)(p))[7] = (d); \ + ((uint8_t*)(p))[6] = (d)>>8; \ + ((uint8_t*)(p))[5] = (d)>>16; \ + ((uint8_t*)(p))[4] = (d)>>24; \ + ((uint8_t*)(p))[3] = (d)>>32; \ + ((uint8_t*)(p))[2] = (d)>>40; \ + ((uint8_t*)(p))[1] = (d)>>48; \ + ((uint8_t*)(p))[0] = (d)>>56; \ + } while(0) +#endif + +#ifndef AV_RL64 +# define AV_RL64(x) \ + (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ + ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ + ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ + ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ + ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ + ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ + ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ + (uint64_t)((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ + ((uint8_t*)(p))[4] = (d)>>32; \ + ((uint8_t*)(p))[5] = (d)>>40; \ + ((uint8_t*)(p))[6] = (d)>>48; \ + ((uint8_t*)(p))[7] = (d)>>56; \ + } while(0) +#endif + +#if HAVE_BIGENDIAN +# define AV_RN(s, p) AV_RB##s(p) +# define AV_WN(s, p, v) AV_WB##s(p, v) +#else +# define AV_RN(s, p) AV_RL##s(p) +# define AV_WN(s, p, v) AV_WL##s(p, v) +#endif + +#endif /* HAVE_FAST_UNALIGNED */ + +#ifndef AV_RN16 +# define AV_RN16(p) AV_RN(16, p) +#endif + +#ifndef AV_RN32 +# define AV_RN32(p) AV_RN(32, p) +#endif + +#ifndef AV_RN64 +# define AV_RN64(p) AV_RN(64, p) +#endif + +#ifndef AV_WN16 +# define AV_WN16(p, v) AV_WN(16, p, v) +#endif + +#ifndef AV_WN32 +# define AV_WN32(p, v) AV_WN(32, p, v) +#endif + +#ifndef AV_WN64 +# define AV_WN64(p, v) AV_WN(64, p, v) +#endif + +#if HAVE_BIGENDIAN +# define AV_RB(s, p) AV_RN##s(p) +# define AV_WB(s, p, v) AV_WN##s(p, v) +# define AV_RL(s, p) bswap_##s(AV_RN##s(p)) +# define AV_WL(s, p, v) AV_WN##s(p, bswap_##s(v)) +#else +# define AV_RB(s, p) bswap_##s(AV_RN##s(p)) +# define AV_WB(s, p, v) AV_WN##s(p, bswap_##s(v)) +# define AV_RL(s, p) AV_RN##s(p) +# define AV_WL(s, p, v) AV_WN##s(p, v) +#endif + +#define AV_RB8(x) (((const uint8_t*)(x))[0]) +#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) + +#define AV_RL8(x) AV_RB8(x) +#define AV_WL8(p, d) AV_WB8(p, d) + +#ifndef AV_RB16 +# define AV_RB16(p) AV_RB(16, p) +#endif +#ifndef AV_WB16 +# define AV_WB16(p, v) AV_WB(16, p, v) +#endif + +#ifndef AV_RL16 +# define AV_RL16(p) AV_RL(16, p) +#endif +#ifndef AV_WL16 +# define AV_WL16(p, v) AV_WL(16, p, v) +#endif + +#ifndef AV_RB32 +# define AV_RB32(p) AV_RB(32, p) +#endif +#ifndef AV_WB32 +# define AV_WB32(p, v) AV_WB(32, p, v) +#endif + +#ifndef AV_RL32 +# define AV_RL32(p) AV_RL(32, p) +#endif +#ifndef AV_WL32 +# define AV_WL32(p, v) AV_WL(32, p, v) +#endif + +#ifndef AV_RB64 +# define AV_RB64(p) AV_RB(64, p) +#endif +#ifndef AV_WB64 +# define AV_WB64(p, v) AV_WB(64, p, v) +#endif + +#ifndef AV_RL64 +# define AV_RL64(p) AV_RL(64, p) +#endif +#ifndef AV_WL64 +# define AV_WL64(p, v) AV_WL(64, p, v) +#endif + +#ifndef AV_RB24 +# define AV_RB24(x) \ + ((((const uint8_t*)(x))[0] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[2]) +#endif +#ifndef AV_WB24 +# define AV_WB24(p, d) do { \ + ((uint8_t*)(p))[2] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[0] = (d)>>16; \ + } while(0) +#endif + +#ifndef AV_RL24 +# define AV_RL24(x) \ + ((((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) +#endif +#ifndef AV_WL24 +# define AV_WL24(p, d) do { \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + } while(0) +#endif + +/* + * The AV_[RW]NA macros access naturally aligned data + * in a type-safe way. + */ + +#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s) +#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v)) + +#ifndef AV_RN16A +# define AV_RN16A(p) AV_RNA(16, p) +#endif + +#ifndef AV_RN32A +# define AV_RN32A(p) AV_RNA(32, p) +#endif + +#ifndef AV_RN64A +# define AV_RN64A(p) AV_RNA(64, p) +#endif + +#ifndef AV_WN16A +# define AV_WN16A(p, v) AV_WNA(16, p, v) +#endif + +#ifndef AV_WN32A +# define AV_WN32A(p, v) AV_WNA(32, p, v) +#endif + +#ifndef AV_WN64A +# define AV_WN64A(p, v) AV_WNA(64, p, v) +#endif + +/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be + * naturally aligned. They may be implemented using MMX, + * so emms_c() must be called before using any float code + * afterwards. + */ + +#define AV_COPY(n, d, s) \ + (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) + +#ifndef AV_COPY16 +# define AV_COPY16(d, s) AV_COPY(16, d, s) +#endif + +#ifndef AV_COPY32 +# define AV_COPY32(d, s) AV_COPY(32, d, s) +#endif + +#ifndef AV_COPY64 +# define AV_COPY64(d, s) AV_COPY(64, d, s) +#endif + +#ifndef AV_COPY128 +# define AV_COPY128(d, s) \ + do { \ + AV_COPY64(d, s); \ + AV_COPY64((char*)(d)+8, (char*)(s)+8); \ + } while(0) +#endif + +#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) + +#ifndef AV_SWAP64 +# define AV_SWAP64(a, b) AV_SWAP(64, a, b) +#endif + +#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) + +#ifndef AV_ZERO16 +# define AV_ZERO16(d) AV_ZERO(16, d) +#endif + +#ifndef AV_ZERO32 +# define AV_ZERO32(d) AV_ZERO(32, d) +#endif + +#ifndef AV_ZERO64 +# define AV_ZERO64(d) AV_ZERO(64, d) +#endif + +#ifndef AV_ZERO128 +# define AV_ZERO128(d) \ + do { \ + AV_ZERO64(d); \ + AV_ZERO64((char*)(d)+8); \ + } while(0) +#endif + +#endif /* AVUTIL_INTREADWRITE_H */ diff --git a/plugins/wma/libwma/fft-ffmpeg.c b/plugins/wma/libwma/fft-ffmpeg.c new file mode 100644 index 00000000..e2d1777d --- /dev/null +++ b/plugins/wma/libwma/fft-ffmpeg.c @@ -0,0 +1,481 @@ +/* + * FFT/IFFT transforms converted to integer precision + * Copyright (c) 2010 Dave Hooper, Mohamed Tarek, Michael Giacomelli + * Copyright (c) 2008 Loren Merritt + * Copyright (c) 2002 Fabrice Bellard + * Partly based on libdjbfft by D. J. Bernstein + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavcodec/fft.c + * FFT/IFFT transforms. + */ + + +#ifdef CPU_ARM +// we definitely want CONFIG_SMALL undefined for ipod +// so we get the inlined version of fft16 (which is measurably faster) +#undef CONFIG_SMALL +#else +#undef CONFIG_SMALL +#endif + +#include "fft.h" +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <inttypes.h> +#include <time.h> + +#include "codeclib_misc.h" +#include "mdct_lookup.h" + +/* constants for fft_16 (same constants as in mdct_arm.S ... ) */ +#define cPI1_8 (0x7641af3d) /* cos(pi/8) s.31 */ +#define cPI2_8 (0x5a82799a) /* cos(2pi/8) = 1/sqrt(2) s.31 */ +#define cPI3_8 (0x30fbc54d) /* cos(3pi/8) s.31 */ + +/* asm-optimised functions and/or macros */ +#include "fft-ffmpeg_arm.h" + +#ifndef ICODE_ATTR_TREMOR_MDCT +#define ICODE_ATTR_TREMOR_MDCT ICODE_ATTR +#endif + +/* Use to give gcc hints on which branch is most likely taken */ +#if defined(__GNUC__) && __GNUC__ >= 3 +#define LIKELY(x) __builtin_expect(!!(x), 1) +#define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +#if 0 +static int split_radix_permutation(int i, int n, int inverse) +{ + int m; + if(n <= 2) return i&1; + m = n >> 1; + if(!(i&m)) return split_radix_permutation(i, m, inverse)*2; + m >>= 1; + if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1; + else return split_radix_permutation(i, m, inverse)*4 - 1; +} + +static void ff_fft_permute_c(FFTContext *s, FFTComplex *z) +{ + int j, k, np; + FFTComplex tmp; + //const uint16_t *revtab = s->revtab; + np = 1 << s->nbits; + + const int revtab_shift = (12 - s->nbits); + + /* reverse */ + for(j=0;j<np;j++) { + k = revtab[j]>>revtab_shift; + if (k < j) { + tmp = z[k]; + z[k] = z[j]; + z[j] = tmp; + } + } +} +#endif + +#define BF(x,y,a,b) {\ + x = a - b;\ + y = a + b;\ +} + +#define BF_REV(x,y,a,b) {\ + x = a + b;\ + y = a - b;\ +} + +#ifndef FFT_FFMPEG_INCL_OPTIMISED_BUTTERFLIES +#define BUTTERFLIES(a0,a1,a2,a3) {\ + {\ + FFTSample temp1,temp2;\ + BF(temp1, temp2, t5, t1);\ + BF(a2.re, a0.re, a0.re, temp2);\ + BF(a3.im, a1.im, a1.im, temp1);\ + }\ + {\ + FFTSample temp1,temp2;\ + BF(temp1, temp2, t2, t6);\ + BF(a3.re, a1.re, a1.re, temp1);\ + BF(a2.im, a0.im, a0.im, temp2);\ + }\ +} + +// force loading all the inputs before storing any. +// this is slightly slower for small data, but avoids store->load aliasing +// for addresses separated by large powers of 2. +#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\ + FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\ + {\ + FFTSample temp1, temp2;\ + BF(temp1, temp2, t5, t1);\ + BF(a2.re, a0.re, r0, temp2);\ + BF(a3.im, a1.im, i1, temp1);\ + }\ + {\ + FFTSample temp1, temp2;\ + BF(temp1, temp2, t2, t6);\ + BF(a3.re, a1.re, r1, temp1);\ + BF(a2.im, a0.im, i0, temp2);\ + }\ +} +#endif + +/* + see conjugate pair description in + http://www.fftw.org/newsplit.pdf + + a0 = z[k] + a1 = z[k+N/4] + a2 = z[k+2N/4] + a3 = z[k+3N/4] + + result: + y[k] = z[k]+w(z[k+2N/4])+w'(z[k+3N/4]) + y[k+N/4] = z[k+N/4]-iw(z[k+2N/4])+iw'(z[k+3N/4]) + y[k+2N/4] = z[k]-w(z[k+2N/4])-w'(z[k+3N/4]) + y[k+3N/4] = z[k+N/4]+iw(z[k+2N/4])-iw'(z[k+3N/4]) + + i.e. + + a0 = a0 + (w.a2 + w'.a3) + a1 = a1 - i(w.a2 - w'.a3) + a2 = a0 - (w.a2 + w'.a3) + a3 = a1 + i(w.a2 - w'.a3) + + note re(w') = re(w) and im(w') = -im(w) + + so therefore + + re(a0) = re(a0) + re(w.a2) + re(w.a3) + im(a0) = im(a0) + im(w.a2) - im(w.a3) etc + + and remember also that + Re([s+it][u+iv]) = su-tv + Im([s+it][u+iv]) = sv+tu + + so + Re(w'.(s+it)) = Re(w').s - Im(w').t = Re(w).s + Im(w).t + Im(w'.(s+it)) = Re(w').t + Im(w').s = Re(w).t - Im(w).s + + For inverse dft we take the complex conjugate of all twiddle factors. + Hence + + a0 = a0 + (w'.a2 + w.a3) + a1 = a1 - i(w'.a2 - w.a3) + a2 = a0 - (w'.a2 + w.a3) + a3 = a1 + i(w'.a2 - w.a3) + + Define t1 = Re(w'.a2) = Re(w)*Re(a2) + Im(w)*Im(a2) + t2 = Im(w'.a2) = Re(w)*Im(a2) - Im(w)*Re(a2) + t5 = Re(w.a3) = Re(w)*Re(a3) - Im(w)*Im(a3) + t6 = Im(w.a3) = Re(w)*Im(a3) + Im(w)*Re(a3) + + Then we just output: + a0.re = a0.re + ( t1 + t5 ) + a0.im = a0.im + ( t2 + t6 ) + a1.re = a1.re + ( t2 - t6 ) // since we multiply by -i and i(-i) = 1 + a1.im = a1.im - ( t1 - t5 ) // since we multiply by -i and 1(-i) = -i + a2.re = a0.re - ( t1 + t5 ) + a2.im = a0.im - ( t1 + t5 ) + a3.re = a1.re - ( t2 - t6 ) // since we multiply by +i and i(+i) = -1 + a3.im = a1.im + ( t1 - t5 ) // since we multiply by +i and 1(+i) = i + + +*/ + +#ifndef FFT_FFMPEG_INCL_OPTIMISED_TRANSFORM +static inline FFTComplex* TRANSFORM(FFTComplex * z, unsigned int n, FFTSample wre, FFTSample wim) +{ + register FFTSample t1,t2,t5,t6,r_re,r_im; + r_re = z[n*2].re; + r_im = z[n*2].im; + XPROD31_R(r_re, r_im, wre, wim, t1,t2); + r_re = z[n*3].re; + r_im = z[n*3].im; + XNPROD31_R(r_re, r_im, wre, wim, t5,t6); + BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]); + return z+1; +} + +static inline FFTComplex* TRANSFORM_W01(FFTComplex * z, unsigned int n, const FFTSample * w) +{ + register const FFTSample wre=w[0],wim=w[1]; + register FFTSample t1,t2,t5,t6,r_re,r_im; + r_re = z[n*2].re; + r_im = z[n*2].im; + XPROD31_R(r_re, r_im, wre, wim, t1,t2); + r_re = z[n*3].re; + r_im = z[n*3].im; + XNPROD31_R(r_re, r_im, wre, wim, t5,t6); + BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]); + return z+1; +} + +static inline FFTComplex* TRANSFORM_W10(FFTComplex * z, unsigned int n, const FFTSample * w) +{ + register const FFTSample wim=w[0],wre=w[1]; + register FFTSample t1,t2,t5,t6,r_re,r_im; + r_re = z[n*2].re; + r_im = z[n*2].im; + XPROD31_R(r_re, r_im, wre, wim, t1,t2); + r_re = z[n*3].re; + r_im = z[n*3].im; + XNPROD31_R(r_re, r_im, wre, wim, t5,t6); + BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]); + return z+1; +} + +static inline FFTComplex* TRANSFORM_EQUAL(FFTComplex * z, unsigned int n) +{ + register FFTSample t1,t2,t5,t6,temp1,temp2; + register FFTSample * my_z = (FFTSample *)(z); + my_z += n*4; + t2 = MULT31(my_z[0], cPI2_8); + temp1 = MULT31(my_z[1], cPI2_8); + my_z += n*2; + temp2 = MULT31(my_z[0], cPI2_8); + t5 = MULT31(my_z[1], cPI2_8); + t1 = ( temp1 + t2 ); + t2 = ( temp1 - t2 ); + t6 = ( temp2 + t5 ); + t5 = ( temp2 - t5 ); + my_z -= n*6; + BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]); + return z+1; +} + +static inline FFTComplex* TRANSFORM_ZERO(FFTComplex * z, unsigned int n) +{ + FFTSample t1,t2,t5,t6; + t1 = z[n*2].re; + t2 = z[n*2].im; + t5 = z[n*3].re; + t6 = z[n*3].im; + BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]); + return z+1; +} +#endif + +/* z[0...8n-1], w[1...2n-1] */ +#define ICODE_ATTR +static void pass(FFTComplex *z_arg, unsigned int STEP_arg, unsigned int n_arg) ICODE_ATTR_TREMOR_MDCT; +static void pass(FFTComplex *z_arg, unsigned int STEP_arg, unsigned int n_arg) +{ + register FFTComplex * z = z_arg; + register unsigned int STEP = STEP_arg; + register unsigned int n = n_arg; + + register const FFTSample *w = sincos_lookup0+STEP; + /* wre = *(wim+1) . ordering is sin,cos */ + register const FFTSample *w_end = sincos_lookup0+1024; + + /* first two are special (well, first one is special, but we need to do pairs) */ + z = TRANSFORM_ZERO(z,n); + z = TRANSFORM_W10(z,n,w); + w += STEP; + /* first pass forwards through sincos_lookup0*/ + do { + z = TRANSFORM_W10(z,n,w); + w += STEP; + z = TRANSFORM_W10(z,n,w); + w += STEP; + } while(LIKELY(w < w_end)); + /* second half: pass backwards through sincos_lookup0*/ + /* wim and wre are now in opposite places so ordering now [0],[1] */ + w_end=sincos_lookup0; + while(LIKELY(w>w_end)) + { + z = TRANSFORM_W01(z,n,w); + w -= STEP; + z = TRANSFORM_W01(z,n,w); + w -= STEP; + } +} + +/* what is STEP? + sincos_lookup0 has sin,cos pairs for 1/4 cycle, in 1024 points + so half cycle would be 2048 points + ff_cos_16 has 8 elements corresponding to 4 cos points and 4 sin points + so each of the 4 points pairs corresponds to a 256*2-byte jump in sincos_lookup0 + 8192/16 (from "ff_cos_16") is 512 bytes. + i.e. for fft16, STEP = 8192/16 */ +#define DECL_FFT(n,n2,n4)\ +static void fft##n(FFTComplex *z) ICODE_ATTR_TREMOR_MDCT;\ +static void fft##n(FFTComplex *z)\ +{\ + fft##n2(z);\ + fft##n4(z+n4*2);\ + fft##n4(z+n4*3);\ + pass(z,8192/n,n4);\ +} + +#ifndef FFT_FFMPEG_INCL_OPTIMISED_FFT4 +static inline void fft4(FFTComplex *z) +{ + FFTSample t1, t2, t3, t4, t5, t6, t7, t8; + + BF(t3, t1, z[0].re, z[1].re); // t3=r1-r3 ; t1 = r1+r3 + BF(t8, t6, z[3].re, z[2].re); // t8=r7-r5 ; t6 = r7+r5 + + BF(z[2].re, z[0].re, t1, t6); // r5=t1-t6 ; r1 = t1+t6 + + BF(t4, t2, z[0].im, z[1].im); // t4=r2-r4 ; t2 = r2+r4 + BF(t7, t5, z[2].im, z[3].im); // t7=r6-r8 ; t5 = r6+r8 + + BF(z[3].im, z[1].im, t4, t8); // r8=t4-t8 ; r4 = t4+t8 + BF(z[3].re, z[1].re, t3, t7); // r7=t3-t7 ; r3 = t3+t7 + BF(z[2].im, z[0].im, t2, t5); // r6=t2-t5 ; r2 = t2+t5 +} +#endif + +static void fft4_dispatch(FFTComplex *z) +{ + fft4(z); +} + +#ifndef FFT_FFMPEG_INCL_OPTIMISED_FFT8 +static inline void fft8(FFTComplex *z) +{ + fft4(z); + FFTSample t1,t2,t3,t4,t7,t8; + + BF(t1, z[5].re, z[4].re, -z[5].re); + BF(t2, z[5].im, z[4].im, -z[5].im); + BF(t3, z[7].re, z[6].re, -z[7].re); + BF(t4, z[7].im, z[6].im, -z[7].im); + BF(t8, t1, t3, t1); + BF(t7, t2, t2, t4); + BF(z[4].re, z[0].re, z[0].re, t1); + BF(z[4].im, z[0].im, z[0].im, t2); + BF(z[6].re, z[2].re, z[2].re, t7); + BF(z[6].im, z[2].im, z[2].im, t8); + + z++; + TRANSFORM_EQUAL(z,2); +} +#endif + +static void fft8_dispatch(FFTComplex *z) +{ + fft8(z); +} + +#ifndef CONFIG_SMALL +static void fft16(FFTComplex *z) ICODE_ATTR_TREMOR_MDCT; +static void fft16(FFTComplex *z) +{ + fft8(z); + fft4(z+8); + fft4(z+12); + + TRANSFORM_ZERO(z,4); + z+=2; + TRANSFORM_EQUAL(z,4); + z-=1; + TRANSFORM(z,4,cPI1_8,cPI3_8); + z+=2; + TRANSFORM(z,4,cPI3_8,cPI1_8); +} +#else +DECL_FFT(16,8,4) +#endif +DECL_FFT(32,16,8) +DECL_FFT(64,32,16) +DECL_FFT(128,64,32) +DECL_FFT(256,128,64) +DECL_FFT(512,256,128) +DECL_FFT(1024,512,256) +DECL_FFT(2048,1024,512) +DECL_FFT(4096,2048,1024) + +static void (*fft_dispatch[])(FFTComplex*) = { + fft4_dispatch, fft8_dispatch, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, + fft2048, fft4096 +}; + +void ff_fft_calc_c(int nbits, FFTComplex *z) +{ + fft_dispatch[nbits-2](z); +} + +#if 0 +int main (void) +{ +#define PRECISION 16 +#define FFT_SIZE 1024 +#define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5))) +#define itofix32(x) ((x) << PRECISION) +#define fixtoi32(x) ((x) >> PRECISION) + + int j; + const long N = FFT_SIZE; + double r[FFT_SIZE] = {0.0}, i[FFT_SIZE] = {0.0}; + long n; + double t; + double amp, phase; + clock_t start, end; + double exec_time = 0; + FFTContext s; + FFTComplex z[FFT_SIZE]; + memset(z, 0, 64*sizeof(FFTComplex)); + + /* Generate saw-tooth test data */ + for (n = 0; n < FFT_SIZE; n++) + { + t = (2 * M_PI * n)/N; + /*z[n].re = 1.1 + sin( t) + + 0.5 * sin(2.0 * t) + + (1.0/3.0) * sin(3.0 * t) + + 0.25 * sin(4.0 * t) + + 0.2 * sin(5.0 * t) + + (1.0/6.0) * sin(6.0 * t) + + (1.0/7.0) * sin(7.0 * t) ;*/ + z[n].re = ftofix32(cos(2*M_PI*n/64)); + //printf("z[%d] = %f\n", n, z[n].re); + //getchar(); + } + + ff_fft_init(&s, 10, 1); +//start = clock(); +//for(n = 0; n < 1000000; n++) + ff_fft_permute_c(&s, z); + ff_fft_calc_c(&s, z); +//end = clock(); +//exec_time = (((double)end-(double)start)/CLOCKS_PER_SEC); + for(j = 0; j < FFT_SIZE; j++) + { + printf("%8.4f\n", sqrt(pow(fixtof32(z[j].re),2)+ pow(fixtof32(z[j].im), 2))); + //getchar(); + } + printf("muls = %d, adds = %d\n", muls, adds); +//printf(" Time elapsed = %f\n", exec_time); + //ff_fft_end(&s); + +} +#endif diff --git a/plugins/wma/libwma/fft-ffmpeg_arm.h b/plugins/wma/libwma/fft-ffmpeg_arm.h new file mode 100644 index 00000000..073ad8ee --- /dev/null +++ b/plugins/wma/libwma/fft-ffmpeg_arm.h @@ -0,0 +1,456 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Dave Hooper + * + * ARM optimisations for ffmpeg's fft (used in fft-ffmpeg.c) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifdef CPU_ARM + +/* Start off with optimised variants of the butterflies that work + nicely on arm */ +/* 1. where y and a share the same variable/register */ +#define BF_OPT(x,y,a,b) {\ + y = a + b;\ + x = y - (b<<1);\ +} + +/* 2. where y and b share the same variable/register */ +#define BF_OPT2(x,y,a,b) {\ + x = a - b;\ + y = x + (b<<1);\ +} + +/* 3. where y and b share the same variable/register (but y=(-b)) */ +#define BF_OPT2_REV(x,y,a,b) {\ + x = a + b;\ + y = x - (b<<1);\ +} + + +/* standard BUTTERFLIES package. Note, we actually manually inline this + in all the TRANSFORM macros below anyway */ +#define FFT_FFMPEG_INCL_OPTIMISED_BUTTERFLIES +#define BUTTERFLIES(a0,a1,a2,a3) {\ + {\ + BF_OPT(t1, t5, t5, t1);\ + BF_OPT(t6, t2, t2, t6);\ + BF_OPT(a2.re, a0.re, a0.re, t5);\ + BF_OPT(a2.im, a0.im, a0.im, t2);\ + BF_OPT(a3.re, a1.re, a1.re, t6);\ + BF_OPT(a3.im, a1.im, a1.im, t1);\ + }\ +} + +#define FFT_FFMPEG_INCL_OPTIMISED_TRANSFORM + +static inline FFTComplex* TRANSFORM( FFTComplex* z, int n, FFTSample wre, FFTSample wim ) +{ + register FFTSample t1,t2 asm("r5"),t5 asm("r6"),t6 asm("r7"),r_re asm("r8"),r_im asm("r9"); + z += n*2; /* z[o2] */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + XPROD31_R(r_re, r_im, wre, wim, t1,t2); + + z += n; /* z[o3] */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + XNPROD31_R(r_re, r_im, wre, wim, t5,t6); + + BF_OPT(t1, t5, t5, t1); + BF_OPT(t6, t2, t2, t6); + + { + register FFTSample rt0temp asm("r4"); + /*{*/ + /* BF_OPT(t1, t5, t5, t1);*/ + /* BF_OPT(t6, t2, t2, t6);*/ + /* BF_OPT(a2.re, a0.re, a0.re, t5);*/ + /* BF_OPT(a2.im, a0.im, a0.im, t2);*/ + /* BF_OPT(a3.re, a1.re, a1.re, t6);*/ + /* BF_OPT(a3.im, a1.im, a1.im, t1);*/ + /*}*/ + z -= n*3; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(rt0temp, r_re, r_re, t5); + BF_OPT(t2, r_im, r_im, t2); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory" ); + z += n; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(t5, r_re, r_re, t6); + BF_OPT(t6, r_im, r_im, t1); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* my_z[0] = rt0temp; my_z[1] = t2; */ + asm volatile( "stmia %[my_z], {%[rt0temp],%[t2]}\n\t"::[my_z] "r" (z), [rt0temp] "r" (rt0temp), [t2] "r" (t2):"memory"); + } + z += n; + + /* my_z[0] = t5; my_z[1] = t6; */ + asm volatile( "stmia %[my_z]!, {%[t5],%[t6]}\n\t":[my_z] "+r" (z) : [t5] "r" (t5), [t6] "r" (t6):"memory"); + z -= n*3; + return(z); +} + +static inline FFTComplex* TRANSFORM_W01( FFTComplex* z, int n, const FFTSample* w ) +{ + register FFTSample t1,t2 asm("r5"),t5 asm("r6"),t6 asm("r7"),r_re asm("r8"),r_im asm("r9"); + + /* load wre,wim into t5,t6 */ + asm volatile( "ldmia %[w], {%[wre], %[wim]}\n\t":[wre] "=r" (t5), [wim] "=r" (t6):[w] "r" (w)); + z += n*2; /* z[o2] -- 2n * 2 since complex numbers */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + XPROD31_R(r_re, r_im, t5 /*wre*/, t6 /*wim*/, t1,t2); + + z += n; /* z[o3] */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + XNPROD31_R(r_re, r_im, t5 /*wre*/, t6 /*wim*/, t5,t6); + + BF_OPT(t1, t5, t5, t1); + BF_OPT(t6, t2, t2, t6); + { + register FFTSample rt0temp asm("r4"); + /*{*/ + /* BF_OPT(t1, t5, t5, t1);*/ + /* BF_OPT(t6, t2, t2, t6);*/ + /* BF_OPT(a2.re, a0.re, a0.re, t5);*/ + /* BF_OPT(a2.im, a0.im, a0.im, t2);*/ + /* BF_OPT(a3.re, a1.re, a1.re, t6);*/ + /* BF_OPT(a3.im, a1.im, a1.im, t1);*/ + /*}*/ + z -= n*3; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(rt0temp, r_re, r_re, t5); + BF_OPT(t2, r_im, r_im, t2); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(t5, r_re, r_re, t6); + BF_OPT(t6, r_im, r_im, t1); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* my_z[0] = rt0temp; my_z[1] = t2; */ + asm volatile( "stmia %[my_z], {%[rt0temp],%[t2]}\n\t"::[my_z] "r" (z), [rt0temp] "r" (rt0temp), [t2] "r" (t2):"memory"); + } + z += n; + + /* my_z[0] = t5; my_z[1] = t6; */ + asm volatile( "stmia %[my_z]!, {%[t5],%[t6]}\n\t":[my_z] "+r" (z) : [t5] "r" (t5), [t6] "r" (t6):"memory"); + z -= n*3; + return(z); +} + +static inline FFTComplex* TRANSFORM_W10( FFTComplex* z, int n, const FFTSample* w ) +{ + register FFTSample t1,t2 asm("r5"),t5 asm("r6"),t6 asm("r7"),r_re asm("r8"),r_im asm("r9"); + + /* load wim,wre into t5,t6 */ + asm volatile( "ldmia %[w], {%[wim], %[wre]}\n\t":[wim] "=r" (t5), [wre] "=r" (t6):[w] "r" (w)); + z += n*2; /* z[o2] -- 2n * 2 since complex numbers */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + XPROD31_R(r_re, r_im, t6 /*wim*/, t5 /*wre*/, t1,t2); + + z += n; /* z[o3] */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + XNPROD31_R(r_re, r_im, t6 /*wim*/, t5 /*wre*/, t5,t6); + + BF_OPT(t1, t5, t5, t1); + BF_OPT(t6, t2, t2, t6); + { + register FFTSample rt0temp asm("r4"); + /*{*/ + /* BF_OPT(t1, t5, t5, t1);*/ + /* BF_OPT(t6, t2, t2, t6);*/ + /* BF_OPT(a2.re, a0.re, a0.re, t5);*/ + /* BF_OPT(a2.im, a0.im, a0.im, t2);*/ + /* BF_OPT(a3.re, a1.re, a1.re, t6);*/ + /* BF_OPT(a3.im, a1.im, a1.im, t1);*/ + /*}*/ + z -= n*3; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(rt0temp, r_re, r_re, t5); + BF_OPT(t2, r_im, r_im, t2); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(t5, r_re, r_re, t6); + BF_OPT(t6, r_im, r_im, t1); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* my_z[0] = rt0temp; my_z[1] = t2; */ + asm volatile( "stmia %[my_z], {%[rt0temp],%[t2]}\n\t"::[my_z] "r" (z), [rt0temp] "r" (rt0temp), [t2] "r" (t2):"memory"); + } + z += n; + + /* my_z[0] = t5; my_z[1] = t6; */ + asm volatile( "stmia %[my_z]!, {%[t5],%[t6]}\n\t":[my_z] "+r" (z) : [t5] "r" (t5), [t6] "r" (t6):"memory"); + z -= n*3; + return(z); +} + +static inline FFTComplex* TRANSFORM_EQUAL( FFTComplex* z, int n ) +{ + register FFTSample t1,t2 asm("r5"),t5 asm("r6"),t6 asm("r7"),r_re asm("r8"),r_im asm("r9"); + + z += n*2; /* z[o2] -- 2n * 2 since complex numbers */ + asm volatile( "ldmia %[my_z], {%[t5],%[t6]}\n\t":[t5] "=r" (t5), [t6] "=r" (t6):[my_z] "r" (z)); + z += n; /* z[o3] */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + +/**/ +/*t2 = MULT32(cPI2_8, t5);*/ +/*t1 = MULT31(cPI2_8, t6);*/ +/*t6 = MULT31(cPI2_8, r_re);*/ +/*t5 = MULT32(cPI2_8, r_im);*/ + +/*t1 = ( t1 + (t2<<1) );*/ +/*t2 = ( t1 - (t2<<2) );*/ +/*t6 = ( t6 + (t5<<1) );*/ +/*t5 = ( t6 - (t5<<2) );*/ +/**/ + t2 = MULT31(cPI2_8, t5); + t6 = MULT31(cPI2_8, t6); + r_re = MULT31(cPI2_8, r_re); + t5 = MULT31(cPI2_8, r_im); + + t1 = ( t6 + t2 ); + t2 = ( t6 - t2 ); + t6 = ( r_re + t5 ); + t5 = ( r_re - t5 ); + + BF_OPT(t1, t5, t5, t1); + BF_OPT(t6, t2, t2, t6); + { + register FFTSample rt0temp asm("r4"); + /*{*/ + /* BF_OPT(t1, t5, t5, t1);*/ + /* BF_OPT(t6, t2, t2, t6);*/ + /* BF_OPT(a2.re, a0.re, a0.re, t5);*/ + /* BF_OPT(a2.im, a0.im, a0.im, t2);*/ + /* BF_OPT(a3.re, a1.re, a1.re, t6);*/ + /* BF_OPT(a3.im, a1.im, a1.im, t1);*/ + /*}*/ + z -= n*3; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(rt0temp, r_re, r_re, t5); + BF_OPT(t2, r_im, r_im, t2); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(t5, r_re, r_re, t6); + BF_OPT(t6, r_im, r_im, t1); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* my_z[0] = rt0temp; my_z[1] = t2; */ + asm volatile( "stmia %[my_z], {%[rt0temp],%[t2]}\n\t"::[my_z] "r" (z), [rt0temp] "r" (rt0temp), [t2] "r" (t2):"memory"); + } + z += n; + + /* my_z[0] = t5; my_z[1] = t6; */ + asm volatile( "stmia %[my_z]!, {%[t5],%[t6]}\n\t":[my_z] "+r" (z) : [t5] "r" (t5), [t6] "r" (t6):"memory"); + z -= n*3; + return(z); +} + +static inline FFTComplex* TRANSFORM_ZERO( FFTComplex* z, int n ) +{ + register FFTSample t1,t2 asm("r5"),t5 asm("r6"),t6 asm("r7"), r_re asm("r8"), r_im asm("r9"); + + z += n*2; /* z[o2] -- 2n * 2 since complex numbers */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + z += n; /* z[o3] */ + asm volatile( "ldmia %[my_z], {%[t5],%[t6]}\n\t":[t5] "=r" (t5), [t6] "=r" (t6):[my_z] "r" (z)); + + BF_OPT(t1, t5, t5, r_re); + BF_OPT(t6, t2, r_im, t6); + { + register FFTSample rt0temp asm("r4"); + /*{*/ + /* BF_OPT(t1, t5, t5, t1);*/ + /* BF_OPT(t6, t2, t2, t6);*/ + /* BF_OPT(a2.re, a0.re, a0.re, t5);*/ + /* BF_OPT(a2.im, a0.im, a0.im, t2);*/ + /* BF_OPT(a3.re, a1.re, a1.re, t6);*/ + /* BF_OPT(a3.im, a1.im, a1.im, t1);*/ + /*}*/ + z -= n*3; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(rt0temp, r_re, r_re, t5); + BF_OPT(t2, r_im, r_im, t2); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* r_re = my_z[0]; r_im = my_z[1]; */ + asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z)); + BF_OPT(t5, r_re, r_re, t6); + BF_OPT(t6, r_im, r_im, t1); + /* my_z[0] = r_re; my_z[1] = r_im; */ + asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im):"memory"); + z += n; + /* my_z[0] = rt0temp; my_z[1] = t2; */ + asm volatile( "stmia %[my_z], {%[rt0temp],%[t2]}\n\t"::[my_z] "r" (z), [rt0temp] "r" (rt0temp), [t2] "r" (t2):"memory"); + } + z += n; + + /* my_z[0] = t5; my_z[1] = t6; */ + asm volatile( "stmia %[my_z]!, {%[t5],%[t6]}\n\t":[my_z] "+r" (z) : [t5] "r" (t5), [t6] "r" (t6):"memory"); + z -= n*3; + return(z); +} + +#define FFT_FFMPEG_INCL_OPTIMISED_FFT4 +static inline FFTComplex* fft4(FFTComplex * z) +{ + FFTSample temp; + + /* input[0..7] -> output[0..7] */ + /* load r1=z[0],r2=z[1],...,r8=z[7] */ + asm volatile( + "ldmia %[z], {r1-r8}\n\t" + "add r1,r1,r3\n\t" /* r1 :=t1 */ + "sub r3,r1,r3, lsl #1\n\t" /* r3 :=t3 */ + "sub r7,r7,r5\n\t" /* r10:=t8 */ + "add r5,r7,r5, lsl #1\n\t" /* r5 :=t6 */ + + "add r1,r1,r5\n\t" /* r1 = o[0] */ + "sub r5,r1,r5, lsl #1\n\t" /* r5 = o[4] */ + + "add r2,r2,r4\n\t" /* r2 :=t2 */ + "sub r4,r2,r4, lsl #1\n\t" /* r9 :=t4 */ + + "add %[temp],r6,r8\n\t" /* r10:=t5 */ + "sub r6,r6,r8\n\t" /* r6 :=t7 */ + + "sub r8,r4,r7\n\t" /* r8 = o[7]*/ + "add r4,r4,r7\n\t" /* r4 = o[3]*/ + "sub r7,r3,r6\n\t" /* r7 = o[6]*/ + "add r3,r3,r6\n\t" /* r3 = o[2]*/ + "sub r6,r2,%[temp]\n\t" /* r6 = o[5]*/ + "add r2,r2,%[temp]\n\t" /* r2 = o[1]*/ + + "stmia %[z]!, {r1-r8}\n\t" + : /* outputs */ [z] "+r" (z), [temp] "=r" (temp) + : /* inputs */ + : /* clobbers */ + "r1","r2","r3","r4","r5","r6","r7","r8","memory" + ); + return z; +} + +#define FFT_FFMPEG_INCL_OPTIMISED_FFT8 + /* The chunk of asm below is equivalent to the following: + + // first load in z[4].re thru z[7].im into local registers + // ... + BF_OPT2_REV(z[4].re, z[5].re, z[4].re, z[5].re); // x=a+b; y=x-(b<<1) + BF_OPT2_REV(z[4].im, z[5].im, z[4].im, z[5].im); + BF_REV (temp, z[7].re, z[6].re, z[7].re); // x=a+b; y=a-b; + BF_REV (z[6].re, z[7].im, z[6].im, z[7].im); + // save z[7].re and z[7].im as those are complete now + // z[5].re and z[5].im are also complete now but save these later on + + BF(z[6].im, z[4].re, temp, z[4].re); // x=a-b; y=a+b + BF_OPT(z[6].re, z[4].im, z[4].im, z[6].re); // y=a+b; x=y-(b<<1) + // now load z[2].re and z[2].im + // ... + BF_OPT(z[6].re, z[2].re, z[2].re, z[6].re); // y=a+b; x=y-(b<<1) + BF_OPT(z[6].im, z[2].im, z[2].im, z[6].im); // y=a+b; x=y-(b<<1) + // Now save z[6].re and z[6].im, along with z[5].re and z[5].im + // for efficiency. Also save z[2].re and z[2].im. + // Now load z[0].re and z[0].im + // ... + + BF_OPT(z[4].re, z[0].re, z[0].re, z[4].re); // y=a+b; x=y-(b<<1) + BF_OPT(z[4].im, z[0].im, z[0].im, z[4].im); // y=a+b; x=y-(b<<1) + // Finally save out z[4].re, z[4].im, z[0].re and z[0].im + // ... + */ +static inline void fft8(FFTComplex * z) +{ + FFTComplex* m4 = fft4(z); + { + /* note that we increment z_ptr on the final stmia, which + leaves z_ptr pointing to z[1].re ready for the Transform step */ + + register FFTSample temp; + + asm volatile( + /* read in z[4].re thru z[7].im */ + "ldmia %[z4_ptr]!, {r1-r8}\n\t" + /* (now points one word past &z[7].im) */ + "add r1,r1,r3\n\t" + "sub r3,r1,r3,lsl #1\n\t" + "add r2,r2,r4\n\t" + "sub r4,r2,r4,lsl #1\n\t" + "add %[temp],r5,r7\n\t" + "sub r7,r5,r7\n\t" + "add r5,r6,r8\n\t" + "sub r8,r6,r8\n\t" + + "stmdb %[z4_ptr]!, {r7,r8}\n\t" /* write z[7].re,z[7].im straight away */ + /* Note, registers r7 & r8 now free */ + + "sub r6,%[temp],r1\n\t" + "add r1,%[temp],r1\n\t" + "add r2,r2,r5\n\t" + "sub r5,r2,r5,lsl #1\n\t" + "add %[temp], %[z_ptr], #16\n\t" /* point to &z[2].re */ + "ldmia %[temp],{r7,r8}\n\t" /* load z[2].re and z[2].im */ + "add r7,r7,r5\n\t" + "sub r5,r7,r5,lsl #1\n\t" + "add r8,r8,r6\n\t" + "sub r6,r8,r6,lsl #1\n\t" + + /* write out z[5].re, z[5].im, z[6].re, z[6].im in one go*/ + "stmdb %[z4_ptr]!, {r3-r6}\n\t" + "stmia %[temp],{r7,r8}\n\t" /* write out z[2].re, z[2].im */ + "ldmia %[z_ptr],{r7,r8}\n\t" /* load r[0].re, r[0].im */ + + "add r7,r7,r1\n\t" + "sub r1,r7,r1,lsl #1\n\t" + "add r8,r8,r2\n\t" + "sub r2,r8,r2,lsl #1\n\t" + + "stmia %[z_ptr]!,{r7,r8}\n\t" /* write out z[0].re, z[0].im */ + "stmdb %[z4_ptr], {r1,r2}\n\t" /* write out z[4].re, z[4].im */ + : [z4_ptr] "+r" (m4), [temp] "=r" (temp), [z_ptr] "+r" (z) + : + : "r1","r2","r3","r4","r5","r6","r7","r8","memory" + ); + } + + TRANSFORM_EQUAL(z,2); +} + +#endif // CPU_ARM diff --git a/plugins/wma/libwma/fft.h b/plugins/wma/libwma/fft.h new file mode 100644 index 00000000..302a3b39 --- /dev/null +++ b/plugins/wma/libwma/fft.h @@ -0,0 +1,64 @@ +/* + * WMA compatible decoder + * Copyright (c) 2002 The FFmpeg Project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef CODECLIB_FFT_H_INCLUDED +#define CODECLIB_FFT_H_INCLUDED + +#include <inttypes.h> +typedef int32_t fixed32; +typedef int64_t fixed64; + +#define FFT_FIXED + +#ifdef FFT_FIXED +typedef fixed32 FFTSample; +#else /* FFT_FIXED */ +typedef float FFTSample; +#endif /* FFT_FIXED */ + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext { + int nbits; + int inverse; + uint16_t *revtab; + int mdct_size; /* size of MDCT (i.e. number of input data * 2) */ + int mdct_bits; /* n = 2^nbits */ + /* pre/post rotation tables */ + FFTSample *tcos; + FFTSample *tsin; + void (*fft_permute)(struct FFTContext *s, FFTComplex *z); + void (*fft_calc)(struct FFTContext *s, FFTComplex *z); + void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); + void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input); + void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input); + int split_radix; + int permutation; +#define FF_MDCT_PERM_NONE 0 +#define FF_MDCT_PERM_INTERLEAVE 1 +} FFTContext; + +// internal api (fft<->mdct) +//int fft_calc_unscaled(FFTContext *s, FFTComplex *z); +//void ff_fft_permute_c(FFTContext *s, FFTComplex *z); // internal only? +void ff_fft_calc_c(int nbits, FFTComplex *z); + +#endif // CODECLIB_FFT_H_INCLUDED + diff --git a/plugins/wma/libwma/mdct.c b/plugins/wma/libwma/mdct.c new file mode 100644 index 00000000..460bfea5 --- /dev/null +++ b/plugins/wma/libwma/mdct.c @@ -0,0 +1,653 @@ +/* + * Fixed Point IMDCT + * Copyright (c) 2002 The FFmpeg Project. + * Copyright (c) 2010 Dave Hooper, Mohamed Tarek, Michael Giacomelli + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "mdct.h" +#include "codeclib_misc.h" +#include "mdct_lookup.h" + +/* Use to give gcc hints on which branch is most likely taken */ +#if defined(__GNUC__) && __GNUC__ >= 3 +#define LIKELY(x) __builtin_expect(!!(x), 1) +#define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +#ifndef ICODE_ATTR_TREMOR_MDCT +#define ICODE_ATTR_TREMOR_MDCT ICODE_ATTR +#endif + +/** + * Compute the middle half of the inverse MDCT of size N = 2^nbits + * thus excluding the parts that can be derived by symmetry + * @param output N/2 samples + * @param input N/2 samples + * + * NOTE - CANNOT CURRENTLY OPERATE IN PLACE (input and output must + * not overlap or intersect at all) + */ +#define ICODE_ATTR +void ff_imdct_half(unsigned int nbits, fixed32 *output, const fixed32 *input) ICODE_ATTR_TREMOR_MDCT; +void ff_imdct_half(unsigned int nbits, fixed32 *output, const fixed32 *input) +{ + int n8, n4, n2, n, j; + const fixed32 *in1, *in2; + (void)j; + n = 1 << nbits; + + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + + FFTComplex *z = (FFTComplex *)output; + + /* pre rotation */ + in1 = input; + in2 = input + n2 - 1; + + /* revtab comes from the fft; revtab table is sized for N=4096 size fft = 2^12. + The fft is size N/4 so s->nbits-2, so our shift needs to be (12-(nbits-2)) */ + const int revtab_shift = (14- nbits); + + /* bitreverse reorder the input and rotate; result here is in OUTPUT ... */ + /* (note that when using the current split radix, the bitreverse ordering is + complex, meaning that this reordering cannot easily be done in-place) */ + /* Using the following pdf, you can see that it is possible to rearrange + the 'classic' pre/post rotate with an alternative one that enables + us to use fewer distinct twiddle factors. + http://www.eurasip.org/Proceedings/Eusipco/Eusipco2006/papers/1568980508.pdf + + For prerotation, the factors are just sin,cos(2PI*i/N) + For postrotation, the factors are sin,cos(2PI*(i+1/4)/N) + + Therefore, prerotation can immediately reuse the same twiddles as fft + (for postrotation it's still a bit complex, we reuse the fft trig tables + where we can, or a special table for N=2048, or interpolate between + trig tables for N>2048) + */ + const int32_t *T = sincos_lookup0; + const int step = 2<<(12-nbits); + const uint16_t * p_revtab=revtab; + { + const uint16_t * const p_revtab_end = p_revtab + n8; +#ifdef CPU_COLDFIRE + asm volatile ("move.l (%[in2]), %%d0\n\t" + "move.l (%[in1]), %%d1\n\t" + "bra.s 1f\n\t" + "0:\n\t" + "movem.l (%[T]), %%d2-%%d3\n\t" + + "addq.l #8, %[in1]\n\t" + "subq.l #8, %[in2]\n\t" + + "lea (%[step]*4, %[T]), %[T]\n\t" + + "mac.l %%d0, %%d3, (%[T]), %%d4, %%acc0;" + "msac.l %%d1, %%d2, (4, %[T]), %%d5, %%acc0;" + "mac.l %%d1, %%d3, (%[in1]), %%d1, %%acc1;" + "mac.l %%d0, %%d2, (%[in2]), %%d0, %%acc1;" + + "addq.l #8, %[in1]\n\t" + "subq.l #8, %[in2]\n\t" + + "mac.l %%d0, %%d5, %%acc2;" + "msac.l %%d1, %%d4, (%[p_revtab])+, %%d2, %%acc2;" + "mac.l %%d1, %%d5, (%[in1]), %%d1, %%acc3;" + "mac.l %%d0, %%d4, (%[in2]), %%d0, %%acc3;" + + "clr.l %%d3\n\t" + "move.w %%d2, %%d3\n\t" + "eor.l %%d3, %%d2\n\t" + "swap %%d2\n\t" + "lsr.l %[revtab_shift], %%d2\n\t" + + "movclr.l %%acc0, %%d4;" + "movclr.l %%acc1, %%d5;" + "lsl.l #3, %%d2\n\t" + "lea (%%d2, %[z]), %%a1\n\t" + "movem.l %%d4-%%d5, (%%a1)\n\t" + + "lsr.l %[revtab_shift], %%d3\n\t" + + "movclr.l %%acc2, %%d4;" + "movclr.l %%acc3, %%d5;" + "lsl.l #3, %%d3\n\t" + "lea (%%d3, %[z]), %%a1\n\t" + "movem.l %%d4-%%d5, (%%a1)\n\t" + + "lea (%[step]*4, %[T]), %[T]\n\t" + + "1:\n\t" + "cmp.l %[p_revtab_end], %[p_revtab]\n\t" + "bcs.s 0b\n\t" + : [in1] "+a" (in1), [in2] "+a" (in2), [T] "+a" (T), + [p_revtab] "+a" (p_revtab) + : [z] "a" (z), [step] "d" (step), [revtab_shift] "d" (revtab_shift), + [p_revtab_end] "r" (p_revtab_end) + : "d0", "d1", "d2", "d3", "d4", "d5", "a1", "cc", "memory"); +#else + while(LIKELY(p_revtab < p_revtab_end)) + { + j = (*p_revtab)>>revtab_shift; + XNPROD31(*in2, *in1, T[1], T[0], &z[j].re, &z[j].im ); + T += step; + in1 += 2; + in2 -= 2; + p_revtab++; + j = (*p_revtab)>>revtab_shift; + XNPROD31(*in2, *in1, T[1], T[0], &z[j].re, &z[j].im ); + T += step; + in1 += 2; + in2 -= 2; + p_revtab++; + } +#endif + } + { + const uint16_t * const p_revtab_end = p_revtab + n8; +#ifdef CPU_COLDFIRE + asm volatile ("move.l (%[in2]), %%d0\n\t" + "move.l (%[in1]), %%d1\n\t" + "bra.s 1f\n\t" + "0:\n\t" + "movem.l (%[T]), %%d2-%%d3\n\t" + + "addq.l #8, %[in1]\n\t" + "subq.l #8, %[in2]\n\t" + + "lea (%[step]*4, %[T]), %[T]\n\t" + + "mac.l %%d0, %%d2, (%[T]), %%d4, %%acc0;" + "msac.l %%d1, %%d3, (4, %[T]), %%d5, %%acc0;" + "mac.l %%d1, %%d2, (%[in1]), %%d1, %%acc1;" + "mac.l %%d0, %%d3, (%[in2]), %%d0, %%acc1;" + + "addq.l #8, %[in1]\n\t" + "subq.l #8, %[in2]\n\t" + + "mac.l %%d0, %%d4, %%acc2;" + "msac.l %%d1, %%d5, (%[p_revtab])+, %%d2, %%acc2;" + "mac.l %%d1, %%d4, (%[in1]), %%d1, %%acc3;" + "mac.l %%d0, %%d5, (%[in2]), %%d0, %%acc3;" + + "clr.l %%d3\n\t" + "move.w %%d2, %%d3\n\t" + "eor.l %%d3, %%d2\n\t" + "swap %%d2\n\t" + "lsr.l %[revtab_shift], %%d2\n\t" + + "movclr.l %%acc0, %%d4;" + "movclr.l %%acc1, %%d5;" + "lsl.l #3, %%d2\n\t" + "lea (%%d2, %[z]), %%a1\n\t" + "movem.l %%d4-%%d5, (%%a1)\n\t" + + "lsr.l %[revtab_shift], %%d3\n\t" + + "movclr.l %%acc2, %%d4;" + "movclr.l %%acc3, %%d5;" + "lsl.l #3, %%d3\n\t" + "lea (%%d3, %[z]), %%a1\n\t" + "movem.l %%d4-%%d5, (%%a1)\n\t" + + "lea (%[step]*4, %[T]), %[T]\n\t" + + "1:\n\t" + "cmp.l %[p_revtab_end], %[p_revtab]\n\t" + "bcs.s 0b\n\t" + : [in1] "+a" (in1), [in2] "+a" (in2), [T] "+a" (T), + [p_revtab] "+a" (p_revtab) + : [z] "a" (z), [step] "d" (-step), [revtab_shift] "d" (revtab_shift), + [p_revtab_end] "r" (p_revtab_end) + : "d0", "d1", "d2", "d3", "d4", "d5", "a1", "cc", "memory"); +#else + while(LIKELY(p_revtab < p_revtab_end)) + { + j = (*p_revtab)>>revtab_shift; + XNPROD31(*in2, *in1, T[0], T[1], &z[j].re, &z[j].im); + T -= step; + in1 += 2; + in2 -= 2; + p_revtab++; + j = (*p_revtab)>>revtab_shift; + XNPROD31(*in2, *in1, T[0], T[1], &z[j].re, &z[j].im); + T -= step; + in1 += 2; + in2 -= 2; + p_revtab++; + } +#endif + } + + + /* ... and so fft runs in OUTPUT buffer */ + ff_fft_calc_c(nbits-2, z); + + /* post rotation + reordering. now keeps the result within the OUTPUT buffer */ + switch( nbits ) + { + default: + { + fixed32 * z1 = (fixed32 *)(&z[0]); + int magic_step = step>>2; + int newstep; + if(n<=1024) + { + T = sincos_lookup0 + magic_step; + newstep = step>>1; + } + else + { + T = sincos_lookup1; + newstep = 2; + } + +#ifdef CPU_COLDFIRE + fixed32 * z2 = (fixed32 *)(&z[n4]); + int c = n4; + if (newstep == 2) + { + asm volatile ("movem.l (%[z1]), %%d0-%%d1\n\t" + "addq.l #8, %[z1]\n\t" + "movem.l (%[T]), %%d2-%%d3\n\t" + "addq.l #8, %[T]\n\t" + "bra.s 1f\n\t" + "0:\n\t" + "msac.l %%d1, %%d2, (%[T])+, %%a3, %%acc0\n\t" + "mac.l %%d0, %%d3, (%[T])+, %%a4, %%acc0\n\t" + + "msac.l %%d1, %%d3, -(%[z2]), %%d1, %%acc1\n\t" + "msac.l %%d0, %%d2, -(%[z2]), %%d0, %%acc1\n\t" + + "msac.l %%d1, %%a4, (%[T])+, %%d2, %%acc2\n\t" + "mac.l %%d0, %%a3, (%[T])+, %%d3, %%acc2\n\t" + "msac.l %%d0, %%a4, (%[z1])+, %%d0, %%acc3\n\t" + "msac.l %%d1, %%a3, (%[z1])+, %%d1, %%acc3\n\t" + + "movclr.l %%acc0, %%a3\n\t" + "movclr.l %%acc3, %%a4\n\t" + "movem.l %%a3-%%a4, (-16, %[z1])\n\t" + + "movclr.l %%acc1, %%a4\n\t" + "movclr.l %%acc2, %%a3\n\t" + "movem.l %%a3-%%a4, (%[z2])\n\t" + + "subq.l #2, %[n]\n\t" + "1:\n\t" + "bhi.s 0b\n\t" + : [z1] "+a" (z1), [z2] "+a" (z2), [T] "+a" (T), [n] "+d" (c) + : + : "d0", "d1", "d2", "d3", "a3", "a4", "cc", "memory"); + } + else + { + asm volatile ("movem.l (%[z1]), %%d0-%%d1\n\t" + "addq.l #8, %[z1]\n\t" + "movem.l (%[T]), %%d2-%%d3\n\t" + "lea (%[newstep]*4, %[T]), %[T]\n\t" + "bra.s 1f\n\t" + "0:\n\t" + "msac.l %%d1, %%d2, (%[T]), %%a3, %%acc0\n\t" + "mac.l %%d0, %%d3, (4, %[T]), %%a4, %%acc0\n\t" + "msac.l %%d1, %%d3, -(%[z2]), %%d1, %%acc1\n\t" + "msac.l %%d0, %%d2, -(%[z2]), %%d0, %%acc1\n\t" + + "lea (%[newstep]*4, %[T]), %[T]\n\t" + "msac.l %%d1, %%a4, (%[T]), %%d2, %%acc2\n\t" + "mac.l %%d0, %%a3, (4, %[T]), %%d3, %%acc2\n\t" + "msac.l %%d0, %%a4, (%[z1])+, %%d0, %%acc3\n\t" + "msac.l %%d1, %%a3, (%[z1])+, %%d1, %%acc3\n\t" + + "lea (%[newstep]*4, %[T]), %[T]\n\t" + + "movclr.l %%acc0, %%a3\n\t" + "movclr.l %%acc3, %%a4\n\t" + "movem.l %%a3-%%a4, (-16, %[z1])\n\t" + + "movclr.l %%acc1, %%a4\n\t" + "movclr.l %%acc2, %%a3\n\t" + "movem.l %%a3-%%a4, (%[z2])\n\t" + + "subq.l #2, %[n]\n\t" + "1:\n\t" + "bhi.s 0b\n\t" + : [z1] "+a" (z1), [z2] "+a" (z2), [T] "+a" (T), [n] "+d" (c) + : [newstep] "d" (newstep) + : "d0", "d1", "d2", "d3", "a3", "a4", "cc", "memory"); + } +#else + fixed32 * z2 = (fixed32 *)(&z[n4-1]); + while(z1<z2) + { + fixed32 r0,i0,r1,i1; + XNPROD31_R(z1[1], z1[0], T[0], T[1], r0, i1 ); T+=newstep; + XNPROD31_R(z2[1], z2[0], T[1], T[0], r1, i0 ); T+=newstep; + z1[0] = -r0; + z1[1] = -i0; + z2[0] = -r1; + z2[1] = -i1; + z1+=2; + z2-=2; + } +#endif + break; + } + + case 12: /* n=4096 */ + { + /* linear interpolation (50:50) between sincos_lookup0 and sincos_lookup1 */ + const int32_t * V = sincos_lookup1; + T = sincos_lookup0; + int32_t t0,t1,v0,v1; + fixed32 * z1 = (fixed32 *)(&z[0]); + fixed32 * z2 = (fixed32 *)(&z[n4-1]); + + t0 = T[0]>>1; t1=T[1]>>1; + + while(z1<z2) + { + fixed32 r0,i0,r1,i1; + t0 += (v0 = (V[0]>>1)); + t1 += (v1 = (V[1]>>1)); + XNPROD31_R(z1[1], z1[0], t0, t1, r0, i1 ); + T+=2; + v0 += (t0 = (T[0]>>1)); + v1 += (t1 = (T[1]>>1)); + XNPROD31_R(z2[1], z2[0], v1, v0, r1, i0 ); + z1[0] = -r0; + z1[1] = -i0; + z2[0] = -r1; + z2[1] = -i1; + z1+=2; + z2-=2; + V+=2; + } + + break; + } + + case 13: /* n = 8192 */ + { + /* weight linear interpolation between sincos_lookup0 and sincos_lookup1 + specifically: 25:75 for first twiddle and 75:25 for second twiddle */ + const int32_t * V = sincos_lookup1; + T = sincos_lookup0; + int32_t t0,t1,v0,v1,q0,q1; + fixed32 * z1 = (fixed32 *)(&z[0]); + fixed32 * z2 = (fixed32 *)(&z[n4-1]); + + t0 = T[0]; t1=T[1]; + + while(z1<z2) + { + fixed32 r0,i0,r1,i1; + v0 = V[0]; v1 = V[1]; + t0 += (q0 = (v0-t0)>>1); + t1 += (q1 = (v1-t1)>>1); + XNPROD31_R(z1[1], z1[0], t0, t1, r0, i1 ); + t0 = v0-q0; + t1 = v1-q1; + XNPROD31_R(z2[1], z2[0], t1, t0, r1, i0 ); + z1[0] = -r0; + z1[1] = -i0; + z2[0] = -r1; + z2[1] = -i1; + z1+=2; + z2-=2; + T+=2; + + t0 = T[0]; t1 = T[1]; + v0 += (q0 = (t0-v0)>>1); + v1 += (q1 = (t1-v1)>>1); + XNPROD31_R(z1[1], z1[0], v0, v1, r0, i1 ); + v0 = t0-q0; + v1 = t1-q1; + XNPROD31_R(z2[1], z2[0], v1, v0, r1, i0 ); + z1[0] = -r0; + z1[1] = -i0; + z2[0] = -r1; + z2[1] = -i1; + z1+=2; + z2-=2; + V+=2; + } + + break; + } + } +} + +/** + * Compute inverse MDCT of size N = 2^nbits + * @param output N samples + * @param input N/2 samples + * "In-place" processing can be achieved provided that: + * [0 .. N/2-1 | N/2 .. N-1 ] + * <----input----> + * <-----------output-----------> + * + * The result of ff_imdct_half is to put the 'half' imdct here + * + * N/2 N-1 + * <--half imdct--> + * + * We want it here for the full imdct: + * N/4 3N/4-1 + * <--------------> + * + * In addition we need to apply two symmetries to get the full imdct: + * + * <AAAAAA> <DDDDDD> + * <BBBBBB><CCCCCC> + * + * D is a reflection of C + * A is a reflection of B (but with sign flipped) + * + * We process the symmetries at the same time as we 'move' the half imdct + * from [N/2,N-1] to [N/4,3N/4-1] + * + * TODO: find a way to make ff_imdct_half put the result in [N/4..3N/4-1] + * This would require being able to use revtab 'inplace' (since the input + * and output of imdct_half would then overlap somewhat) + */ +void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input) ICODE_ATTR_TREMOR_MDCT; +#ifndef CPU_ARM +void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input) +{ + const int n = (1<<nbits); + const int n2 = (n>>1); + const int n4 = (n>>2); + + /* tell imdct_half to put the output in [N/2..3N/4-1] i.e. output+n2 */ + ff_imdct_half(nbits,output+n2,input); + + fixed32 * in_r, * in_r2, * out_r, * out_r2; + + /* Copy BBBB to AAAA, reflected and sign-flipped. + Also copy BBBB to its correct destination (from [N/2..3N/4-1] to [N/4..N/2-1]) */ + out_r = output; + out_r2 = output+n2-8; + in_r = output+n2+n4-8; + while(out_r<out_r2) + { +#if defined CPU_COLDFIRE + asm volatile( + "movem.l (%[in_r]), %%d0-%%d7\n\t" + "movem.l %%d0-%%d7, (%[out_r2])\n\t" + "neg.l %%d7\n\t" + "move.l %%d7, (%[out_r])+\n\t" + "neg.l %%d6\n\t" + "move.l %%d6, (%[out_r])+\n\t" + "neg.l %%d5\n\t" + "move.l %%d5, (%[out_r])+\n\t" + "neg.l %%d4\n\t" + "move.l %%d4, (%[out_r])+\n\t" + "neg.l %%d3\n\t" + "move.l %%d3, (%[out_r])+\n\t" + "neg.l %%d2\n\t" + "move.l %%d2, (%[out_r])+\n\t" + "lea.l (-8*4, %[in_r]), %[in_r]\n\t" + "neg.l %%d1\n\t" + "move.l %%d1, (%[out_r])+\n\t" + "lea.l (-8*4, %[out_r2]), %[out_r2]\n\t" + "neg.l %%d0\n\t" + "move.l %%d0, (%[out_r])+\n\t" + : [in_r] "+a" (in_r), [out_r] "+a" (out_r), [out_r2] "+a" (out_r2) + : + : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory" ); +#else + out_r[0] = -(out_r2[7] = in_r[7]); + out_r[1] = -(out_r2[6] = in_r[6]); + out_r[2] = -(out_r2[5] = in_r[5]); + out_r[3] = -(out_r2[4] = in_r[4]); + out_r[4] = -(out_r2[3] = in_r[3]); + out_r[5] = -(out_r2[2] = in_r[2]); + out_r[6] = -(out_r2[1] = in_r[1]); + out_r[7] = -(out_r2[0] = in_r[0]); + in_r -= 8; + out_r += 8; + out_r2 -= 8; +#endif + } + in_r = output + n2+n4; + in_r2 = output + n-4; + out_r = output + n2; + out_r2 = output + n2 + n4 - 4; + while(in_r<in_r2) + { +#if defined CPU_COLDFIRE + asm volatile( + "movem.l (%[in_r]), %%d0-%%d3\n\t" + "movem.l %%d0-%%d3, (%[out_r])\n\t" + "movem.l (%[in_r2]), %%d4-%%d7\n\t" + "movem.l %%d4-%%d7, (%[out_r2])\n\t" + "move.l %%d0, %%a3\n\t" + "move.l %%d3, %%d0\n\t" + "move.l %%d1, %%d3\n\t" + "movem.l %%d0/%%d2-%%d3/%%a3, (%[in_r2])\n\t" + "move.l %%d7, %%d1\n\t" + "move.l %%d6, %%d2\n\t" + "move.l %%d5, %%d3\n\t" + "movem.l %%d1-%%d4, (%[in_r])\n\t" + "lea.l (4*4, %[in_r]), %[in_r]\n\t" + "lea.l (-4*4, %[in_r2]), %[in_r2]\n\t" + "lea.l (4*4, %[out_r]), %[out_r]\n\t" + "lea.l (-4*4, %[out_r2]), %[out_r2]\n\t" + : [in_r] "+a" (in_r), [in_r2] "+a" (in_r2), + [out_r] "+a" (out_r), [out_r2] "+a" (out_r2) + : + : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a3", "memory", "cc" ); +#else + register fixed32 t0,t1,t2,t3; + register fixed32 s0,s1,s2,s3; + + /* Copy and reflect CCCC to DDDD. Because CCCC is already where + we actually want to put DDDD this is a bit complicated. + * So simultaneously do the following things: + * 1. copy range from [n2+n4 .. n-1] to range[n2 .. n2+n4-1] + * 2. reflect range from [n2+n4 .. n-1] inplace + * + * [ | ] + * ^a -> <- ^b ^c -> <- ^d + * + * #1: copy from ^c to ^a + * #2: copy from ^d to ^b + * #3: swap ^c and ^d in place + */ + /* #1 pt1 : load 4 words from ^c. */ + t0=in_r[0]; t1=in_r[1]; t2=in_r[2]; t3=in_r[3]; + /* #1 pt2 : write to ^a */ + out_r[0]=t0;out_r[1]=t1;out_r[2]=t2;out_r[3]=t3; + /* #2 pt1 : load 4 words from ^d */ + s0=in_r2[0];s1=in_r2[1];s2=in_r2[2];s3=in_r2[3]; + /* #2 pt2 : write to ^b */ + out_r2[0]=s0;out_r2[1]=s1;out_r2[2]=s2;out_r2[3]=s3; + /* #3 pt1 : write words from #2 to ^c */ + in_r[0]=s3;in_r[1]=s2;in_r[2]=s1;in_r[3]=s0; + /* #3 pt2 : write words from #1 to ^d */ + in_r2[0]=t3;in_r2[1]=t2;in_r2[2]=t1;in_r2[3]=t0; + + in_r += 4; + in_r2 -= 4; + out_r += 4; + out_r2 -= 4; +#endif + } +} +#else +/* Follows the same structure as the canonical version above */ +void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input) +{ + const int n = (1<<nbits); + const int n2 = (n>>1); + const int n4 = (n>>2); + + ff_imdct_half(nbits,output+n2,input); + + fixed32 * in_r, * in_r2, * out_r, * out_r2; + + out_r = output; + out_r2 = output+n2; + in_r = output+n2+n4; + while(out_r<out_r2) + { + asm volatile( + "ldmdb %[in_r]!, {r0-r7}\n\t" + "stmdb %[out_r2]!, {r0-r7}\n\t" + "rsb r8,r0,#0\n\t" + "rsb r0,r7,#0\n\t" + "rsb r7,r1,#0\n\t" + "rsb r1,r6,#0\n\t" + "rsb r6,r2,#0\n\t" + "rsb r2,r5,#0\n\t" + "rsb r5,r3,#0\n\t" + "rsb r3,r4,#0\n\t" + "stmia %[out_r]!, {r0-r3,r5-r8}\n\t" + : [in_r] "+r" (in_r), [out_r] "+r" (out_r), [out_r2] "+r" (out_r2) + : + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "memory" ); + } + in_r = output + n2+n4; + in_r2 = output + n; + out_r = output + n2; + out_r2 = output + n2 + n4; + while(in_r<in_r2) + { + asm volatile( + "ldmia %[in_r], {r0-r3}\n\t" + "stmia %[out_r]!, {r0-r3}\n\t" + "ldmdb %[in_r2], {r5-r8}\n\t" + "stmdb %[out_r2]!, {r5-r8}\n\t" + "mov r4,r0\n\t" + "mov r0,r3\n\t" + "mov r3,r1\n\t" + "stmdb %[in_r2]!, {r0,r2,r3,r4}\n\t" + "mov r4,r8\n\t" + "mov r8,r5\n\t" + "mov r5,r7\n\t" + "stmia %[in_r]!, {r4,r5,r6,r8}\n\t" + : + [in_r] "+r" (in_r), [in_r2] "+r" (in_r2), [out_r] "+r" (out_r), [out_r2] "+r" (out_r2) + : + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "memory" ); + } +} +#endif diff --git a/plugins/wma/libwma/mdct.h b/plugins/wma/libwma/mdct.h new file mode 100644 index 00000000..48d1c25a --- /dev/null +++ b/plugins/wma/libwma/mdct.h @@ -0,0 +1,139 @@ +/* + * WMA compatible decoder + * Copyright (c) 2002 The FFmpeg Project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef CODECLIB_MDCT_H_INCLUDED +#define CODECLIB_MDCT_H_INCLUDED + +//#include "types.h" +#include "fft.h" + +void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input); +void ff_imdct_half(unsigned int nbits, fixed32 *output, const fixed32 *input); + +#ifdef CPU_ARM + +/*Sign-15.16 format */ +#define fixmul32b(x, y) \ + ({ int32_t __hi; \ + uint32_t __lo; \ + int32_t __result; \ + asm ("smull %0, %1, %3, %4\n\t" \ + "mov %2, %1, lsl #1" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y) \ + : "cc" ); \ + __result; \ + }) + +#elif defined(CPU_COLDFIRE) + +static inline int32_t fixmul32b(int32_t x, int32_t y) +{ + asm ( + "mac.l %[x], %[y], %%acc0 \n" /* multiply */ + "movclr.l %%acc0, %[x] \n" /* get higher half */ + : [x] "+d" (x) + : [y] "d" (y) + ); + return x; +} + +#else + +static inline fixed32 fixmul32b(fixed32 x, fixed32 y) +{ + fixed64 temp; + + temp = x; + temp *= y; + + temp >>= 31; //16+31-16 = 31 bits + + return (fixed32)temp; +} +#endif + + +#ifdef CPU_ARM +static inline +void CMUL(fixed32 *x, fixed32 *y, + fixed32 a, fixed32 b, + fixed32 t, fixed32 v) +{ + /* This version loses one bit of precision. Could be solved at the cost + * of 2 extra cycles if it becomes an issue. */ + int x1, y1, l; + asm( + "smull %[l], %[y1], %[b], %[t] \n" + "smlal %[l], %[y1], %[a], %[v] \n" + "rsb %[b], %[b], #0 \n" + "smull %[l], %[x1], %[a], %[t] \n" + "smlal %[l], %[x1], %[b], %[v] \n" + : [l] "=&r" (l), [x1]"=&r" (x1), [y1]"=&r" (y1), [b] "+r" (b) + : [a] "r" (a), [t] "r" (t), [v] "r" (v) + : "cc" + ); + *x = x1 << 1; + *y = y1 << 1; +} +#elif defined CPU_COLDFIRE +static inline +void CMUL(fixed32 *x, fixed32 *y, + fixed32 a, fixed32 b, + fixed32 t, fixed32 v) +{ + asm volatile ("mac.l %[a], %[t], %%acc0;" + "msac.l %[b], %[v], %%acc0;" + "mac.l %[b], %[t], %%acc1;" + "mac.l %[a], %[v], %%acc1;" + "movclr.l %%acc0, %[a];" + "move.l %[a], (%[x]);" + "movclr.l %%acc1, %[a];" + "move.l %[a], (%[y]);" + : [a] "+&r" (a) + : [x] "a" (x), [y] "a" (y), + [b] "r" (b), [t] "r" (t), [v] "r" (v) + : "cc", "memory"); +} +#else +static inline +void CMUL(fixed32 *pre, + fixed32 *pim, + fixed32 are, + fixed32 aim, + fixed32 bre, + fixed32 bim) +{ + //int64_t x,y; + fixed32 _aref = are; + fixed32 _aimf = aim; + fixed32 _bref = bre; + fixed32 _bimf = bim; + fixed32 _r1 = fixmul32b(_bref, _aref); + fixed32 _r2 = fixmul32b(_bimf, _aimf); + fixed32 _r3 = fixmul32b(_bref, _aimf); + fixed32 _r4 = fixmul32b(_bimf, _aref); + *pre = _r1 - _r2; + *pim = _r3 + _r4; + +} +#endif + + +#endif // CODECLIB_MDCT_H_INCLUDED diff --git a/plugins/wma/libwma/mdct_lookup.c b/plugins/wma/libwma/mdct_lookup.c new file mode 100644 index 00000000..5966841a --- /dev/null +++ b/plugins/wma/libwma/mdct_lookup.c @@ -0,0 +1,873 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Michael Giacomelli + * + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifdef ROCKBOX +#include <codecs/lib/codeclib.h> +#else +#include <stdlib.h> +#include <stdint.h> +#endif /* ROCKBOX */ + +#define ICONST_ATTR +/* {sin(2*i*PI/4096, cos(2*i*PI/4096)}, with i = 0 to 512 */ +const int32_t sincos_lookup0[1026] ICONST_ATTR = { + 0x00000000, 0x7fffffff, 0x003243f5, 0x7ffff621, + 0x006487e3, 0x7fffd886, 0x0096cbc1, 0x7fffa72c, + 0x00c90f88, 0x7fff6216, 0x00fb5330, 0x7fff0943, + 0x012d96b1, 0x7ffe9cb2, 0x015fda03, 0x7ffe1c65, + 0x01921d20, 0x7ffd885a, 0x01c45ffe, 0x7ffce093, + 0x01f6a297, 0x7ffc250f, 0x0228e4e2, 0x7ffb55ce, + 0x025b26d7, 0x7ffa72d1, 0x028d6870, 0x7ff97c18, + 0x02bfa9a4, 0x7ff871a2, 0x02f1ea6c, 0x7ff75370, + 0x03242abf, 0x7ff62182, 0x03566a96, 0x7ff4dbd9, + 0x0388a9ea, 0x7ff38274, 0x03bae8b2, 0x7ff21553, + 0x03ed26e6, 0x7ff09478, 0x041f6480, 0x7feeffe1, + 0x0451a177, 0x7fed5791, 0x0483ddc3, 0x7feb9b85, + 0x04b6195d, 0x7fe9cbc0, 0x04e8543e, 0x7fe7e841, + 0x051a8e5c, 0x7fe5f108, 0x054cc7b1, 0x7fe3e616, + 0x057f0035, 0x7fe1c76b, 0x05b137df, 0x7fdf9508, + 0x05e36ea9, 0x7fdd4eec, 0x0615a48b, 0x7fdaf519, + 0x0647d97c, 0x7fd8878e, 0x067a0d76, 0x7fd6064c, + 0x06ac406f, 0x7fd37153, 0x06de7262, 0x7fd0c8a3, + 0x0710a345, 0x7fce0c3e, 0x0742d311, 0x7fcb3c23, + 0x077501be, 0x7fc85854, 0x07a72f45, 0x7fc560cf, + 0x07d95b9e, 0x7fc25596, 0x080b86c2, 0x7fbf36aa, + 0x083db0a7, 0x7fbc040a, 0x086fd947, 0x7fb8bdb8, + 0x08a2009a, 0x7fb563b3, 0x08d42699, 0x7fb1f5fc, + 0x09064b3a, 0x7fae7495, 0x09386e78, 0x7faadf7c, + 0x096a9049, 0x7fa736b4, 0x099cb0a7, 0x7fa37a3c, + 0x09cecf89, 0x7f9faa15, 0x0a00ece8, 0x7f9bc640, + 0x0a3308bd, 0x7f97cebd, 0x0a6522fe, 0x7f93c38c, + 0x0a973ba5, 0x7f8fa4b0, 0x0ac952aa, 0x7f8b7227, + 0x0afb6805, 0x7f872bf3, 0x0b2d7baf, 0x7f82d214, + 0x0b5f8d9f, 0x7f7e648c, 0x0b919dcf, 0x7f79e35a, + 0x0bc3ac35, 0x7f754e80, 0x0bf5b8cb, 0x7f70a5fe, + 0x0c27c389, 0x7f6be9d4, 0x0c59cc68, 0x7f671a05, + 0x0c8bd35e, 0x7f62368f, 0x0cbdd865, 0x7f5d3f75, + 0x0cefdb76, 0x7f5834b7, 0x0d21dc87, 0x7f531655, + 0x0d53db92, 0x7f4de451, 0x0d85d88f, 0x7f489eaa, + 0x0db7d376, 0x7f434563, 0x0de9cc40, 0x7f3dd87c, + 0x0e1bc2e4, 0x7f3857f6, 0x0e4db75b, 0x7f32c3d1, + 0x0e7fa99e, 0x7f2d1c0e, 0x0eb199a4, 0x7f2760af, + 0x0ee38766, 0x7f2191b4, 0x0f1572dc, 0x7f1baf1e, + 0x0f475bff, 0x7f15b8ee, 0x0f7942c7, 0x7f0faf25, + 0x0fab272b, 0x7f0991c4, 0x0fdd0926, 0x7f0360cb, + 0x100ee8ad, 0x7efd1c3c, 0x1040c5bb, 0x7ef6c418, + 0x1072a048, 0x7ef05860, 0x10a4784b, 0x7ee9d914, + 0x10d64dbd, 0x7ee34636, 0x11082096, 0x7edc9fc6, + 0x1139f0cf, 0x7ed5e5c6, 0x116bbe60, 0x7ecf1837, + 0x119d8941, 0x7ec8371a, 0x11cf516a, 0x7ec14270, + 0x120116d5, 0x7eba3a39, 0x1232d979, 0x7eb31e78, + 0x1264994e, 0x7eabef2c, 0x1296564d, 0x7ea4ac58, + 0x12c8106f, 0x7e9d55fc, 0x12f9c7aa, 0x7e95ec1a, + 0x132b7bf9, 0x7e8e6eb2, 0x135d2d53, 0x7e86ddc6, + 0x138edbb1, 0x7e7f3957, 0x13c0870a, 0x7e778166, + 0x13f22f58, 0x7e6fb5f4, 0x1423d492, 0x7e67d703, + 0x145576b1, 0x7e5fe493, 0x148715ae, 0x7e57dea7, + 0x14b8b17f, 0x7e4fc53e, 0x14ea4a1f, 0x7e47985b, + 0x151bdf86, 0x7e3f57ff, 0x154d71aa, 0x7e37042a, + 0x157f0086, 0x7e2e9cdf, 0x15b08c12, 0x7e26221f, + 0x15e21445, 0x7e1d93ea, 0x16139918, 0x7e14f242, + 0x16451a83, 0x7e0c3d29, 0x1676987f, 0x7e0374a0, + 0x16a81305, 0x7dfa98a8, 0x16d98a0c, 0x7df1a942, + 0x170afd8d, 0x7de8a670, 0x173c6d80, 0x7ddf9034, + 0x176dd9de, 0x7dd6668f, 0x179f429f, 0x7dcd2981, + 0x17d0a7bc, 0x7dc3d90d, 0x1802092c, 0x7dba7534, + 0x183366e9, 0x7db0fdf8, 0x1864c0ea, 0x7da77359, + 0x18961728, 0x7d9dd55a, 0x18c7699b, 0x7d9423fc, + 0x18f8b83c, 0x7d8a5f40, 0x192a0304, 0x7d808728, + 0x195b49ea, 0x7d769bb5, 0x198c8ce7, 0x7d6c9ce9, + 0x19bdcbf3, 0x7d628ac6, 0x19ef0707, 0x7d58654d, + 0x1a203e1b, 0x7d4e2c7f, 0x1a517128, 0x7d43e05e, + 0x1a82a026, 0x7d3980ec, 0x1ab3cb0d, 0x7d2f0e2b, + 0x1ae4f1d6, 0x7d24881b, 0x1b161479, 0x7d19eebf, + 0x1b4732ef, 0x7d0f4218, 0x1b784d30, 0x7d048228, + 0x1ba96335, 0x7cf9aef0, 0x1bda74f6, 0x7ceec873, + 0x1c0b826a, 0x7ce3ceb2, 0x1c3c8b8c, 0x7cd8c1ae, + 0x1c6d9053, 0x7ccda169, 0x1c9e90b8, 0x7cc26de5, + 0x1ccf8cb3, 0x7cb72724, 0x1d00843d, 0x7cabcd28, + 0x1d31774d, 0x7ca05ff1, 0x1d6265dd, 0x7c94df83, + 0x1d934fe5, 0x7c894bde, 0x1dc4355e, 0x7c7da505, + 0x1df5163f, 0x7c71eaf9, 0x1e25f282, 0x7c661dbc, + 0x1e56ca1e, 0x7c5a3d50, 0x1e879d0d, 0x7c4e49b7, + 0x1eb86b46, 0x7c4242f2, 0x1ee934c3, 0x7c362904, + 0x1f19f97b, 0x7c29fbee, 0x1f4ab968, 0x7c1dbbb3, + 0x1f7b7481, 0x7c116853, 0x1fac2abf, 0x7c0501d2, + 0x1fdcdc1b, 0x7bf88830, 0x200d888d, 0x7bebfb70, + 0x203e300d, 0x7bdf5b94, 0x206ed295, 0x7bd2a89e, + 0x209f701c, 0x7bc5e290, 0x20d0089c, 0x7bb9096b, + 0x21009c0c, 0x7bac1d31, 0x21312a65, 0x7b9f1de6, + 0x2161b3a0, 0x7b920b89, 0x219237b5, 0x7b84e61f, + 0x21c2b69c, 0x7b77ada8, 0x21f3304f, 0x7b6a6227, + 0x2223a4c5, 0x7b5d039e, 0x225413f8, 0x7b4f920e, + 0x22847de0, 0x7b420d7a, 0x22b4e274, 0x7b3475e5, + 0x22e541af, 0x7b26cb4f, 0x23159b88, 0x7b190dbc, + 0x2345eff8, 0x7b0b3d2c, 0x23763ef7, 0x7afd59a4, + 0x23a6887f, 0x7aef6323, 0x23d6cc87, 0x7ae159ae, + 0x24070b08, 0x7ad33d45, 0x243743fa, 0x7ac50dec, + 0x24677758, 0x7ab6cba4, 0x2497a517, 0x7aa8766f, + 0x24c7cd33, 0x7a9a0e50, 0x24f7efa2, 0x7a8b9348, + 0x25280c5e, 0x7a7d055b, 0x2558235f, 0x7a6e648a, + 0x2588349d, 0x7a5fb0d8, 0x25b84012, 0x7a50ea47, + 0x25e845b6, 0x7a4210d8, 0x26184581, 0x7a332490, + 0x26483f6c, 0x7a24256f, 0x26783370, 0x7a151378, + 0x26a82186, 0x7a05eead, 0x26d809a5, 0x79f6b711, + 0x2707ebc7, 0x79e76ca7, 0x2737c7e3, 0x79d80f6f, + 0x27679df4, 0x79c89f6e, 0x27976df1, 0x79b91ca4, + 0x27c737d3, 0x79a98715, 0x27f6fb92, 0x7999dec4, + 0x2826b928, 0x798a23b1, 0x2856708d, 0x797a55e0, + 0x288621b9, 0x796a7554, 0x28b5cca5, 0x795a820e, + 0x28e5714b, 0x794a7c12, 0x29150fa1, 0x793a6361, + 0x2944a7a2, 0x792a37fe, 0x29743946, 0x7919f9ec, + 0x29a3c485, 0x7909a92d, 0x29d34958, 0x78f945c3, + 0x2a02c7b8, 0x78e8cfb2, 0x2a323f9e, 0x78d846fb, + 0x2a61b101, 0x78c7aba2, 0x2a911bdc, 0x78b6fda8, + 0x2ac08026, 0x78a63d11, 0x2aefddd8, 0x789569df, + 0x2b1f34eb, 0x78848414, 0x2b4e8558, 0x78738bb3, + 0x2b7dcf17, 0x786280bf, 0x2bad1221, 0x7851633b, + 0x2bdc4e6f, 0x78403329, 0x2c0b83fa, 0x782ef08b, + 0x2c3ab2b9, 0x781d9b65, 0x2c69daa6, 0x780c33b8, + 0x2c98fbba, 0x77fab989, 0x2cc815ee, 0x77e92cd9, + 0x2cf72939, 0x77d78daa, 0x2d263596, 0x77c5dc01, + 0x2d553afc, 0x77b417df, 0x2d843964, 0x77a24148, + 0x2db330c7, 0x7790583e, 0x2de2211e, 0x777e5cc3, + 0x2e110a62, 0x776c4edb, 0x2e3fec8b, 0x775a2e89, + 0x2e6ec792, 0x7747fbce, 0x2e9d9b70, 0x7735b6af, + 0x2ecc681e, 0x77235f2d, 0x2efb2d95, 0x7710f54c, + 0x2f29ebcc, 0x76fe790e, 0x2f58a2be, 0x76ebea77, + 0x2f875262, 0x76d94989, 0x2fb5fab2, 0x76c69647, + 0x2fe49ba7, 0x76b3d0b4, 0x30133539, 0x76a0f8d2, + 0x3041c761, 0x768e0ea6, 0x30705217, 0x767b1231, + 0x309ed556, 0x76680376, 0x30cd5115, 0x7654e279, + 0x30fbc54d, 0x7641af3d, 0x312a31f8, 0x762e69c4, + 0x3158970e, 0x761b1211, 0x3186f487, 0x7607a828, + 0x31b54a5e, 0x75f42c0b, 0x31e39889, 0x75e09dbd, + 0x3211df04, 0x75ccfd42, 0x32401dc6, 0x75b94a9c, + 0x326e54c7, 0x75a585cf, 0x329c8402, 0x7591aedd, + 0x32caab6f, 0x757dc5ca, 0x32f8cb07, 0x7569ca99, + 0x3326e2c3, 0x7555bd4c, 0x3354f29b, 0x75419de7, + 0x3382fa88, 0x752d6c6c, 0x33b0fa84, 0x751928e0, + 0x33def287, 0x7504d345, 0x340ce28b, 0x74f06b9e, + 0x343aca87, 0x74dbf1ef, 0x3468aa76, 0x74c7663a, + 0x34968250, 0x74b2c884, 0x34c4520d, 0x749e18cd, + 0x34f219a8, 0x7489571c, 0x351fd918, 0x74748371, + 0x354d9057, 0x745f9dd1, 0x357b3f5d, 0x744aa63f, + 0x35a8e625, 0x74359cbd, 0x35d684a6, 0x74208150, + 0x36041ad9, 0x740b53fb, 0x3631a8b8, 0x73f614c0, + 0x365f2e3b, 0x73e0c3a3, 0x368cab5c, 0x73cb60a8, + 0x36ba2014, 0x73b5ebd1, 0x36e78c5b, 0x73a06522, + 0x3714f02a, 0x738acc9e, 0x37424b7b, 0x73752249, + 0x376f9e46, 0x735f6626, 0x379ce885, 0x73499838, + 0x37ca2a30, 0x7333b883, 0x37f76341, 0x731dc70a, + 0x382493b0, 0x7307c3d0, 0x3851bb77, 0x72f1aed9, + 0x387eda8e, 0x72db8828, 0x38abf0ef, 0x72c54fc1, + 0x38d8fe93, 0x72af05a7, 0x39060373, 0x7298a9dd, + 0x3932ff87, 0x72823c67, 0x395ff2c9, 0x726bbd48, + 0x398cdd32, 0x72552c85, 0x39b9bebc, 0x723e8a20, + 0x39e6975e, 0x7227d61c, 0x3a136712, 0x7211107e, + 0x3a402dd2, 0x71fa3949, 0x3a6ceb96, 0x71e35080, + 0x3a99a057, 0x71cc5626, 0x3ac64c0f, 0x71b54a41, + 0x3af2eeb7, 0x719e2cd2, 0x3b1f8848, 0x7186fdde, + 0x3b4c18ba, 0x716fbd68, 0x3b78a007, 0x71586b74, + 0x3ba51e29, 0x71410805, 0x3bd19318, 0x7129931f, + 0x3bfdfecd, 0x71120cc5, 0x3c2a6142, 0x70fa74fc, + 0x3c56ba70, 0x70e2cbc6, 0x3c830a50, 0x70cb1128, + 0x3caf50da, 0x70b34525, 0x3cdb8e09, 0x709b67c0, + 0x3d07c1d6, 0x708378ff, 0x3d33ec39, 0x706b78e3, + 0x3d600d2c, 0x70536771, 0x3d8c24a8, 0x703b44ad, + 0x3db832a6, 0x7023109a, 0x3de4371f, 0x700acb3c, + 0x3e10320d, 0x6ff27497, 0x3e3c2369, 0x6fda0cae, + 0x3e680b2c, 0x6fc19385, 0x3e93e950, 0x6fa90921, + 0x3ebfbdcd, 0x6f906d84, 0x3eeb889c, 0x6f77c0b3, + 0x3f1749b8, 0x6f5f02b2, 0x3f430119, 0x6f463383, + 0x3f6eaeb8, 0x6f2d532c, 0x3f9a5290, 0x6f1461b0, + 0x3fc5ec98, 0x6efb5f12, 0x3ff17cca, 0x6ee24b57, + 0x401d0321, 0x6ec92683, 0x40487f94, 0x6eaff099, + 0x4073f21d, 0x6e96a99d, 0x409f5ab6, 0x6e7d5193, + 0x40cab958, 0x6e63e87f, 0x40f60dfb, 0x6e4a6e66, + 0x4121589b, 0x6e30e34a, 0x414c992f, 0x6e174730, + 0x4177cfb1, 0x6dfd9a1c, 0x41a2fc1a, 0x6de3dc11, + 0x41ce1e65, 0x6dca0d14, 0x41f93689, 0x6db02d29, + 0x42244481, 0x6d963c54, 0x424f4845, 0x6d7c3a98, + 0x427a41d0, 0x6d6227fa, 0x42a5311b, 0x6d48047e, + 0x42d0161e, 0x6d2dd027, 0x42faf0d4, 0x6d138afb, + 0x4325c135, 0x6cf934fc, 0x4350873c, 0x6cdece2f, + 0x437b42e1, 0x6cc45698, 0x43a5f41e, 0x6ca9ce3b, + 0x43d09aed, 0x6c8f351c, 0x43fb3746, 0x6c748b3f, + 0x4425c923, 0x6c59d0a9, 0x4450507e, 0x6c3f055d, + 0x447acd50, 0x6c242960, 0x44a53f93, 0x6c093cb6, + 0x44cfa740, 0x6bee3f62, 0x44fa0450, 0x6bd3316a, + 0x452456bd, 0x6bb812d1, 0x454e9e80, 0x6b9ce39b, + 0x4578db93, 0x6b81a3cd, 0x45a30df0, 0x6b66536b, + 0x45cd358f, 0x6b4af279, 0x45f7526b, 0x6b2f80fb, + 0x4621647d, 0x6b13fef5, 0x464b6bbe, 0x6af86c6c, + 0x46756828, 0x6adcc964, 0x469f59b4, 0x6ac115e2, + 0x46c9405c, 0x6aa551e9, 0x46f31c1a, 0x6a897d7d, + 0x471cece7, 0x6a6d98a4, 0x4746b2bc, 0x6a51a361, + 0x47706d93, 0x6a359db9, 0x479a1d67, 0x6a1987b0, + 0x47c3c22f, 0x69fd614a, 0x47ed5be6, 0x69e12a8c, + 0x4816ea86, 0x69c4e37a, 0x48406e08, 0x69a88c19, + 0x4869e665, 0x698c246c, 0x48935397, 0x696fac78, + 0x48bcb599, 0x69532442, 0x48e60c62, 0x69368bce, + 0x490f57ee, 0x6919e320, 0x49389836, 0x68fd2a3d, + 0x4961cd33, 0x68e06129, 0x498af6df, 0x68c387e9, + 0x49b41533, 0x68a69e81, 0x49dd282a, 0x6889a4f6, + 0x4a062fbd, 0x686c9b4b, 0x4a2f2be6, 0x684f8186, + 0x4a581c9e, 0x683257ab, 0x4a8101de, 0x68151dbe, + 0x4aa9dba2, 0x67f7d3c5, 0x4ad2a9e2, 0x67da79c3, + 0x4afb6c98, 0x67bd0fbd, 0x4b2423be, 0x679f95b7, + 0x4b4ccf4d, 0x67820bb7, 0x4b756f40, 0x676471c0, + 0x4b9e0390, 0x6746c7d8, 0x4bc68c36, 0x67290e02, + 0x4bef092d, 0x670b4444, 0x4c177a6e, 0x66ed6aa1, + 0x4c3fdff4, 0x66cf8120, 0x4c6839b7, 0x66b187c3, + 0x4c9087b1, 0x66937e91, 0x4cb8c9dd, 0x6675658c, + 0x4ce10034, 0x66573cbb, 0x4d092ab0, 0x66390422, + 0x4d31494b, 0x661abbc5, 0x4d595bfe, 0x65fc63a9, + 0x4d8162c4, 0x65ddfbd3, 0x4da95d96, 0x65bf8447, + 0x4dd14c6e, 0x65a0fd0b, 0x4df92f46, 0x65826622, + 0x4e210617, 0x6563bf92, 0x4e48d0dd, 0x6545095f, + 0x4e708f8f, 0x6526438f, 0x4e984229, 0x65076e25, + 0x4ebfe8a5, 0x64e88926, 0x4ee782fb, 0x64c99498, + 0x4f0f1126, 0x64aa907f, 0x4f369320, 0x648b7ce0, + 0x4f5e08e3, 0x646c59bf, 0x4f857269, 0x644d2722, + 0x4faccfab, 0x642de50d, 0x4fd420a4, 0x640e9386, + 0x4ffb654d, 0x63ef3290, 0x50229da1, 0x63cfc231, + 0x5049c999, 0x63b0426d, 0x5070e92f, 0x6390b34a, + 0x5097fc5e, 0x637114cc, 0x50bf031f, 0x635166f9, + 0x50e5fd6d, 0x6331a9d4, 0x510ceb40, 0x6311dd64, + 0x5133cc94, 0x62f201ac, 0x515aa162, 0x62d216b3, + 0x518169a5, 0x62b21c7b, 0x51a82555, 0x6292130c, + 0x51ced46e, 0x6271fa69, 0x51f576ea, 0x6251d298, + 0x521c0cc2, 0x62319b9d, 0x524295f0, 0x6211557e, + 0x5269126e, 0x61f1003f, 0x528f8238, 0x61d09be5, + 0x52b5e546, 0x61b02876, 0x52dc3b92, 0x618fa5f7, + 0x53028518, 0x616f146c, 0x5328c1d0, 0x614e73da, + 0x534ef1b5, 0x612dc447, 0x537514c2, 0x610d05b7, + 0x539b2af0, 0x60ec3830, 0x53c13439, 0x60cb5bb7, + 0x53e73097, 0x60aa7050, 0x540d2005, 0x60897601, + 0x5433027d, 0x60686ccf, 0x5458d7f9, 0x604754bf, + 0x547ea073, 0x60262dd6, 0x54a45be6, 0x6004f819, + 0x54ca0a4b, 0x5fe3b38d, 0x54efab9c, 0x5fc26038, + 0x55153fd4, 0x5fa0fe1f, 0x553ac6ee, 0x5f7f8d46, + 0x556040e2, 0x5f5e0db3, 0x5585adad, 0x5f3c7f6b, + 0x55ab0d46, 0x5f1ae274, 0x55d05faa, 0x5ef936d1, + 0x55f5a4d2, 0x5ed77c8a, 0x561adcb9, 0x5eb5b3a2, + 0x56400758, 0x5e93dc1f, 0x566524aa, 0x5e71f606, + 0x568a34a9, 0x5e50015d, 0x56af3750, 0x5e2dfe29, + 0x56d42c99, 0x5e0bec6e, 0x56f9147e, 0x5de9cc33, + 0x571deefa, 0x5dc79d7c, 0x5742bc06, 0x5da5604f, + 0x57677b9d, 0x5d8314b1, 0x578c2dba, 0x5d60baa7, + 0x57b0d256, 0x5d3e5237, 0x57d5696d, 0x5d1bdb65, + 0x57f9f2f8, 0x5cf95638, 0x581e6ef1, 0x5cd6c2b5, + 0x5842dd54, 0x5cb420e0, 0x58673e1b, 0x5c9170bf, + 0x588b9140, 0x5c6eb258, 0x58afd6bd, 0x5c4be5b0, + 0x58d40e8c, 0x5c290acc, 0x58f838a9, 0x5c0621b2, + 0x591c550e, 0x5be32a67, 0x594063b5, 0x5bc024f0, + 0x59646498, 0x5b9d1154, 0x598857b2, 0x5b79ef96, + 0x59ac3cfd, 0x5b56bfbd, 0x59d01475, 0x5b3381ce, + 0x59f3de12, 0x5b1035cf, 0x5a1799d1, 0x5aecdbc5, + 0x5a3b47ab, 0x5ac973b5, 0x5a5ee79a, 0x5aa5fda5, + 0x5a82799a, 0x5a82799a + }; + + /* {sin((2*i+1)*PI/4096, cos((2*i+1)*PI/4096)}, with i = 0 to 511 */ +const int32_t sincos_lookup1[1024] ICONST_ATTR = { + 0x001921fb, 0x7ffffd88, 0x004b65ee, 0x7fffe9cb, + 0x007da9d4, 0x7fffc251, 0x00afeda8, 0x7fff8719, + 0x00e23160, 0x7fff3824, 0x011474f6, 0x7ffed572, + 0x0146b860, 0x7ffe5f03, 0x0178fb99, 0x7ffdd4d7, + 0x01ab3e97, 0x7ffd36ee, 0x01dd8154, 0x7ffc8549, + 0x020fc3c6, 0x7ffbbfe6, 0x024205e8, 0x7ffae6c7, + 0x027447b0, 0x7ff9f9ec, 0x02a68917, 0x7ff8f954, + 0x02d8ca16, 0x7ff7e500, 0x030b0aa4, 0x7ff6bcf0, + 0x033d4abb, 0x7ff58125, 0x036f8a51, 0x7ff4319d, + 0x03a1c960, 0x7ff2ce5b, 0x03d407df, 0x7ff1575d, + 0x040645c7, 0x7fefcca4, 0x04388310, 0x7fee2e30, + 0x046abfb3, 0x7fec7c02, 0x049cfba7, 0x7feab61a, + 0x04cf36e5, 0x7fe8dc78, 0x05017165, 0x7fe6ef1c, + 0x0533ab20, 0x7fe4ee06, 0x0565e40d, 0x7fe2d938, + 0x05981c26, 0x7fe0b0b1, 0x05ca5361, 0x7fde7471, + 0x05fc89b8, 0x7fdc247a, 0x062ebf22, 0x7fd9c0ca, + 0x0660f398, 0x7fd74964, 0x06932713, 0x7fd4be46, + 0x06c5598a, 0x7fd21f72, 0x06f78af6, 0x7fcf6ce8, + 0x0729bb4e, 0x7fcca6a7, 0x075bea8c, 0x7fc9ccb2, + 0x078e18a7, 0x7fc6df08, 0x07c04598, 0x7fc3dda9, + 0x07f27157, 0x7fc0c896, 0x08249bdd, 0x7fbd9fd0, + 0x0856c520, 0x7fba6357, 0x0888ed1b, 0x7fb7132b, + 0x08bb13c5, 0x7fb3af4e, 0x08ed3916, 0x7fb037bf, + 0x091f5d06, 0x7facac7f, 0x09517f8f, 0x7fa90d8e, + 0x0983a0a7, 0x7fa55aee, 0x09b5c048, 0x7fa1949e, + 0x09e7de6a, 0x7f9dbaa0, 0x0a19fb04, 0x7f99ccf4, + 0x0a4c1610, 0x7f95cb9a, 0x0a7e2f85, 0x7f91b694, + 0x0ab0475c, 0x7f8d8de1, 0x0ae25d8d, 0x7f895182, + 0x0b147211, 0x7f850179, 0x0b4684df, 0x7f809dc5, + 0x0b7895f0, 0x7f7c2668, 0x0baaa53b, 0x7f779b62, + 0x0bdcb2bb, 0x7f72fcb4, 0x0c0ebe66, 0x7f6e4a5e, + 0x0c40c835, 0x7f698461, 0x0c72d020, 0x7f64aabf, + 0x0ca4d620, 0x7f5fbd77, 0x0cd6da2d, 0x7f5abc8a, + 0x0d08dc3f, 0x7f55a7fa, 0x0d3adc4e, 0x7f507fc7, + 0x0d6cda53, 0x7f4b43f2, 0x0d9ed646, 0x7f45f47b, + 0x0dd0d01f, 0x7f409164, 0x0e02c7d7, 0x7f3b1aad, + 0x0e34bd66, 0x7f359057, 0x0e66b0c3, 0x7f2ff263, + 0x0e98a1e9, 0x7f2a40d2, 0x0eca90ce, 0x7f247ba5, + 0x0efc7d6b, 0x7f1ea2dc, 0x0f2e67b8, 0x7f18b679, + 0x0f604faf, 0x7f12b67c, 0x0f923546, 0x7f0ca2e7, + 0x0fc41876, 0x7f067bba, 0x0ff5f938, 0x7f0040f6, + 0x1027d784, 0x7ef9f29d, 0x1059b352, 0x7ef390ae, + 0x108b8c9b, 0x7eed1b2c, 0x10bd6356, 0x7ee69217, + 0x10ef377d, 0x7edff570, 0x11210907, 0x7ed94538, + 0x1152d7ed, 0x7ed28171, 0x1184a427, 0x7ecbaa1a, + 0x11b66dad, 0x7ec4bf36, 0x11e83478, 0x7ebdc0c6, + 0x1219f880, 0x7eb6aeca, 0x124bb9be, 0x7eaf8943, + 0x127d7829, 0x7ea85033, 0x12af33ba, 0x7ea1039b, + 0x12e0ec6a, 0x7e99a37c, 0x1312a230, 0x7e922fd6, + 0x13445505, 0x7e8aa8ac, 0x137604e2, 0x7e830dff, + 0x13a7b1bf, 0x7e7b5fce, 0x13d95b93, 0x7e739e1d, + 0x140b0258, 0x7e6bc8eb, 0x143ca605, 0x7e63e03b, + 0x146e4694, 0x7e5be40c, 0x149fe3fc, 0x7e53d462, + 0x14d17e36, 0x7e4bb13c, 0x1503153a, 0x7e437a9c, + 0x1534a901, 0x7e3b3083, 0x15663982, 0x7e32d2f4, + 0x1597c6b7, 0x7e2a61ed, 0x15c95097, 0x7e21dd73, + 0x15fad71b, 0x7e194584, 0x162c5a3b, 0x7e109a24, + 0x165dd9f0, 0x7e07db52, 0x168f5632, 0x7dff0911, + 0x16c0cef9, 0x7df62362, 0x16f2443e, 0x7ded2a47, + 0x1723b5f9, 0x7de41dc0, 0x17552422, 0x7ddafdce, + 0x17868eb3, 0x7dd1ca75, 0x17b7f5a3, 0x7dc883b4, + 0x17e958ea, 0x7dbf298d, 0x181ab881, 0x7db5bc02, + 0x184c1461, 0x7dac3b15, 0x187d6c82, 0x7da2a6c6, + 0x18aec0db, 0x7d98ff17, 0x18e01167, 0x7d8f4409, + 0x19115e1c, 0x7d85759f, 0x1942a6f3, 0x7d7b93da, + 0x1973ebe6, 0x7d719eba, 0x19a52ceb, 0x7d679642, + 0x19d669fc, 0x7d5d7a74, 0x1a07a311, 0x7d534b50, + 0x1a38d823, 0x7d4908d9, 0x1a6a0929, 0x7d3eb30f, + 0x1a9b361d, 0x7d3449f5, 0x1acc5ef6, 0x7d29cd8c, + 0x1afd83ad, 0x7d1f3dd6, 0x1b2ea43a, 0x7d149ad5, + 0x1b5fc097, 0x7d09e489, 0x1b90d8bb, 0x7cff1af5, + 0x1bc1ec9e, 0x7cf43e1a, 0x1bf2fc3a, 0x7ce94dfb, + 0x1c240786, 0x7cde4a98, 0x1c550e7c, 0x7cd333f3, + 0x1c861113, 0x7cc80a0f, 0x1cb70f43, 0x7cbcccec, + 0x1ce80906, 0x7cb17c8d, 0x1d18fe54, 0x7ca618f3, + 0x1d49ef26, 0x7c9aa221, 0x1d7adb73, 0x7c8f1817, + 0x1dabc334, 0x7c837ad8, 0x1ddca662, 0x7c77ca65, + 0x1e0d84f5, 0x7c6c06c0, 0x1e3e5ee5, 0x7c602fec, + 0x1e6f342c, 0x7c5445e9, 0x1ea004c1, 0x7c4848ba, + 0x1ed0d09d, 0x7c3c3860, 0x1f0197b8, 0x7c3014de, + 0x1f325a0b, 0x7c23de35, 0x1f63178f, 0x7c179467, + 0x1f93d03c, 0x7c0b3777, 0x1fc4840a, 0x7bfec765, + 0x1ff532f2, 0x7bf24434, 0x2025dcec, 0x7be5ade6, + 0x205681f1, 0x7bd9047c, 0x208721f9, 0x7bcc47fa, + 0x20b7bcfe, 0x7bbf7860, 0x20e852f6, 0x7bb295b0, + 0x2118e3dc, 0x7ba59fee, 0x21496fa7, 0x7b989719, + 0x2179f64f, 0x7b8b7b36, 0x21aa77cf, 0x7b7e4c45, + 0x21daf41d, 0x7b710a49, 0x220b6b32, 0x7b63b543, + 0x223bdd08, 0x7b564d36, 0x226c4996, 0x7b48d225, + 0x229cb0d5, 0x7b3b4410, 0x22cd12bd, 0x7b2da2fa, + 0x22fd6f48, 0x7b1feee5, 0x232dc66d, 0x7b1227d3, + 0x235e1826, 0x7b044dc7, 0x238e646a, 0x7af660c2, + 0x23beab33, 0x7ae860c7, 0x23eeec78, 0x7ada4dd8, + 0x241f2833, 0x7acc27f7, 0x244f5e5c, 0x7abdef25, + 0x247f8eec, 0x7aafa367, 0x24afb9da, 0x7aa144bc, + 0x24dfdf20, 0x7a92d329, 0x250ffeb7, 0x7a844eae, + 0x25401896, 0x7a75b74f, 0x25702cb7, 0x7a670d0d, + 0x25a03b11, 0x7a584feb, 0x25d0439f, 0x7a497feb, + 0x26004657, 0x7a3a9d0f, 0x26304333, 0x7a2ba75a, + 0x26603a2c, 0x7a1c9ece, 0x26902b39, 0x7a0d836d, + 0x26c01655, 0x79fe5539, 0x26effb76, 0x79ef1436, + 0x271fda96, 0x79dfc064, 0x274fb3ae, 0x79d059c8, + 0x277f86b5, 0x79c0e062, 0x27af53a6, 0x79b15435, + 0x27df1a77, 0x79a1b545, 0x280edb23, 0x79920392, + 0x283e95a1, 0x79823f20, 0x286e49ea, 0x797267f2, + 0x289df7f8, 0x79627e08, 0x28cd9fc1, 0x79528167, + 0x28fd4140, 0x79427210, 0x292cdc6d, 0x79325006, + 0x295c7140, 0x79221b4b, 0x298bffb2, 0x7911d3e2, + 0x29bb87bc, 0x790179cd, 0x29eb0957, 0x78f10d0f, + 0x2a1a847b, 0x78e08dab, 0x2a49f920, 0x78cffba3, + 0x2a796740, 0x78bf56f9, 0x2aa8ced3, 0x78ae9fb0, + 0x2ad82fd2, 0x789dd5cb, 0x2b078a36, 0x788cf94c, + 0x2b36ddf7, 0x787c0a36, 0x2b662b0e, 0x786b088c, + 0x2b957173, 0x7859f44f, 0x2bc4b120, 0x7848cd83, + 0x2bf3ea0d, 0x7837942b, 0x2c231c33, 0x78264849, + 0x2c52478a, 0x7814e9df, 0x2c816c0c, 0x780378f1, + 0x2cb089b1, 0x77f1f581, 0x2cdfa071, 0x77e05f91, + 0x2d0eb046, 0x77ceb725, 0x2d3db928, 0x77bcfc3f, + 0x2d6cbb10, 0x77ab2ee2, 0x2d9bb5f6, 0x77994f11, + 0x2dcaa9d5, 0x77875cce, 0x2df996a3, 0x7775581d, + 0x2e287c5a, 0x776340ff, 0x2e575af3, 0x77511778, + 0x2e863267, 0x773edb8b, 0x2eb502ae, 0x772c8d3a, + 0x2ee3cbc1, 0x771a2c88, 0x2f128d99, 0x7707b979, + 0x2f41482e, 0x76f5340e, 0x2f6ffb7a, 0x76e29c4b, + 0x2f9ea775, 0x76cff232, 0x2fcd4c19, 0x76bd35c7, + 0x2ffbe95d, 0x76aa670d, 0x302a7f3a, 0x76978605, + 0x30590dab, 0x768492b4, 0x308794a6, 0x76718d1c, + 0x30b61426, 0x765e7540, 0x30e48c22, 0x764b4b23, + 0x3112fc95, 0x76380ec8, 0x31416576, 0x7624c031, + 0x316fc6be, 0x76115f63, 0x319e2067, 0x75fdec60, + 0x31cc7269, 0x75ea672a, 0x31fabcbd, 0x75d6cfc5, + 0x3228ff5c, 0x75c32634, 0x32573a3f, 0x75af6a7b, + 0x32856d5e, 0x759b9c9b, 0x32b398b3, 0x7587bc98, + 0x32e1bc36, 0x7573ca75, 0x330fd7e1, 0x755fc635, + 0x333debab, 0x754bafdc, 0x336bf78f, 0x7537876c, + 0x3399fb85, 0x75234ce8, 0x33c7f785, 0x750f0054, + 0x33f5eb89, 0x74faa1b3, 0x3423d78a, 0x74e63108, + 0x3451bb81, 0x74d1ae55, 0x347f9766, 0x74bd199f, + 0x34ad6b32, 0x74a872e8, 0x34db36df, 0x7493ba34, + 0x3508fa66, 0x747eef85, 0x3536b5be, 0x746a12df, + 0x356468e2, 0x74552446, 0x359213c9, 0x744023bc, + 0x35bfb66e, 0x742b1144, 0x35ed50c9, 0x7415ece2, + 0x361ae2d3, 0x7400b69a, 0x36486c86, 0x73eb6e6e, + 0x3675edd9, 0x73d61461, 0x36a366c6, 0x73c0a878, + 0x36d0d746, 0x73ab2ab4, 0x36fe3f52, 0x73959b1b, + 0x372b9ee3, 0x737ff9ae, 0x3758f5f2, 0x736a4671, + 0x37864477, 0x73548168, 0x37b38a6d, 0x733eaa96, + 0x37e0c7cc, 0x7328c1ff, 0x380dfc8d, 0x7312c7a5, + 0x383b28a9, 0x72fcbb8c, 0x38684c19, 0x72e69db7, + 0x389566d6, 0x72d06e2b, 0x38c278d9, 0x72ba2cea, + 0x38ef821c, 0x72a3d9f7, 0x391c8297, 0x728d7557, + 0x39497a43, 0x7276ff0d, 0x39766919, 0x7260771b, + 0x39a34f13, 0x7249dd86, 0x39d02c2a, 0x72333251, + 0x39fd0056, 0x721c7580, 0x3a29cb91, 0x7205a716, + 0x3a568dd4, 0x71eec716, 0x3a834717, 0x71d7d585, + 0x3aaff755, 0x71c0d265, 0x3adc9e86, 0x71a9bdba, + 0x3b093ca3, 0x71929789, 0x3b35d1a5, 0x717b5fd3, + 0x3b625d86, 0x7164169d, 0x3b8ee03e, 0x714cbbeb, + 0x3bbb59c7, 0x71354fc0, 0x3be7ca1a, 0x711dd220, + 0x3c143130, 0x7106430e, 0x3c408f03, 0x70eea28e, + 0x3c6ce38a, 0x70d6f0a4, 0x3c992ec0, 0x70bf2d53, + 0x3cc5709e, 0x70a7589f, 0x3cf1a91c, 0x708f728b, + 0x3d1dd835, 0x70777b1c, 0x3d49fde1, 0x705f7255, + 0x3d761a19, 0x70475839, 0x3da22cd7, 0x702f2ccd, + 0x3dce3614, 0x7016f014, 0x3dfa35c8, 0x6ffea212, + 0x3e262bee, 0x6fe642ca, 0x3e52187f, 0x6fcdd241, + 0x3e7dfb73, 0x6fb5507a, 0x3ea9d4c3, 0x6f9cbd79, + 0x3ed5a46b, 0x6f841942, 0x3f016a61, 0x6f6b63d8, + 0x3f2d26a0, 0x6f529d40, 0x3f58d921, 0x6f39c57d, + 0x3f8481dd, 0x6f20dc92, 0x3fb020ce, 0x6f07e285, + 0x3fdbb5ec, 0x6eeed758, 0x40074132, 0x6ed5bb10, + 0x4032c297, 0x6ebc8db0, 0x405e3a16, 0x6ea34f3d, + 0x4089a7a8, 0x6e89ffb9, 0x40b50b46, 0x6e709f2a, + 0x40e064ea, 0x6e572d93, 0x410bb48c, 0x6e3daaf8, + 0x4136fa27, 0x6e24175c, 0x416235b2, 0x6e0a72c5, + 0x418d6729, 0x6df0bd35, 0x41b88e84, 0x6dd6f6b1, + 0x41e3abbc, 0x6dbd1f3c, 0x420ebecb, 0x6da336dc, + 0x4239c7aa, 0x6d893d93, 0x4264c653, 0x6d6f3365, + 0x428fbabe, 0x6d551858, 0x42baa4e6, 0x6d3aec6e, + 0x42e584c3, 0x6d20afac, 0x43105a50, 0x6d066215, + 0x433b2585, 0x6cec03af, 0x4365e65b, 0x6cd1947c, + 0x43909ccd, 0x6cb71482, 0x43bb48d4, 0x6c9c83c3, + 0x43e5ea68, 0x6c81e245, 0x44108184, 0x6c67300b, + 0x443b0e21, 0x6c4c6d1a, 0x44659039, 0x6c319975, + 0x449007c4, 0x6c16b521, 0x44ba74bd, 0x6bfbc021, + 0x44e4d71c, 0x6be0ba7b, 0x450f2edb, 0x6bc5a431, + 0x45397bf4, 0x6baa7d49, 0x4563be60, 0x6b8f45c7, + 0x458df619, 0x6b73fdae, 0x45b82318, 0x6b58a503, + 0x45e24556, 0x6b3d3bcb, 0x460c5cce, 0x6b21c208, + 0x46366978, 0x6b0637c1, 0x46606b4e, 0x6aea9cf8, + 0x468a624a, 0x6acef1b2, 0x46b44e65, 0x6ab335f4, + 0x46de2f99, 0x6a9769c1, 0x470805df, 0x6a7b8d1e, + 0x4731d131, 0x6a5fa010, 0x475b9188, 0x6a43a29a, + 0x478546de, 0x6a2794c1, 0x47aef12c, 0x6a0b7689, + 0x47d8906d, 0x69ef47f6, 0x48022499, 0x69d3090e, + 0x482badab, 0x69b6b9d3, 0x48552b9b, 0x699a5a4c, + 0x487e9e64, 0x697dea7b, 0x48a805ff, 0x69616a65, + 0x48d16265, 0x6944da10, 0x48fab391, 0x6928397e, + 0x4923f97b, 0x690b88b5, 0x494d341e, 0x68eec7b9, + 0x49766373, 0x68d1f68f, 0x499f8774, 0x68b5153a, + 0x49c8a01b, 0x689823bf, 0x49f1ad61, 0x687b2224, + 0x4a1aaf3f, 0x685e106c, 0x4a43a5b0, 0x6840ee9b, + 0x4a6c90ad, 0x6823bcb7, 0x4a957030, 0x68067ac3, + 0x4abe4433, 0x67e928c5, 0x4ae70caf, 0x67cbc6c0, + 0x4b0fc99d, 0x67ae54ba, 0x4b387af9, 0x6790d2b6, + 0x4b6120bb, 0x677340ba, 0x4b89badd, 0x67559eca, + 0x4bb24958, 0x6737ecea, 0x4bdacc28, 0x671a2b20, + 0x4c034345, 0x66fc596f, 0x4c2baea9, 0x66de77dc, + 0x4c540e4e, 0x66c0866d, 0x4c7c622d, 0x66a28524, + 0x4ca4aa41, 0x66847408, 0x4ccce684, 0x6666531d, + 0x4cf516ee, 0x66482267, 0x4d1d3b7a, 0x6629e1ec, + 0x4d455422, 0x660b91af, 0x4d6d60df, 0x65ed31b5, + 0x4d9561ac, 0x65cec204, 0x4dbd5682, 0x65b0429f, + 0x4de53f5a, 0x6591b38c, 0x4e0d1c30, 0x657314cf, + 0x4e34ecfc, 0x6554666d, 0x4e5cb1b9, 0x6535a86b, + 0x4e846a60, 0x6516dacd, 0x4eac16eb, 0x64f7fd98, + 0x4ed3b755, 0x64d910d1, 0x4efb4b96, 0x64ba147d, + 0x4f22d3aa, 0x649b08a0, 0x4f4a4f89, 0x647bed3f, + 0x4f71bf2e, 0x645cc260, 0x4f992293, 0x643d8806, + 0x4fc079b1, 0x641e3e38, 0x4fe7c483, 0x63fee4f8, + 0x500f0302, 0x63df7c4d, 0x50363529, 0x63c0043b, + 0x505d5af1, 0x63a07cc7, 0x50847454, 0x6380e5f6, + 0x50ab814d, 0x63613fcd, 0x50d281d5, 0x63418a50, + 0x50f975e6, 0x6321c585, 0x51205d7b, 0x6301f171, + 0x5147388c, 0x62e20e17, 0x516e0715, 0x62c21b7e, + 0x5194c910, 0x62a219aa, 0x51bb7e75, 0x628208a1, + 0x51e22740, 0x6261e866, 0x5208c36a, 0x6241b8ff, + 0x522f52ee, 0x62217a72, 0x5255d5c5, 0x62012cc2, + 0x527c4bea, 0x61e0cff5, 0x52a2b556, 0x61c06410, + 0x52c91204, 0x619fe918, 0x52ef61ee, 0x617f5f12, + 0x5315a50e, 0x615ec603, 0x533bdb5d, 0x613e1df0, + 0x536204d7, 0x611d66de, 0x53882175, 0x60fca0d2, + 0x53ae3131, 0x60dbcbd1, 0x53d43406, 0x60bae7e1, + 0x53fa29ed, 0x6099f505, 0x542012e1, 0x6078f344, + 0x5445eedb, 0x6057e2a2, 0x546bbdd7, 0x6036c325, + 0x54917fce, 0x601594d1, 0x54b734ba, 0x5ff457ad, + 0x54dcdc96, 0x5fd30bbc, 0x5502775c, 0x5fb1b104, + 0x55280505, 0x5f90478a, 0x554d858d, 0x5f6ecf53, + 0x5572f8ed, 0x5f4d4865, 0x55985f20, 0x5f2bb2c5, + 0x55bdb81f, 0x5f0a0e77, 0x55e303e6, 0x5ee85b82, + 0x5608426e, 0x5ec699e9, 0x562d73b2, 0x5ea4c9b3, + 0x565297ab, 0x5e82eae5, 0x5677ae54, 0x5e60fd84, + 0x569cb7a8, 0x5e3f0194, 0x56c1b3a1, 0x5e1cf71c, + 0x56e6a239, 0x5dfade20, 0x570b8369, 0x5dd8b6a7, + 0x5730572e, 0x5db680b4, 0x57551d80, 0x5d943c4e, + 0x5779d65b, 0x5d71e979, 0x579e81b8, 0x5d4f883b, + 0x57c31f92, 0x5d2d189a, 0x57e7afe4, 0x5d0a9a9a, + 0x580c32a7, 0x5ce80e41, 0x5830a7d6, 0x5cc57394, + 0x58550f6c, 0x5ca2ca99, 0x58796962, 0x5c801354, + 0x589db5b3, 0x5c5d4dcc, 0x58c1f45b, 0x5c3a7a05, + 0x58e62552, 0x5c179806, 0x590a4893, 0x5bf4a7d2, + 0x592e5e19, 0x5bd1a971, 0x595265df, 0x5bae9ce7, + 0x59765fde, 0x5b8b8239, 0x599a4c12, 0x5b68596d, + 0x59be2a74, 0x5b452288, 0x59e1faff, 0x5b21dd90, + 0x5a05bdae, 0x5afe8a8b, 0x5a29727b, 0x5adb297d, + 0x5a4d1960, 0x5ab7ba6c, 0x5a70b258, 0x5a943d5e, +}; + +/*split radix bit reverse table for FFT of size up to 2048*/ + +const uint16_t revtab[1<<12] = { +0, 3072, 1536, 2816, 768, 3840, 1408, 2432, 384, 3456, 1920, 2752, 704, +3776, 1216, 2240, 192, 3264, 1728, 3008, 960, 4032, 1376, 2400, 352, 3424, +1888, 2656, 608, 3680, 1120, 2144, 96, 3168, 1632, 2912, 864, 3936, 1504, +2528, 480, 3552, 2016, 2736, 688, 3760, 1200, 2224, 176, 3248, 1712, 2992, +944, 4016, 1328, 2352, 304, 3376, 1840, 2608, 560, 3632, 1072, 2096, 48, +3120, 1584, 2864, 816, 3888, 1456, 2480, 432, 3504, 1968, 2800, 752, 3824, +1264, 2288, 240, 3312, 1776, 3056, 1008, 4080, 1368, 2392, 344, 3416, 1880, +2648, 600, 3672, 1112, 2136, 88, 3160, 1624, 2904, 856, 3928, 1496, 2520, +472, 3544, 2008, 2712, 664, 3736, 1176, 2200, 152, 3224, 1688, 2968, 920, +3992, 1304, 2328, 280, 3352, 1816, 2584, 536, 3608, 1048, 2072, 24, 3096, +1560, 2840, 792, 3864, 1432, 2456, 408, 3480, 1944, 2776, 728, 3800, 1240, +2264, 216, 3288, 1752, 3032, 984, 4056, 1400, 2424, 376, 3448, 1912, 2680, +632, 3704, 1144, 2168, 120, 3192, 1656, 2936, 888, 3960, 1528, 2552, 504, +3576, 2040, 2732, 684, 3756, 1196, 2220, 172, 3244, 1708, 2988, 940, 4012, +1324, 2348, 300, 3372, 1836, 2604, 556, 3628, 1068, 2092, 44, 3116, 1580, +2860, 812, 3884, 1452, 2476, 428, 3500, 1964, 2796, 748, 3820, 1260, 2284, +236, 3308, 1772, 3052, 1004, 4076, 1356, 2380, 332, 3404, 1868, 2636, 588, +3660, 1100, 2124, 76, 3148, 1612, 2892, 844, 3916, 1484, 2508, 460, 3532, +1996, 2700, 652, 3724, 1164, 2188, 140, 3212, 1676, 2956, 908, 3980, 1292, +2316, 268, 3340, 1804, 2572, 524, 3596, 1036, 2060, 12, 3084, 1548, 2828, +780, 3852, 1420, 2444, 396, 3468, 1932, 2764, 716, 3788, 1228, 2252, 204, +3276, 1740, 3020, 972, 4044, 1388, 2412, 364, 3436, 1900, 2668, 620, 3692, +1132, 2156, 108, 3180, 1644, 2924, 876, 3948, 1516, 2540, 492, 3564, 2028, +2748, 700, 3772, 1212, 2236, 188, 3260, 1724, 3004, 956, 4028, 1340, 2364, +316, 3388, 1852, 2620, 572, 3644, 1084, 2108, 60, 3132, 1596, 2876, 828, +3900, 1468, 2492, 444, 3516, 1980, 2812, 764, 3836, 1276, 2300, 252, 3324, +1788, 3068, 1020, 4092, 1366, 2390, 342, 3414, 1878, 2646, 598, 3670, 1110, +2134, 86, 3158, 1622, 2902, 854, 3926, 1494, 2518, 470, 3542, 2006, 2710, +662, 3734, 1174, 2198, 150, 3222, 1686, 2966, 918, 3990, 1302, 2326, 278, +3350, 1814, 2582, 534, 3606, 1046, 2070, 22, 3094, 1558, 2838, 790, 3862, +1430, 2454, 406, 3478, 1942, 2774, 726, 3798, 1238, 2262, 214, 3286, 1750, +3030, 982, 4054, 1398, 2422, 374, 3446, 1910, 2678, 630, 3702, 1142, 2166, +118, 3190, 1654, 2934, 886, 3958, 1526, 2550, 502, 3574, 2038, 2726, 678, +3750, 1190, 2214, 166, 3238, 1702, 2982, 934, 4006, 1318, 2342, 294, 3366, +1830, 2598, 550, 3622, 1062, 2086, 38, 3110, 1574, 2854, 806, 3878, 1446, +2470, 422, 3494, 1958, 2790, 742, 3814, 1254, 2278, 230, 3302, 1766, 3046, +998, 4070, 1350, 2374, 326, 3398, 1862, 2630, 582, 3654, 1094, 2118, 70, +3142, 1606, 2886, 838, 3910, 1478, 2502, 454, 3526, 1990, 2694, 646, 3718, +1158, 2182, 134, 3206, 1670, 2950, 902, 3974, 1286, 2310, 262, 3334, 1798, +2566, 518, 3590, 1030, 2054, 6, 3078, 1542, 2822, 774, 3846, 1414, 2438, +390, 3462, 1926, 2758, 710, 3782, 1222, 2246, 198, 3270, 1734, 3014, 966, +4038, 1382, 2406, 358, 3430, 1894, 2662, 614, 3686, 1126, 2150, 102, 3174, +1638, 2918, 870, 3942, 1510, 2534, 486, 3558, 2022, 2742, 694, 3766, 1206, +2230, 182, 3254, 1718, 2998, 950, 4022, 1334, 2358, 310, 3382, 1846, 2614, +566, 3638, 1078, 2102, 54, 3126, 1590, 2870, 822, 3894, 1462, 2486, 438, +3510, 1974, 2806, 758, 3830, 1270, 2294, 246, 3318, 1782, 3062, 1014, 4086, +1374, 2398, 350, 3422, 1886, 2654, 606, 3678, 1118, 2142, 94, 3166, 1630, +2910, 862, 3934, 1502, 2526, 478, 3550, 2014, 2718, 670, 3742, 1182, 2206, +158, 3230, 1694, 2974, 926, 3998, 1310, 2334, 286, 3358, 1822, 2590, 542, +3614, 1054, 2078, 30, 3102, 1566, 2846, 798, 3870, 1438, 2462, 414, 3486, +1950, 2782, 734, 3806, 1246, 2270, 222, 3294, 1758, 3038, 990, 4062, 1406, +2430, 382, 3454, 1918, 2686, 638, 3710, 1150, 2174, 126, 3198, 1662, 2942, +894, 3966, 1534, 2558, 510, 3582, 2046, 2731, 683, 3755, 1195, 2219, 171, +3243, 1707, 2987, 939, 4011, 1323, 2347, 299, 3371, 1835, 2603, 555, 3627, +1067, 2091, 43, 3115, 1579, 2859, 811, 3883, 1451, 2475, 427, 3499, 1963, +2795, 747, 3819, 1259, 2283, 235, 3307, 1771, 3051, 1003, 4075, 1355, 2379, +331, 3403, 1867, 2635, 587, 3659, 1099, 2123, 75, 3147, 1611, 2891, 843, +3915, 1483, 2507, 459, 3531, 1995, 2699, 651, 3723, 1163, 2187, 139, 3211, +1675, 2955, 907, 3979, 1291, 2315, 267, 3339, 1803, 2571, 523, 3595, 1035, +2059, 11, 3083, 1547, 2827, 779, 3851, 1419, 2443, 395, 3467, 1931, 2763, +715, 3787, 1227, 2251, 203, 3275, 1739, 3019, 971, 4043, 1387, 2411, 363, +3435, 1899, 2667, 619, 3691, 1131, 2155, 107, 3179, 1643, 2923, 875, 3947, +1515, 2539, 491, 3563, 2027, 2747, 699, 3771, 1211, 2235, 187, 3259, 1723, +3003, 955, 4027, 1339, 2363, 315, 3387, 1851, 2619, 571, 3643, 1083, 2107, +59, 3131, 1595, 2875, 827, 3899, 1467, 2491, 443, 3515, 1979, 2811, 763, +3835, 1275, 2299, 251, 3323, 1787, 3067, 1019, 4091, 1363, 2387, 339, 3411, +1875, 2643, 595, 3667, 1107, 2131, 83, 3155, 1619, 2899, 851, 3923, 1491, +2515, 467, 3539, 2003, 2707, 659, 3731, 1171, 2195, 147, 3219, 1683, 2963, +915, 3987, 1299, 2323, 275, 3347, 1811, 2579, 531, 3603, 1043, 2067, 19, +3091, 1555, 2835, 787, 3859, 1427, 2451, 403, 3475, 1939, 2771, 723, 3795, +1235, 2259, 211, 3283, 1747, 3027, 979, 4051, 1395, 2419, 371, 3443, 1907, +2675, 627, 3699, 1139, 2163, 115, 3187, 1651, 2931, 883, 3955, 1523, 2547, +499, 3571, 2035, 2723, 675, 3747, 1187, 2211, 163, 3235, 1699, 2979, 931, +4003, 1315, 2339, 291, 3363, 1827, 2595, 547, 3619, 1059, 2083, 35, 3107, +1571, 2851, 803, 3875, 1443, 2467, 419, 3491, 1955, 2787, 739, 3811, 1251, +2275, 227, 3299, 1763, 3043, 995, 4067, 1347, 2371, 323, 3395, 1859, 2627, +579, 3651, 1091, 2115, 67, 3139, 1603, 2883, 835, 3907, 1475, 2499, 451, +3523, 1987, 2691, 643, 3715, 1155, 2179, 131, 3203, 1667, 2947, 899, 3971, +1283, 2307, 259, 3331, 1795, 2563, 515, 3587, 1027, 2051, 3, 3075, 1539, +2819, 771, 3843, 1411, 2435, 387, 3459, 1923, 2755, 707, 3779, 1219, 2243, +195, 3267, 1731, 3011, 963, 4035, 1379, 2403, 355, 3427, 1891, 2659, 611, +3683, 1123, 2147, 99, 3171, 1635, 2915, 867, 3939, 1507, 2531, 483, 3555, +2019, 2739, 691, 3763, 1203, 2227, 179, 3251, 1715, 2995, 947, 4019, 1331, +2355, 307, 3379, 1843, 2611, 563, 3635, 1075, 2099, 51, 3123, 1587, 2867, +819, 3891, 1459, 2483, 435, 3507, 1971, 2803, 755, 3827, 1267, 2291, 243, +3315, 1779, 3059, 1011, 4083, 1371, 2395, 347, 3419, 1883, 2651, 603, 3675, +1115, 2139, 91, 3163, 1627, 2907, 859, 3931, 1499, 2523, 475, 3547, 2011, +2715, 667, 3739, 1179, 2203, 155, 3227, 1691, 2971, 923, 3995, 1307, 2331, +283, 3355, 1819, 2587, 539, 3611, 1051, 2075, 27, 3099, 1563, 2843, 795, +3867, 1435, 2459, 411, 3483, 1947, 2779, 731, 3803, 1243, 2267, 219, 3291, +1755, 3035, 987, 4059, 1403, 2427, 379, 3451, 1915, 2683, 635, 3707, 1147, +2171, 123, 3195, 1659, 2939, 891, 3963, 1531, 2555, 507, 3579, 2043, 2735, +687, 3759, 1199, 2223, 175, 3247, 1711, 2991, 943, 4015, 1327, 2351, 303, +3375, 1839, 2607, 559, 3631, 1071, 2095, 47, 3119, 1583, 2863, 815, 3887, +1455, 2479, 431, 3503, 1967, 2799, 751, 3823, 1263, 2287, 239, 3311, 1775, +3055, 1007, 4079, 1359, 2383, 335, 3407, 1871, 2639, 591, 3663, 1103, 2127, +79, 3151, 1615, 2895, 847, 3919, 1487, 2511, 463, 3535, 1999, 2703, 655, +3727, 1167, 2191, 143, 3215, 1679, 2959, 911, 3983, 1295, 2319, 271, 3343, +1807, 2575, 527, 3599, 1039, 2063, 15, 3087, 1551, 2831, 783, 3855, 1423, +2447, 399, 3471, 1935, 2767, 719, 3791, 1231, 2255, 207, 3279, 1743, 3023, +975, 4047, 1391, 2415, 367, 3439, 1903, 2671, 623, 3695, 1135, 2159, 111, +3183, 1647, 2927, 879, 3951, 1519, 2543, 495, 3567, 2031, 2751, 703, 3775, +1215, 2239, 191, 3263, 1727, 3007, 959, 4031, 1343, 2367, 319, 3391, 1855, +2623, 575, 3647, 1087, 2111, 63, 3135, 1599, 2879, 831, 3903, 1471, 2495, +447, 3519, 1983, 2815, 767, 3839, 1279, 2303, 255, 3327, 1791, 3071, 1023, +4095, 1365, 2389, 341, 3413, 1877, 2645, 597, 3669, 1109, 2133, 85, 3157, +1621, 2901, 853, 3925, 1493, 2517, 469, 3541, 2005, 2709, 661, 3733, 1173, +2197, 149, 3221, 1685, 2965, 917, 3989, 1301, 2325, 277, 3349, 1813, 2581, +533, 3605, 1045, 2069, 21, 3093, 1557, 2837, 789, 3861, 1429, 2453, 405, +3477, 1941, 2773, 725, 3797, 1237, 2261, 213, 3285, 1749, 3029, 981, 4053, +1397, 2421, 373, 3445, 1909, 2677, 629, 3701, 1141, 2165, 117, 3189, 1653, +2933, 885, 3957, 1525, 2549, 501, 3573, 2037, 2725, 677, 3749, 1189, 2213, +165, 3237, 1701, 2981, 933, 4005, 1317, 2341, 293, 3365, 1829, 2597, 549, +3621, 1061, 2085, 37, 3109, 1573, 2853, 805, 3877, 1445, 2469, 421, 3493, +1957, 2789, 741, 3813, 1253, 2277, 229, 3301, 1765, 3045, 997, 4069, 1349, +2373, 325, 3397, 1861, 2629, 581, 3653, 1093, 2117, 69, 3141, 1605, 2885, +837, 3909, 1477, 2501, 453, 3525, 1989, 2693, 645, 3717, 1157, 2181, 133, +3205, 1669, 2949, 901, 3973, 1285, 2309, 261, 3333, 1797, 2565, 517, 3589, +1029, 2053, 5, 3077, 1541, 2821, 773, 3845, 1413, 2437, 389, 3461, 1925, +2757, 709, 3781, 1221, 2245, 197, 3269, 1733, 3013, 965, 4037, 1381, 2405, +357, 3429, 1893, 2661, 613, 3685, 1125, 2149, 101, 3173, 1637, 2917, 869, +3941, 1509, 2533, 485, 3557, 2021, 2741, 693, 3765, 1205, 2229, 181, 3253, +1717, 2997, 949, 4021, 1333, 2357, 309, 3381, 1845, 2613, 565, 3637, 1077, +2101, 53, 3125, 1589, 2869, 821, 3893, 1461, 2485, 437, 3509, 1973, 2805, +757, 3829, 1269, 2293, 245, 3317, 1781, 3061, 1013, 4085, 1373, 2397, 349, +3421, 1885, 2653, 605, 3677, 1117, 2141, 93, 3165, 1629, 2909, 861, 3933, +1501, 2525, 477, 3549, 2013, 2717, 669, 3741, 1181, 2205, 157, 3229, 1693, +2973, 925, 3997, 1309, 2333, 285, 3357, 1821, 2589, 541, 3613, 1053, 2077, +29, 3101, 1565, 2845, 797, 3869, 1437, 2461, 413, 3485, 1949, 2781, 733, +3805, 1245, 2269, 221, 3293, 1757, 3037, 989, 4061, 1405, 2429, 381, 3453, +1917, 2685, 637, 3709, 1149, 2173, 125, 3197, 1661, 2941, 893, 3965, 1533, +2557, 509, 3581, 2045, 2729, 681, 3753, 1193, 2217, 169, 3241, 1705, 2985, +937, 4009, 1321, 2345, 297, 3369, 1833, 2601, 553, 3625, 1065, 2089, 41, +3113, 1577, 2857, 809, 3881, 1449, 2473, 425, 3497, 1961, 2793, 745, 3817, +1257, 2281, 233, 3305, 1769, 3049, 1001, 4073, 1353, 2377, 329, 3401, 1865, +2633, 585, 3657, 1097, 2121, 73, 3145, 1609, 2889, 841, 3913, 1481, 2505, +457, 3529, 1993, 2697, 649, 3721, 1161, 2185, 137, 3209, 1673, 2953, 905, +3977, 1289, 2313, 265, 3337, 1801, 2569, 521, 3593, 1033, 2057, 9, 3081, +1545, 2825, 777, 3849, 1417, 2441, 393, 3465, 1929, 2761, 713, 3785, 1225, +2249, 201, 3273, 1737, 3017, 969, 4041, 1385, 2409, 361, 3433, 1897, 2665, +617, 3689, 1129, 2153, 105, 3177, 1641, 2921, 873, 3945, 1513, 2537, 489, +3561, 2025, 2745, 697, 3769, 1209, 2233, 185, 3257, 1721, 3001, 953, 4025, +1337, 2361, 313, 3385, 1849, 2617, 569, 3641, 1081, 2105, 57, 3129, 1593, +2873, 825, 3897, 1465, 2489, 441, 3513, 1977, 2809, 761, 3833, 1273, 2297, +249, 3321, 1785, 3065, 1017, 4089, 1361, 2385, 337, 3409, 1873, 2641, 593, +3665, 1105, 2129, 81, 3153, 1617, 2897, 849, 3921, 1489, 2513, 465, 3537, +2001, 2705, 657, 3729, 1169, 2193, 145, 3217, 1681, 2961, 913, 3985, 1297, +2321, 273, 3345, 1809, 2577, 529, 3601, 1041, 2065, 17, 3089, 1553, 2833, +785, 3857, 1425, 2449, 401, 3473, 1937, 2769, 721, 3793, 1233, 2257, 209, +3281, 1745, 3025, 977, 4049, 1393, 2417, 369, 3441, 1905, 2673, 625, 3697, +1137, 2161, 113, 3185, 1649, 2929, 881, 3953, 1521, 2545, 497, 3569, 2033, +2721, 673, 3745, 1185, 2209, 161, 3233, 1697, 2977, 929, 4001, 1313, 2337, +289, 3361, 1825, 2593, 545, 3617, 1057, 2081, 33, 3105, 1569, 2849, 801, +3873, 1441, 2465, 417, 3489, 1953, 2785, 737, 3809, 1249, 2273, 225, 3297, +1761, 3041, 993, 4065, 1345, 2369, 321, 3393, 1857, 2625, 577, 3649, 1089, +2113, 65, 3137, 1601, 2881, 833, 3905, 1473, 2497, 449, 3521, 1985, 2689, +641, 3713, 1153, 2177, 129, 3201, 1665, 2945, 897, 3969, 1281, 2305, 257, +3329, 1793, 2561, 513, 3585, 1025, 2049, 1, 3073, 1537, 2817, 769, 3841, +1409, 2433, 385, 3457, 1921, 2753, 705, 3777, 1217, 2241, 193, 3265, 1729, +3009, 961, 4033, 1377, 2401, 353, 3425, 1889, 2657, 609, 3681, 1121, 2145, +97, 3169, 1633, 2913, 865, 3937, 1505, 2529, 481, 3553, 2017, 2737, 689, +3761, 1201, 2225, 177, 3249, 1713, 2993, 945, 4017, 1329, 2353, 305, 3377, +1841, 2609, 561, 3633, 1073, 2097, 49, 3121, 1585, 2865, 817, 3889, 1457, +2481, 433, 3505, 1969, 2801, 753, 3825, 1265, 2289, 241, 3313, 1777, 3057, +1009, 4081, 1369, 2393, 345, 3417, 1881, 2649, 601, 3673, 1113, 2137, 89, +3161, 1625, 2905, 857, 3929, 1497, 2521, 473, 3545, 2009, 2713, 665, 3737, +1177, 2201, 153, 3225, 1689, 2969, 921, 3993, 1305, 2329, 281, 3353, 1817, +2585, 537, 3609, 1049, 2073, 25, 3097, 1561, 2841, 793, 3865, 1433, 2457, +409, 3481, 1945, 2777, 729, 3801, 1241, 2265, 217, 3289, 1753, 3033, 985, +4057, 1401, 2425, 377, 3449, 1913, 2681, 633, 3705, 1145, 2169, 121, 3193, +1657, 2937, 889, 3961, 1529, 2553, 505, 3577, 2041, 2733, 685, 3757, 1197, +2221, 173, 3245, 1709, 2989, 941, 4013, 1325, 2349, 301, 3373, 1837, 2605, +557, 3629, 1069, 2093, 45, 3117, 1581, 2861, 813, 3885, 1453, 2477, 429, +3501, 1965, 2797, 749, 3821, 1261, 2285, 237, 3309, 1773, 3053, 1005, 4077, +1357, 2381, 333, 3405, 1869, 2637, 589, 3661, 1101, 2125, 77, 3149, 1613, +2893, 845, 3917, 1485, 2509, 461, 3533, 1997, 2701, 653, 3725, 1165, 2189, +141, 3213, 1677, 2957, 909, 3981, 1293, 2317, 269, 3341, 1805, 2573, 525, +3597, 1037, 2061, 13, 3085, 1549, 2829, 781, 3853, 1421, 2445, 397, 3469, +1933, 2765, 717, 3789, 1229, 2253, 205, 3277, 1741, 3021, 973, 4045, 1389, +2413, 365, 3437, 1901, 2669, 621, 3693, 1133, 2157, 109, 3181, 1645, 2925, +877, 3949, 1517, 2541, 493, 3565, 2029, 2749, 701, 3773, 1213, 2237, 189, +3261, 1725, 3005, 957, 4029, 1341, 2365, 317, 3389, 1853, 2621, 573, 3645, +1085, 2109, 61, 3133, 1597, 2877, 829, 3901, 1469, 2493, 445, 3517, 1981, +2813, 765, 3837, 1277, 2301, 253, 3325, 1789, 3069, 1021, 4093, 1367, 2391, +343, 3415, 1879, 2647, 599, 3671, 1111, 2135, 87, 3159, 1623, 2903, 855, +3927, 1495, 2519, 471, 3543, 2007, 2711, 663, 3735, 1175, 2199, 151, 3223, +1687, 2967, 919, 3991, 1303, 2327, 279, 3351, 1815, 2583, 535, 3607, 1047, +2071, 23, 3095, 1559, 2839, 791, 3863, 1431, 2455, 407, 3479, 1943, 2775, +727, 3799, 1239, 2263, 215, 3287, 1751, 3031, 983, 4055, 1399, 2423, 375, +3447, 1911, 2679, 631, 3703, 1143, 2167, 119, 3191, 1655, 2935, 887, 3959, +1527, 2551, 503, 3575, 2039, 2727, 679, 3751, 1191, 2215, 167, 3239, 1703, +2983, 935, 4007, 1319, 2343, 295, 3367, 1831, 2599, 551, 3623, 1063, 2087, +39, 3111, 1575, 2855, 807, 3879, 1447, 2471, 423, 3495, 1959, 2791, 743, +3815, 1255, 2279, 231, 3303, 1767, 3047, 999, 4071, 1351, 2375, 327, 3399, +1863, 2631, 583, 3655, 1095, 2119, 71, 3143, 1607, 2887, 839, 3911, 1479, +2503, 455, 3527, 1991, 2695, 647, 3719, 1159, 2183, 135, 3207, 1671, 2951, +903, 3975, 1287, 2311, 263, 3335, 1799, 2567, 519, 3591, 1031, 2055, 7, +3079, 1543, 2823, 775, 3847, 1415, 2439, 391, 3463, 1927, 2759, 711, 3783, +1223, 2247, 199, 3271, 1735, 3015, 967, 4039, 1383, 2407, 359, 3431, 1895, +2663, 615, 3687, 1127, 2151, 103, 3175, 1639, 2919, 871, 3943, 1511, 2535, +487, 3559, 2023, 2743, 695, 3767, 1207, 2231, 183, 3255, 1719, 2999, 951, +4023, 1335, 2359, 311, 3383, 1847, 2615, 567, 3639, 1079, 2103, 55, 3127, +1591, 2871, 823, 3895, 1463, 2487, 439, 3511, 1975, 2807, 759, 3831, 1271, +2295, 247, 3319, 1783, 3063, 1015, 4087, 1375, 2399, 351, 3423, 1887, 2655, +607, 3679, 1119, 2143, 95, 3167, 1631, 2911, 863, 3935, 1503, 2527, 479, +3551, 2015, 2719, 671, 3743, 1183, 2207, 159, 3231, 1695, 2975, 927, 3999, +1311, 2335, 287, 3359, 1823, 2591, 543, 3615, 1055, 2079, 31, 3103, 1567, +2847, 799, 3871, 1439, 2463, 415, 3487, 1951, 2783, 735, 3807, 1247, 2271, +223, 3295, 1759, 3039, 991, 4063, 1407, 2431, 383, 3455, 1919, 2687, 639, +3711, 1151, 2175, 127, 3199, 1663, 2943, 895, 3967, 1535, 2559, 511, 3583, +2047, 2730, 682, 3754, 1194, 2218, 170, 3242, 1706, 2986, 938, 4010, 1322, +2346, 298, 3370, 1834, 2602, 554, 3626, 1066, 2090, 42, 3114, 1578, 2858, +810, 3882, 1450, 2474, 426, 3498, 1962, 2794, 746, 3818, 1258, 2282, 234, +3306, 1770, 3050, 1002, 4074, 1354, 2378, 330, 3402, 1866, 2634, 586, 3658, +1098, 2122, 74, 3146, 1610, 2890, 842, 3914, 1482, 2506, 458, 3530, 1994, +2698, 650, 3722, 1162, 2186, 138, 3210, 1674, 2954, 906, 3978, 1290, 2314, +266, 3338, 1802, 2570, 522, 3594, 1034, 2058, 10, 3082, 1546, 2826, 778, +3850, 1418, 2442, 394, 3466, 1930, 2762, 714, 3786, 1226, 2250, 202, 3274, +1738, 3018, 970, 4042, 1386, 2410, 362, 3434, 1898, 2666, 618, 3690, 1130, +2154, 106, 3178, 1642, 2922, 874, 3946, 1514, 2538, 490, 3562, 2026, 2746, +698, 3770, 1210, 2234, 186, 3258, 1722, 3002, 954, 4026, 1338, 2362, 314, +3386, 1850, 2618, 570, 3642, 1082, 2106, 58, 3130, 1594, 2874, 826, 3898, +1466, 2490, 442, 3514, 1978, 2810, 762, 3834, 1274, 2298, 250, 3322, 1786, +3066, 1018, 4090, 1362, 2386, 338, 3410, 1874, 2642, 594, 3666, 1106, 2130, +82, 3154, 1618, 2898, 850, 3922, 1490, 2514, 466, 3538, 2002, 2706, 658, +3730, 1170, 2194, 146, 3218, 1682, 2962, 914, 3986, 1298, 2322, 274, 3346, +1810, 2578, 530, 3602, 1042, 2066, 18, 3090, 1554, 2834, 786, 3858, 1426, +2450, 402, 3474, 1938, 2770, 722, 3794, 1234, 2258, 210, 3282, 1746, 3026, +978, 4050, 1394, 2418, 370, 3442, 1906, 2674, 626, 3698, 1138, 2162, 114, +3186, 1650, 2930, 882, 3954, 1522, 2546, 498, 3570, 2034, 2722, 674, 3746, +1186, 2210, 162, 3234, 1698, 2978, 930, 4002, 1314, 2338, 290, 3362, 1826, +2594, 546, 3618, 1058, 2082, 34, 3106, 1570, 2850, 802, 3874, 1442, 2466, +418, 3490, 1954, 2786, 738, 3810, 1250, 2274, 226, 3298, 1762, 3042, 994, +4066, 1346, 2370, 322, 3394, 1858, 2626, 578, 3650, 1090, 2114, 66, 3138, +1602, 2882, 834, 3906, 1474, 2498, 450, 3522, 1986, 2690, 642, 3714, 1154, +2178, 130, 3202, 1666, 2946, 898, 3970, 1282, 2306, 258, 3330, 1794, 2562, +514, 3586, 1026, 2050, 2, 3074, 1538, 2818, 770, 3842, 1410, 2434, 386, +3458, 1922, 2754, 706, 3778, 1218, 2242, 194, 3266, 1730, 3010, 962, 4034, +1378, 2402, 354, 3426, 1890, 2658, 610, 3682, 1122, 2146, 98, 3170, 1634, +2914, 866, 3938, 1506, 2530, 482, 3554, 2018, 2738, 690, 3762, 1202, 2226, +178, 3250, 1714, 2994, 946, 4018, 1330, 2354, 306, 3378, 1842, 2610, 562, +3634, 1074, 2098, 50, 3122, 1586, 2866, 818, 3890, 1458, 2482, 434, 3506, +1970, 2802, 754, 3826, 1266, 2290, 242, 3314, 1778, 3058, 1010, 4082, 1370, +2394, 346, 3418, 1882, 2650, 602, 3674, 1114, 2138, 90, 3162, 1626, 2906, +858, 3930, 1498, 2522, 474, 3546, 2010, 2714, 666, 3738, 1178, 2202, 154, +3226, 1690, 2970, 922, 3994, 1306, 2330, 282, 3354, 1818, 2586, 538, 3610, +1050, 2074, 26, 3098, 1562, 2842, 794, 3866, 1434, 2458, 410, 3482, 1946, +2778, 730, 3802, 1242, 2266, 218, 3290, 1754, 3034, 986, 4058, 1402, 2426, +378, 3450, 1914, 2682, 634, 3706, 1146, 2170, 122, 3194, 1658, 2938, 890, +3962, 1530, 2554, 506, 3578, 2042, 2734, 686, 3758, 1198, 2222, 174, 3246, +1710, 2990, 942, 4014, 1326, 2350, 302, 3374, 1838, 2606, 558, 3630, 1070, +2094, 46, 3118, 1582, 2862, 814, 3886, 1454, 2478, 430, 3502, 1966, 2798, +750, 3822, 1262, 2286, 238, 3310, 1774, 3054, 1006, 4078, 1358, 2382, 334, +3406, 1870, 2638, 590, 3662, 1102, 2126, 78, 3150, 1614, 2894, 846, 3918, +1486, 2510, 462, 3534, 1998, 2702, 654, 3726, 1166, 2190, 142, 3214, 1678, +2958, 910, 3982, 1294, 2318, 270, 3342, 1806, 2574, 526, 3598, 1038, 2062, +14, 3086, 1550, 2830, 782, 3854, 1422, 2446, 398, 3470, 1934, 2766, 718, +3790, 1230, 2254, 206, 3278, 1742, 3022, 974, 4046, 1390, 2414, 366, 3438, +1902, 2670, 622, 3694, 1134, 2158, 110, 3182, 1646, 2926, 878, 3950, 1518, +2542, 494, 3566, 2030, 2750, 702, 3774, 1214, 2238, 190, 3262, 1726, 3006, +958, 4030, 1342, 2366, 318, 3390, 1854, 2622, 574, 3646, 1086, 2110, 62, +3134, 1598, 2878, 830, 3902, 1470, 2494, 446, 3518, 1982, 2814, 766, 3838, +1278, 2302, 254, 3326, 1790, 3070, 1022, 4094, 1364, 2388, 340, 3412, 1876, +2644, 596, 3668, 1108, 2132, 84, 3156, 1620, 2900, 852, 3924, 1492, 2516, +468, 3540, 2004, 2708, 660, 3732, 1172, 2196, 148, 3220, 1684, 2964, 916, +3988, 1300, 2324, 276, 3348, 1812, 2580, 532, 3604, 1044, 2068, 20, 3092, +1556, 2836, 788, 3860, 1428, 2452, 404, 3476, 1940, 2772, 724, 3796, 1236, +2260, 212, 3284, 1748, 3028, 980, 4052, 1396, 2420, 372, 3444, 1908, 2676, +628, 3700, 1140, 2164, 116, 3188, 1652, 2932, 884, 3956, 1524, 2548, 500, +3572, 2036, 2724, 676, 3748, 1188, 2212, 164, 3236, 1700, 2980, 932, 4004, +1316, 2340, 292, 3364, 1828, 2596, 548, 3620, 1060, 2084, 36, 3108, 1572, +2852, 804, 3876, 1444, 2468, 420, 3492, 1956, 2788, 740, 3812, 1252, 2276, +228, 3300, 1764, 3044, 996, 4068, 1348, 2372, 324, 3396, 1860, 2628, 580, +3652, 1092, 2116, 68, 3140, 1604, 2884, 836, 3908, 1476, 2500, 452, 3524, +1988, 2692, 644, 3716, 1156, 2180, 132, 3204, 1668, 2948, 900, 3972, 1284, +2308, 260, 3332, 1796, 2564, 516, 3588, 1028, 2052, 4, 3076, 1540, 2820, +772, 3844, 1412, 2436, 388, 3460, 1924, 2756, 708, 3780, 1220, 2244, 196, +3268, 1732, 3012, 964, 4036, 1380, 2404, 356, 3428, 1892, 2660, 612, 3684, +1124, 2148, 100, 3172, 1636, 2916, 868, 3940, 1508, 2532, 484, 3556, 2020, +2740, 692, 3764, 1204, 2228, 180, 3252, 1716, 2996, 948, 4020, 1332, 2356, +308, 3380, 1844, 2612, 564, 3636, 1076, 2100, 52, 3124, 1588, 2868, 820, +3892, 1460, 2484, 436, 3508, 1972, 2804, 756, 3828, 1268, 2292, 244, 3316, +1780, 3060, 1012, 4084, 1372, 2396, 348, 3420, 1884, 2652, 604, 3676, 1116, +2140, 92, 3164, 1628, 2908, 860, 3932, 1500, 2524, 476, 3548, 2012, 2716, +668, 3740, 1180, 2204, 156, 3228, 1692, 2972, 924, 3996, 1308, 2332, 284, +3356, 1820, 2588, 540, 3612, 1052, 2076, 28, 3100, 1564, 2844, 796, 3868, +1436, 2460, 412, 3484, 1948, 2780, 732, 3804, 1244, 2268, 220, 3292, 1756, +3036, 988, 4060, 1404, 2428, 380, 3452, 1916, 2684, 636, 3708, 1148, 2172, +124, 3196, 1660, 2940, 892, 3964, 1532, 2556, 508, 3580, 2044, 2728, 680, +3752, 1192, 2216, 168, 3240, 1704, 2984, 936, 4008, 1320, 2344, 296, 3368, +1832, 2600, 552, 3624, 1064, 2088, 40, 3112, 1576, 2856, 808, 3880, 1448, +2472, 424, 3496, 1960, 2792, 744, 3816, 1256, 2280, 232, 3304, 1768, 3048, +1000, 4072, 1352, 2376, 328, 3400, 1864, 2632, 584, 3656, 1096, 2120, 72, +3144, 1608, 2888, 840, 3912, 1480, 2504, 456, 3528, 1992, 2696, 648, 3720, +1160, 2184, 136, 3208, 1672, 2952, 904, 3976, 1288, 2312, 264, 3336, 1800, +2568, 520, 3592, 1032, 2056, 8, 3080, 1544, 2824, 776, 3848, 1416, 2440, +392, 3464, 1928, 2760, 712, 3784, 1224, 2248, 200, 3272, 1736, 3016, 968, +4040, 1384, 2408, 360, 3432, 1896, 2664, 616, 3688, 1128, 2152, 104, 3176, +1640, 2920, 872, 3944, 1512, 2536, 488, 3560, 2024, 2744, 696, 3768, 1208, +2232, 184, 3256, 1720, 3000, 952, 4024, 1336, 2360, 312, 3384, 1848, 2616, +568, 3640, 1080, 2104, 56, 3128, 1592, 2872, 824, 3896, 1464, 2488, 440, +3512, 1976, 2808, 760, 3832, 1272, 2296, 248, 3320, 1784, 3064, 1016, 4088, +1360, 2384, 336, 3408, 1872, 2640, 592, 3664, 1104, 2128, 80, 3152, 1616, +2896, 848, 3920, 1488, 2512, 464, 3536, 2000, 2704, 656, 3728, 1168, 2192, +144, 3216, 1680, 2960, 912, 3984, 1296, 2320, 272, 3344, 1808, 2576, 528, +3600, 1040, 2064, 16, 3088, 1552, 2832, 784, 3856, 1424, 2448, 400, 3472, +1936, 2768, 720, 3792, 1232, 2256, 208, 3280, 1744, 3024, 976, 4048, 1392, +2416, 368, 3440, 1904, 2672, 624, 3696, 1136, 2160, 112, 3184, 1648, 2928, +880, 3952, 1520, 2544, 496, 3568, 2032, 2720, 672, 3744, 1184, 2208, 160, +3232, 1696, 2976, 928, 4000, 1312, 2336, 288, 3360, 1824, 2592, 544, 3616, +1056, 2080, 32, 3104, 1568, 2848, 800, 3872, 1440, 2464, 416, 3488, 1952, +2784, 736, 3808, 1248, 2272, 224, 3296, 1760, 3040, 992, 4064, 1344, 2368, +320, 3392, 1856, 2624, 576, 3648, 1088, 2112, 64, 3136, 1600, 2880, 832, +3904, 1472, 2496, 448, 3520, 1984, 2688, 640, 3712, 1152, 2176, 128, 3200, +1664, 2944, 896, 3968, 1280, 2304, 256, 3328, 1792, 2560, 512, 3584, 1024, +2048}; + + diff --git a/plugins/wma/libwma/mdct_lookup.h b/plugins/wma/libwma/mdct_lookup.h new file mode 100644 index 00000000..909b95dd --- /dev/null +++ b/plugins/wma/libwma/mdct_lookup.h @@ -0,0 +1,24 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * + * * + ******************************************************************** + + function: sin,cos lookup tables + + ********************************************************************/ + + +extern const int32_t sincos_lookup0[1026]; +extern const int32_t sincos_lookup1[1024]; +extern const uint16_t revtab[1<<12]; + + + diff --git a/plugins/wma/libwma/types.h b/plugins/wma/libwma/types.h new file mode 100644 index 00000000..dc65cf3e --- /dev/null +++ b/plugins/wma/libwma/types.h @@ -0,0 +1,3 @@ +#define fixed32 int32_t +#define fixed64 int64_t + diff --git a/plugins/wma/libwma/wmadata.h b/plugins/wma/libwma/wmadata.h new file mode 100644 index 00000000..b8df54a8 --- /dev/null +++ b/plugins/wma/libwma/wmadata.h @@ -0,0 +1,2612 @@ +/* + * WMA compatible decoder + * copyright (c) 2002 The FFmpeg Project + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file wmadata.h + * Various WMA tables. + */ + +static const uint16_t wma_critical_freqs[25] = { + 100, 200, 300, 400, 510, 630, 770, 920, + 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, + 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, + 24500, +}; + +/* first value is number of bands */ +static const uint8_t exponent_band_22050[3][25] = { + { 10, 4, 8, 4, 8, 8, 12, 20, 24, 24, 16, }, + { 14, 4, 8, 8, 4, 12, 12, 16, 24, 16, 20, 24, 32, 40, 36, }, + { 23, 4, 4, 4, 8, 4, 4, 8, 8, 8, 8, 8, 12, 12, 16, 16, 24, 24, 32, 44, 48, 60, 84, 72, }, +}; + +static const uint8_t exponent_band_32000[3][25] = { + { 11, 4, 4, 8, 4, 4, 12, 16, 24, 20, 28, 4, }, + { 15, 4, 8, 4, 4, 8, 8, 16, 20, 12, 20, 20, 28, 40, 56, 8, }, + { 16, 8, 4, 8, 8, 12, 16, 20, 24, 40, 32, 32, 44, 56, 80, 112, 16, }, +}; + +static const uint8_t exponent_band_44100[3][25] = { + { 12, 4, 4, 4, 4, 4, 8, 8, 8, 12, 16, 20, 36, }, + { 15, 4, 8, 4, 8, 8, 4, 8, 8, 12, 12, 12, 24, 28, 40, 76, }, + { 17, 4, 8, 8, 4, 12, 12, 8, 8, 24, 16, 20, 24, 32, 40, 60, 80, 152, }, +}; + +static const uint16_t hgain_huffcodes[37] = { + 0x00003, 0x002e7, 0x00001, 0x005cd, 0x0005d, 0x005c9, 0x0005e, 0x00003, + 0x00016, 0x0000b, 0x00001, 0x00006, 0x00001, 0x00006, 0x00004, 0x00005, + 0x00004, 0x00007, 0x00003, 0x00007, 0x00004, 0x0000a, 0x0000a, 0x00002, + 0x00003, 0x00000, 0x00005, 0x00002, 0x0005f, 0x00004, 0x00003, 0x00002, + 0x005c8, 0x000b8, 0x005ca, 0x005cb, 0x005cc, +}; + +static const uint8_t hgain_huffbits[37] = { + 10, 12, 10, 13, 9, 13, 9, 8, + 7, 5, 5, 4, 4, 3, 3, 3, + 4, 3, 4, 4, 5, 5, 6, 8, + 7, 10, 8, 10, 9, 8, 9, 9, + 13, 10, 13, 13, 13, +}; + +static const fixed32 lsp_codebook[NB_LSP_COEFS][16] = { +{0x1fcc2,0x1fabd,0x1f8c7,0x1f66d,0x1f34c,0x1eef1,0x1e83e,0x1dca6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, +{0x1f8fc,0x1f5f9,0x1f328,0x1f025,0x1ecd8,0x1e8fc,0x1e46f,0x1df1b,0x1d87c,0x1d047,0x1c6b5,0x1bb8f,0x1add8,0x19c0e,0x18220,0x154ca}, +{0x1e6ae,0x1dd65,0x1d58e,0x1cd3b,0x1c439,0x1ba69,0x1af5e,0x1a32c,0x195c4,0x18498,0x16fd2,0x156ea,0x13de4,0x11f63,0xf7ae,0xbd90}, +{0x1c4fa,0x1ada0,0x19976,0x1891d,0x17986,0x1697f,0x15858,0x145fd,0x1316b,0x11900,0xfcfa,0xdf55,0xbe63,0x9902,0x6e83,0x2e05}, +{0x16f2d,0x15205,0x135f3,0x11b14,0x10170,0xe743,0xcdec,0xb504,0x9ab2,0x7f86,0x6296,0x4565,0x24e2,0x90,0xffffd52f,0xffffa172}, +{0xffbc,0xd786,0xb521,0x943e,0x7876,0x5ea3,0x44ad,0x2bf0,0x1274,0xfffff829,0xfffe9981,0xffffbfab,0xffffa0bb,0xffff7d3f,0xffff59e3,0xffff3269}, +{0x43e1,0x102a,0xffffe94a,0xffffc9fa,0xffffb076,0xffff9a6b,0xffff871c,0xffff7555,0xffff62b4,0xffff4f81,0xffff3bf4,0xffff25f7,0xffff0c0f,0xfffeef53,0xfffecb7e,0xfffe9fb3}, +{0xffff75ea,0xffff4325,0xffff1da2,0xfffefd23,0xfffeddb9,0xfffebb51,0xfffe945f,0xfffe6131,0xfffee5fe,0xfffed5ba,0xfffec442,0xfffeb224,0xfffe9f95,0xfffe880e,0xfffe6c7a,0xfffe54c1}, +{0xffff9d2e,0xffff709e,0xffff5489,0xffff3d5e,0xffff295b,0xffff1761,0xffff06a2,0xfffef68a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, +{0xfffe7045,0xfffe572f,0xfffe45ea,0xfffe38af,0xfffe2d8f,0xfffe2347,0xfffe18df,0xfffe0d42,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0} +}; + +static const uint32_t scale_huffcodes[121] = { + 0x3ffe8, 0x3ffe6, 0x3ffe7, 0x3ffe5, 0x7fff5, 0x7fff1, 0x7ffed, 0x7fff6, + 0x7ffee, 0x7ffef, 0x7fff0, 0x7fffc, 0x7fffd, 0x7ffff, 0x7fffe, 0x7fff7, + 0x7fff8, 0x7fffb, 0x7fff9, 0x3ffe4, 0x7fffa, 0x3ffe3, 0x1ffef, 0x1fff0, + 0x0fff5, 0x1ffee, 0x0fff2, 0x0fff3, 0x0fff4, 0x0fff1, 0x07ff6, 0x07ff7, + 0x03ff9, 0x03ff5, 0x03ff7, 0x03ff3, 0x03ff6, 0x03ff2, 0x01ff7, 0x01ff5, + 0x00ff9, 0x00ff7, 0x00ff6, 0x007f9, 0x00ff4, 0x007f8, 0x003f9, 0x003f7, + 0x003f5, 0x001f8, 0x001f7, 0x000fa, 0x000f8, 0x000f6, 0x00079, 0x0003a, + 0x00038, 0x0001a, 0x0000b, 0x00004, 0x00000, 0x0000a, 0x0000c, 0x0001b, + 0x00039, 0x0003b, 0x00078, 0x0007a, 0x000f7, 0x000f9, 0x001f6, 0x001f9, + 0x003f4, 0x003f6, 0x003f8, 0x007f5, 0x007f4, 0x007f6, 0x007f7, 0x00ff5, + 0x00ff8, 0x01ff4, 0x01ff6, 0x01ff8, 0x03ff8, 0x03ff4, 0x0fff0, 0x07ff4, + 0x0fff6, 0x07ff5, 0x3ffe2, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, + 0x7ffde, 0x7ffd8, 0x7ffd2, 0x7ffd3, 0x7ffd4, 0x7ffd5, 0x7ffd6, 0x7fff2, + 0x7ffdf, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffe6, 0x7ffe0, + 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffd7, 0x7ffec, 0x7fff4, + 0x7fff3, +}; + +static const uint8_t scale_huffbits[121] = { + 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 18, 19, 18, 17, 17, + 16, 17, 16, 16, 16, 16, 15, 15, + 14, 14, 14, 14, 14, 14, 13, 13, + 12, 12, 12, 11, 12, 11, 10, 10, + 10, 9, 9, 8, 8, 8, 7, 6, + 6, 5, 4, 3, 1, 4, 4, 5, + 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 10, 11, 11, 11, 11, 12, + 12, 13, 13, 13, 14, 14, 16, 15, + 16, 15, 18, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, +}; + +static const uint32_t coef0_huffcodes[666] = { + 0x00258, 0x0003d, 0x00000, 0x00005, 0x00008, 0x00008, 0x0000c, 0x0001b, + 0x0001f, 0x00015, 0x00024, 0x00032, 0x0003a, 0x00026, 0x0002c, 0x0002f, + 0x0004a, 0x0004d, 0x00061, 0x00070, 0x00073, 0x00048, 0x00052, 0x0005a, + 0x0005d, 0x0006e, 0x00099, 0x0009e, 0x000c1, 0x000ce, 0x000e4, 0x000f0, + 0x00093, 0x0009e, 0x000a2, 0x000a1, 0x000b8, 0x000d2, 0x000d3, 0x0012e, + 0x00130, 0x000de, 0x0012d, 0x0019b, 0x001e4, 0x00139, 0x0013a, 0x0013f, + 0x0014f, 0x0016d, 0x001a2, 0x0027c, 0x0027e, 0x00332, 0x0033c, 0x0033f, + 0x0038b, 0x00396, 0x003c5, 0x00270, 0x0027c, 0x0025a, 0x00395, 0x00248, + 0x004bd, 0x004fb, 0x00662, 0x00661, 0x0071b, 0x004e6, 0x004ff, 0x00666, + 0x0071c, 0x0071a, 0x0071f, 0x00794, 0x00536, 0x004e2, 0x0078e, 0x004ee, + 0x00518, 0x00535, 0x004fb, 0x0078d, 0x00530, 0x00680, 0x0068f, 0x005cb, + 0x00965, 0x006a6, 0x00967, 0x0097f, 0x00682, 0x006ae, 0x00cd0, 0x00e28, + 0x00f13, 0x00f1f, 0x009f5, 0x00cd3, 0x00f11, 0x00926, 0x00964, 0x00f32, + 0x00f12, 0x00f30, 0x00966, 0x00d0b, 0x00a68, 0x00b91, 0x009c7, 0x00b73, + 0x012fa, 0x0131d, 0x013f9, 0x01ca0, 0x0199c, 0x01c7a, 0x0198c, 0x01248, + 0x01c74, 0x01c64, 0x0139e, 0x012fd, 0x00a77, 0x012fc, 0x01c7b, 0x012ca, + 0x014cc, 0x014d2, 0x014e3, 0x014dc, 0x012dc, 0x03344, 0x02598, 0x0263c, + 0x0333b, 0x025e6, 0x01a1c, 0x01e3c, 0x014e2, 0x033d4, 0x01a11, 0x03349, + 0x03cce, 0x014e1, 0x01a34, 0x0273e, 0x02627, 0x0273f, 0x038ee, 0x03971, + 0x03c67, 0x03c61, 0x0333d, 0x038c2, 0x0263f, 0x038cd, 0x02638, 0x02e41, + 0x0351f, 0x03348, 0x03c66, 0x03562, 0x02989, 0x027d5, 0x0333c, 0x02e4f, + 0x0343b, 0x02ddf, 0x04bc8, 0x029c0, 0x02e57, 0x04c72, 0x025b7, 0x03547, + 0x03540, 0x029d3, 0x04c45, 0x025bb, 0x06600, 0x04c73, 0x04bce, 0x0357b, + 0x029a6, 0x029d2, 0x0263e, 0x0298a, 0x07183, 0x06602, 0x07958, 0x04b66, + 0x0537d, 0x05375, 0x04fe9, 0x04b67, 0x0799f, 0x04bc9, 0x051fe, 0x06a3b, + 0x05bb6, 0x04fa8, 0x0728f, 0x05376, 0x0492c, 0x0537e, 0x0795a, 0x06a3c, + 0x0e515, 0x07887, 0x0683a, 0x051f9, 0x051fd, 0x0cc6a, 0x06a8a, 0x0cc6d, + 0x05bb3, 0x0683b, 0x051fc, 0x05378, 0x0728e, 0x07886, 0x05bb7, 0x0f2a4, + 0x0795b, 0x0683c, 0x09fc1, 0x0683d, 0x0b752, 0x09678, 0x0a3e8, 0x06ac7, + 0x051f0, 0x0b759, 0x06af3, 0x04b6b, 0x0f2a0, 0x0f2ad, 0x096c3, 0x0e518, + 0x0b75c, 0x0d458, 0x0cc6b, 0x0537c, 0x067aa, 0x04fea, 0x0343a, 0x0cc71, + 0x0967f, 0x09fc4, 0x096c2, 0x0e516, 0x0f2a1, 0x0d45c, 0x0d45d, 0x0d45e, + 0x12fb9, 0x0967e, 0x1982f, 0x09883, 0x096c4, 0x0b753, 0x12fb8, 0x0f2a8, + 0x1ca21, 0x096c5, 0x0e51a, 0x1ca27, 0x12f3c, 0x0d471, 0x0f2aa, 0x0b75b, + 0x12fbb, 0x0f2a9, 0x0f2ac, 0x0d45a, 0x0b74f, 0x096c8, 0x16e91, 0x096ca, + 0x12fbf, 0x0d0a7, 0x13103, 0x0d516, 0x16e99, 0x12cbd, 0x0a3ea, 0x19829, + 0x0b755, 0x29ba7, 0x1ca28, 0x29ba5, 0x16e93, 0x1982c, 0x19828, 0x25994, + 0x0a3eb, 0x1ca29, 0x16e90, 0x1ca25, 0x1982d, 0x1ca26, 0x16e9b, 0x0b756, + 0x0967c, 0x25997, 0x0b75f, 0x198d3, 0x0b757, 0x19a2a, 0x0d45b, 0x0e517, + 0x1ca24, 0x1ca23, 0x1ca22, 0x0b758, 0x16e97, 0x0cd14, 0x13100, 0x00007, + 0x0003b, 0x0006b, 0x00097, 0x00138, 0x00125, 0x00173, 0x00258, 0x00335, + 0x0028e, 0x004c6, 0x00715, 0x00729, 0x004ef, 0x00519, 0x004ed, 0x00532, + 0x0068c, 0x00686, 0x00978, 0x00e5d, 0x00e31, 0x009f4, 0x00b92, 0x012f8, + 0x00d06, 0x00a67, 0x00d44, 0x00a76, 0x00d59, 0x012cd, 0x01c78, 0x01c75, + 0x0199f, 0x0198f, 0x01c67, 0x014c6, 0x01c79, 0x01c76, 0x00b94, 0x00d1b, + 0x01e32, 0x01e31, 0x01ab0, 0x01a05, 0x01aa1, 0x0333a, 0x025e5, 0x02626, + 0x03541, 0x03544, 0x03421, 0x03546, 0x02e55, 0x02e56, 0x0492d, 0x02dde, + 0x0299b, 0x02ddc, 0x0357a, 0x0249c, 0x0668b, 0x1c77f, 0x1ca20, 0x0d45f, + 0x09886, 0x16e9a, 0x0f2a7, 0x0b751, 0x0a3ee, 0x0cf59, 0x0cf57, 0x0b754, + 0x0d0a6, 0x16e98, 0x0b760, 0x06ac6, 0x0a3f0, 0x12fbe, 0x13104, 0x0f2a5, + 0x0a3ef, 0x0d472, 0x12cba, 0x1982e, 0x16e9c, 0x1c77e, 0x198d0, 0x13105, + 0x16e92, 0x0b75d, 0x0d459, 0x0001a, 0x000c0, 0x0016c, 0x003cd, 0x00350, + 0x0067b, 0x0051e, 0x006a9, 0x009f4, 0x00b72, 0x00d09, 0x01249, 0x01e3d, + 0x01ca1, 0x01a1f, 0x01721, 0x01a8a, 0x016e8, 0x03347, 0x01a35, 0x0249d, + 0x0299a, 0x02596, 0x02e4e, 0x0298b, 0x07182, 0x04c46, 0x025ba, 0x02e40, + 0x027d6, 0x04fe8, 0x06607, 0x05310, 0x09884, 0x072e1, 0x06a3d, 0x04b6a, + 0x04c7a, 0x06603, 0x04c7b, 0x03428, 0x06605, 0x09664, 0x09fc0, 0x071de, + 0x06601, 0x05bb2, 0x09885, 0x0a3e2, 0x1c61f, 0x12cbb, 0x0b750, 0x0cf58, + 0x0967d, 0x25995, 0x668ad, 0x0b75a, 0x09fc2, 0x0537f, 0x0b75e, 0x13fae, + 0x12fbc, 0x00031, 0x001c4, 0x004c5, 0x005b8, 0x00cf4, 0x0096f, 0x00d46, + 0x01e57, 0x01a04, 0x02625, 0x03346, 0x028f9, 0x04c47, 0x072e0, 0x04b69, + 0x03420, 0x07957, 0x06639, 0x0799e, 0x07959, 0x07881, 0x04b68, 0x09fc3, + 0x09fd6, 0x0cc70, 0x0a3f1, 0x12cbe, 0x0e30e, 0x0e51b, 0x06af2, 0x12cbc, + 0x1c77d, 0x0f2ab, 0x12fbd, 0x1aa2f, 0x0a3ec, 0x0d473, 0x05377, 0x0a3e9, + 0x1982b, 0x0e300, 0x12f3f, 0x0cf5f, 0x096c0, 0x38c3c, 0x16e94, 0x16e95, + 0x12f3d, 0x29ba4, 0x29ba6, 0x1c77c, 0x6a8ba, 0x3545c, 0x33457, 0x668ac, + 0x6a8bb, 0x16e9d, 0x0e519, 0x25996, 0x12f3e, 0x00036, 0x0033e, 0x006ad, + 0x00d03, 0x012c8, 0x0124a, 0x03c42, 0x03ccd, 0x06606, 0x07880, 0x06852, + 0x06a3a, 0x05bb4, 0x0f2a2, 0x09fc7, 0x12cb9, 0x0cc6c, 0x0a6e8, 0x096c1, + 0x0004a, 0x00355, 0x012f9, 0x014e8, 0x01abe, 0x025b6, 0x0492e, 0x09fc6, + 0x051ff, 0x0cc6f, 0x096cb, 0x0d071, 0x198d1, 0x12cb8, 0x38c3d, 0x13faf, + 0x096c9, 0x0009d, 0x00539, 0x012ce, 0x0341f, 0x029c1, 0x04b33, 0x0a3e3, + 0x0d070, 0x16e96, 0x0b763, 0x000a0, 0x009ce, 0x038cc, 0x0343d, 0x051fa, + 0x09888, 0x12fba, 0x000df, 0x00a75, 0x029a7, 0x09fc5, 0x0e301, 0x0967b, + 0x001e7, 0x012c9, 0x051fb, 0x09889, 0x0f2a6, 0x0016f, 0x01cb9, 0x0cf5a, + 0x12cbf, 0x09679, 0x00272, 0x01a15, 0x0967a, 0x003cb, 0x025f6, 0x0b762, + 0x0028d, 0x03c60, 0x0cf5e, 0x00352, 0x03ccc, 0x0072f, 0x07186, 0x004ec, + 0x05379, 0x0068e, 0x09887, 0x006a7, 0x06af1, 0x00e29, 0x0cf5b, 0x00f31, + 0x0d470, 0x009c6, 0x013fb, 0x13102, 0x019a5, 0x13101, 0x01983, 0x01c65, + 0x0124f, 0x014c7, 0x01726, 0x01abf, 0x03304, 0x02624, 0x03c41, 0x027d7, + 0x02ddd, 0x02e54, 0x0343c, 0x06604, 0x07181, 0x0663a, 0x04fa9, 0x0663b, + 0x05311, 0x0537a, 0x06839, 0x05bb5, 0x0492f, 0x06af0, 0x096c7, 0x0cc6e, + 0x0537b, 0x0cf5c, 0x0cf56, 0x198d2, 0x0cf5d, 0x0a3ed, 0x0f2a3, 0x1982a, + 0x0b761, 0x096c6, +}; + +static const uint8_t coef0_huffbits[666] = { + 11, 6, 2, 3, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 10, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 11, 12, + 12, 12, 12, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 13, 13, 12, + 12, 12, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 14, + 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 13, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 15, + 15, 14, 14, 15, 15, 15, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 14, 15, 15, 15, 15, 16, + 16, 16, 15, 16, 15, 15, 16, 16, + 16, 16, 15, 16, 16, 16, 15, 16, + 16, 15, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 15, 15, 16, 16, + 15, 16, 16, 16, 17, 17, 17, 16, + 16, 17, 16, 16, 16, 16, 17, 16, + 17, 17, 16, 16, 15, 15, 15, 16, + 17, 16, 17, 16, 16, 17, 17, 17, + 17, 17, 17, 16, 17, 17, 17, 16, + 17, 17, 16, 17, 17, 17, 16, 17, + 17, 16, 16, 17, 17, 17, 18, 17, + 17, 17, 17, 17, 18, 18, 17, 17, + 17, 19, 17, 19, 18, 17, 17, 18, + 17, 17, 18, 17, 17, 17, 18, 17, + 17, 18, 17, 17, 17, 17, 17, 16, + 17, 17, 17, 17, 18, 16, 17, 4, + 6, 8, 9, 9, 10, 10, 10, 10, + 11, 11, 11, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 14, 13, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 16, 15, + 15, 15, 15, 15, 15, 17, 17, 17, + 16, 18, 16, 17, 17, 16, 16, 17, + 17, 18, 17, 16, 17, 17, 17, 16, + 17, 17, 18, 17, 18, 17, 17, 17, + 18, 17, 17, 5, 8, 10, 10, 11, + 11, 12, 12, 12, 13, 13, 14, 13, + 13, 14, 14, 14, 14, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 16, 16, 15, 16, 16, + 15, 15, 15, 15, 15, 16, 16, 15, + 15, 16, 16, 17, 17, 18, 17, 16, + 17, 18, 19, 17, 16, 16, 17, 17, + 17, 6, 9, 11, 12, 12, 13, 13, + 13, 14, 14, 14, 15, 15, 15, 16, + 15, 15, 15, 15, 15, 15, 16, 16, + 16, 16, 17, 18, 16, 16, 16, 18, + 17, 16, 17, 18, 17, 17, 16, 17, + 17, 16, 17, 16, 17, 18, 18, 18, + 17, 19, 19, 17, 20, 19, 18, 19, + 20, 18, 16, 18, 17, 7, 10, 12, + 13, 13, 14, 14, 14, 15, 15, 16, + 16, 16, 16, 16, 18, 16, 17, 17, + 8, 11, 13, 14, 14, 15, 16, 16, + 16, 16, 17, 17, 17, 18, 18, 17, + 17, 8, 12, 14, 15, 15, 15, 17, + 17, 18, 17, 9, 12, 14, 15, 16, + 16, 17, 9, 13, 15, 16, 16, 17, + 9, 13, 16, 16, 16, 10, 13, 16, + 18, 17, 10, 14, 17, 10, 14, 17, + 11, 14, 16, 11, 14, 11, 15, 12, + 16, 12, 16, 12, 16, 12, 16, 12, + 17, 13, 13, 17, 13, 17, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 16, 15, + 16, 16, 16, 16, 16, 16, 17, 16, + 16, 16, 16, 17, 16, 17, 16, 17, + 17, 17, +}; + +static const uint32_t coef1_huffcodes[555] = { + 0x00115, 0x00002, 0x00001, 0x00000, 0x0000d, 0x00007, 0x00013, 0x0001d, + 0x00008, 0x0000c, 0x00023, 0x0002b, 0x0003f, 0x00017, 0x0001b, 0x00043, + 0x00049, 0x00050, 0x00055, 0x00054, 0x00067, 0x00064, 0x0007b, 0x0002d, + 0x00028, 0x0002a, 0x00085, 0x00089, 0x0002b, 0x00035, 0x00090, 0x00091, + 0x00094, 0x00088, 0x000c1, 0x000c6, 0x000f2, 0x000e3, 0x000c5, 0x000e2, + 0x00036, 0x000f0, 0x000a7, 0x000cd, 0x000fb, 0x00059, 0x00116, 0x00103, + 0x00108, 0x0012b, 0x0012d, 0x00188, 0x0012e, 0x0014c, 0x001c3, 0x00187, + 0x001e7, 0x0006f, 0x00094, 0x00069, 0x001e6, 0x001ca, 0x00147, 0x00195, + 0x000a7, 0x00213, 0x00209, 0x00303, 0x00295, 0x00289, 0x0028c, 0x0028d, + 0x00312, 0x00330, 0x0029b, 0x00308, 0x00328, 0x0029a, 0x0025e, 0x003c5, + 0x00384, 0x0039f, 0x00397, 0x00296, 0x0032e, 0x00332, 0x003c6, 0x003e6, + 0x0012d, 0x000d1, 0x00402, 0x000dd, 0x00161, 0x0012b, 0x00127, 0x0045d, + 0x00601, 0x004ab, 0x0045f, 0x00410, 0x004bf, 0x00528, 0x0045c, 0x00424, + 0x00400, 0x00511, 0x00618, 0x0073d, 0x0063a, 0x00614, 0x0073c, 0x007c0, + 0x007cf, 0x00802, 0x00966, 0x00964, 0x00951, 0x008a0, 0x00346, 0x00803, + 0x00a52, 0x0024a, 0x007c1, 0x0063f, 0x00126, 0x00406, 0x00789, 0x008a2, + 0x00960, 0x00967, 0x00c05, 0x00c70, 0x00c79, 0x00a5d, 0x00c26, 0x00c4d, + 0x00372, 0x008a5, 0x00c08, 0x002c5, 0x00f11, 0x00cc4, 0x00f8e, 0x00e16, + 0x00496, 0x00e77, 0x00f9c, 0x00c25, 0x00f1e, 0x00c27, 0x00f1f, 0x00e17, + 0x00ccd, 0x00355, 0x00c09, 0x00c78, 0x00f90, 0x00521, 0x00357, 0x00356, + 0x0068e, 0x00f9d, 0x00c04, 0x00e58, 0x00a20, 0x00a2c, 0x00c4c, 0x0052f, + 0x00f8d, 0x01178, 0x01053, 0x01097, 0x0180f, 0x0180d, 0x012fb, 0x012aa, + 0x0202a, 0x00a40, 0x018ed, 0x01ceb, 0x01455, 0x018e3, 0x012a1, 0x00354, + 0x00353, 0x00f1c, 0x00c7b, 0x00c37, 0x0101d, 0x012cb, 0x01142, 0x0197d, + 0x01095, 0x01e3b, 0x0186b, 0x00588, 0x01c2a, 0x014b8, 0x01e3a, 0x018ec, + 0x01f46, 0x012fa, 0x00a53, 0x01ce8, 0x00a55, 0x01c29, 0x0117b, 0x01052, + 0x012a0, 0x00589, 0x00950, 0x01c2b, 0x00a50, 0x0208b, 0x0180e, 0x02027, + 0x02556, 0x01e20, 0x006e7, 0x01c28, 0x0197a, 0x00684, 0x020a2, 0x01f22, + 0x03018, 0x039cf, 0x03e25, 0x02557, 0x0294c, 0x028a6, 0x00d11, 0x028a9, + 0x02979, 0x00d46, 0x00a56, 0x039ce, 0x030cc, 0x0329a, 0x0149d, 0x0510f, + 0x0451c, 0x02028, 0x03299, 0x01ced, 0x014b9, 0x00f85, 0x00c7a, 0x01800, + 0x00341, 0x012ca, 0x039c8, 0x0329d, 0x00d0d, 0x03e20, 0x05144, 0x00d45, + 0x030d0, 0x0186d, 0x030d5, 0x00d0f, 0x00d40, 0x04114, 0x020a1, 0x0297f, + 0x03e24, 0x032f1, 0x04047, 0x030d4, 0x028a8, 0x00d0e, 0x0451d, 0x04044, + 0x0297e, 0x04042, 0x030d2, 0x030cf, 0x03e21, 0x03e26, 0x028a5, 0x0451a, + 0x00d48, 0x01a16, 0x00d44, 0x04518, 0x0149b, 0x039ca, 0x01498, 0x0403d, + 0x0451b, 0x0149c, 0x032f3, 0x030cb, 0x08073, 0x03e22, 0x0529a, 0x020aa, + 0x039cc, 0x0738a, 0x06530, 0x07389, 0x06193, 0x08071, 0x04043, 0x030ce, + 0x05147, 0x07388, 0x05145, 0x08072, 0x04521, 0x00d47, 0x0297c, 0x030cd, + 0x030ca, 0x0000b, 0x0000c, 0x00083, 0x000e4, 0x00048, 0x00102, 0x001cc, + 0x001f5, 0x00097, 0x0020b, 0x00124, 0x00453, 0x00627, 0x00639, 0x00605, + 0x00517, 0x001b8, 0x00663, 0x00667, 0x007c3, 0x00823, 0x00961, 0x00963, + 0x00e5a, 0x00e59, 0x00a2b, 0x00cbf, 0x00292, 0x00a2d, 0x007d0, 0x00953, + 0x00cc5, 0x00f84, 0x004ab, 0x014a7, 0x0068a, 0x0117a, 0x0052e, 0x01442, + 0x0052c, 0x00c77, 0x00f8f, 0x004aa, 0x01094, 0x01801, 0x012c4, 0x0297b, + 0x00952, 0x01f19, 0x006a5, 0x01149, 0x012c5, 0x01803, 0x022f2, 0x0329b, + 0x04520, 0x0149e, 0x00d13, 0x01f16, 0x01ce9, 0x0101c, 0x006e6, 0x039c9, + 0x06191, 0x07c8e, 0x06192, 0x0ca63, 0x039cd, 0x06190, 0x06884, 0x06885, + 0x07382, 0x00d49, 0x00d41, 0x0450c, 0x0149a, 0x030d1, 0x08077, 0x03e23, + 0x01a15, 0x0e701, 0x0e702, 0x08079, 0x0822a, 0x0a218, 0x07887, 0x0403f, + 0x0520b, 0x0529b, 0x0e700, 0x04519, 0x00007, 0x000e0, 0x000d0, 0x0039b, + 0x003e5, 0x00163, 0x0063e, 0x007c9, 0x00806, 0x00954, 0x01044, 0x01f44, + 0x0197c, 0x01f45, 0x00a51, 0x01f47, 0x00951, 0x0052d, 0x02291, 0x0092f, + 0x00a54, 0x00d12, 0x0297d, 0x00d0c, 0x01499, 0x0329e, 0x032f0, 0x02025, + 0x039c6, 0x00a57, 0x03e46, 0x00d42, 0x0738b, 0x05146, 0x04046, 0x08078, + 0x0510e, 0x07886, 0x02904, 0x04156, 0x04157, 0x06032, 0x030d3, 0x08bce, + 0x04040, 0x0403e, 0x0a414, 0x10457, 0x08075, 0x06887, 0x07c8f, 0x039c7, + 0x07387, 0x08070, 0x08bcf, 0x1482a, 0x10456, 0x1482b, 0x01a17, 0x06886, + 0x0450d, 0x00013, 0x0006b, 0x00615, 0x0080b, 0x0082b, 0x00952, 0x00e5b, + 0x018e2, 0x0186c, 0x01f18, 0x0329f, 0x00d43, 0x03e29, 0x05140, 0x05141, + 0x0ca62, 0x06033, 0x03c42, 0x03e28, 0x0450f, 0x0a21a, 0x07384, 0x0a219, + 0x0e703, 0x0a21b, 0x01a14, 0x07383, 0x045e6, 0x0007a, 0x0012c, 0x00ccc, + 0x0068f, 0x01802, 0x00a52, 0x00953, 0x04045, 0x01a20, 0x0451f, 0x000a4, + 0x00735, 0x01cec, 0x02029, 0x020a3, 0x0451e, 0x00069, 0x00c24, 0x02024, + 0x032f2, 0x05142, 0x00196, 0x00523, 0x000a6, 0x0197b, 0x0030b, 0x0092e, + 0x003e9, 0x03e27, 0x00160, 0x05143, 0x00652, 0x04041, 0x00734, 0x028a7, + 0x0080f, 0x01483, 0x0097c, 0x00340, 0x0068b, 0x00522, 0x01054, 0x01096, + 0x01f17, 0x0202b, 0x01cea, 0x020a0, 0x02978, 0x02026, 0x0297a, 0x039cb, + 0x03e2b, 0x0149f, 0x0329c, 0x07385, 0x08074, 0x0450e, 0x03e2a, 0x05149, + 0x08076, 0x07386, 0x05148, +}; + +static const uint8_t coef1_huffbits[555] = { + 9, 5, 2, 4, 4, 5, 5, 5, + 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 11, 11, 11, 11, 11, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 13, 12, 12, 12, 12, 12, 12, 12, + 13, 12, 12, 12, 12, 12, 12, 12, + 12, 13, 12, 12, 12, 13, 13, 13, + 13, 12, 12, 12, 12, 12, 12, 13, + 12, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 13, 13, 13, 13, 13, 13, + 13, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 14, 13, 14, 13, 13, 13, + 13, 13, 14, 13, 14, 14, 13, 14, + 14, 13, 14, 13, 13, 14, 14, 13, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 15, 14, 14, 14, 14, 15, 15, + 15, 14, 14, 13, 13, 12, 12, 13, + 13, 13, 14, 14, 15, 14, 15, 15, + 14, 13, 14, 15, 15, 15, 14, 14, + 14, 14, 15, 14, 14, 15, 15, 15, + 14, 15, 14, 14, 14, 14, 14, 15, + 15, 16, 15, 15, 15, 14, 15, 15, + 15, 15, 14, 14, 16, 14, 15, 14, + 14, 15, 15, 15, 15, 16, 15, 14, + 15, 15, 15, 16, 15, 15, 14, 14, + 14, 4, 7, 8, 8, 9, 9, 9, + 9, 10, 10, 11, 11, 11, 11, 11, + 11, 12, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 12, + 12, 12, 13, 13, 13, 13, 13, 13, + 13, 12, 12, 13, 13, 13, 13, 14, + 14, 13, 14, 13, 13, 13, 14, 14, + 15, 15, 14, 13, 13, 13, 14, 14, + 15, 15, 15, 16, 14, 15, 17, 17, + 15, 15, 15, 15, 15, 14, 16, 14, + 16, 16, 16, 16, 16, 16, 15, 15, + 17, 15, 16, 15, 6, 8, 10, 10, + 10, 11, 11, 11, 12, 12, 13, 13, + 13, 13, 14, 13, 14, 13, 14, 14, + 14, 14, 14, 15, 15, 14, 14, 14, + 14, 14, 14, 15, 15, 15, 15, 16, + 15, 15, 16, 15, 15, 15, 14, 16, + 15, 15, 18, 17, 16, 17, 15, 14, + 15, 16, 16, 19, 17, 19, 16, 17, + 15, 7, 10, 11, 12, 12, 12, 12, + 13, 13, 13, 14, 15, 14, 15, 15, + 16, 15, 14, 14, 15, 16, 15, 16, + 16, 16, 16, 15, 15, 7, 11, 12, + 13, 13, 14, 14, 15, 15, 15, 8, + 11, 13, 14, 14, 15, 9, 12, 14, + 14, 15, 9, 13, 10, 13, 10, 14, + 10, 14, 11, 15, 11, 15, 11, 14, + 12, 15, 12, 13, 13, 13, 13, 13, + 13, 14, 13, 14, 14, 14, 14, 14, + 14, 15, 14, 15, 16, 15, 14, 15, + 16, 15, 15, +}; + +static const uint32_t coef2_huffcodes[1336] = { + 0x003e6, 0x000f6, 0x00000, 0x00002, 0x00006, 0x0000f, 0x0001b, 0x00028, + 0x00039, 0x0003f, 0x0006b, 0x00076, 0x000b7, 0x000e8, 0x000ef, 0x00169, + 0x001a7, 0x001d4, 0x001dc, 0x002c4, 0x00349, 0x00355, 0x00391, 0x003dc, + 0x00581, 0x005b2, 0x00698, 0x0070c, 0x00755, 0x0073a, 0x00774, 0x007cf, + 0x00b0a, 0x00b66, 0x00d2e, 0x00d5e, 0x00e1b, 0x00eac, 0x00e5a, 0x00f7e, + 0x00fa1, 0x0163e, 0x01a37, 0x01a52, 0x01c39, 0x01ab3, 0x01d5f, 0x01cb6, + 0x01f52, 0x01dd9, 0x02c04, 0x02c2e, 0x02c2d, 0x02c23, 0x03467, 0x034a3, + 0x0351b, 0x03501, 0x03a5d, 0x0351c, 0x03875, 0x03dea, 0x0397b, 0x039db, + 0x03df1, 0x039d8, 0x03bb4, 0x0580a, 0x0584d, 0x05842, 0x05b13, 0x058ea, + 0x0697d, 0x06a06, 0x068cc, 0x06ac7, 0x06a96, 0x072f4, 0x07543, 0x072b4, + 0x07d20, 0x0b003, 0x073b5, 0x07be6, 0x0d180, 0x07bd1, 0x07cb8, 0x07d06, + 0x07d25, 0x0d2f2, 0x0d19a, 0x0d334, 0x0e1dc, 0x0d529, 0x0d584, 0x0e1d2, + 0x0e5e3, 0x0eec4, 0x0e564, 0x0fa49, 0x16001, 0x0eedc, 0x0f7fa, 0x1a32c, + 0x16131, 0x16003, 0x0f9c8, 0x1ef80, 0x1d2a0, 0x1aa4b, 0x0f7ce, 0x1abfe, + 0x1aa50, 0x1a458, 0x1a816, 0x1cae4, 0x1d2fe, 0x1d52e, 0x1aa4c, 0x2c245, + 0x1d2a1, 0x1a35d, 0x1ca1b, 0x1d5d8, 0x1f531, 0x1ca1c, 0x1f389, 0x1f4af, + 0x3a5e7, 0x351fb, 0x2c24b, 0x34bce, 0x2c24d, 0x2c249, 0x2c24a, 0x72dfc, + 0x357ef, 0x35002, 0x3a5e6, 0x39431, 0x5843b, 0x34a77, 0x58431, 0x3a5f3, + 0x3a5dd, 0x3e5e5, 0x356bd, 0x3976e, 0x6a3d2, 0x3500d, 0x694c4, 0x580bd, + 0x3e5e8, 0x74b95, 0x34a6e, 0x3977c, 0x39432, 0x5b0d2, 0x6a3d8, 0x580b8, + 0x5b0cb, 0x5b0d7, 0x72dee, 0x72ded, 0x72dec, 0x74b9c, 0x3977f, 0x72dea, + 0x74b9e, 0x7be7d, 0x580bf, 0x5b0d5, 0x7cba8, 0x74b91, 0x3e5dd, 0xb6171, + 0xd46b3, 0xd46b9, 0x7cba1, 0x74b9f, 0x72de1, 0xe59f5, 0x3e5eb, 0x00004, + 0x00015, 0x00038, 0x00075, 0x000e8, 0x001d3, 0x00347, 0x0039c, 0x00690, + 0x0074a, 0x00b60, 0x00e93, 0x00f74, 0x0163d, 0x01a5a, 0x01d24, 0x01cbe, + 0x01f4b, 0x03468, 0x03562, 0x03947, 0x03e82, 0x05804, 0x05b12, 0x05803, + 0x0696d, 0x06a9e, 0x0697c, 0x06978, 0x06afb, 0x074b2, 0x072f5, 0x073c0, + 0x07541, 0x06944, 0x074b7, 0x070d3, 0x07ba9, 0x0b0b1, 0x0d1af, 0x0e1dd, + 0x0e5e2, 0x0e1a3, 0x0eec3, 0x1612f, 0x0e961, 0x0eeda, 0x0e78e, 0x0fa48, + 0x1612c, 0x0e511, 0x0e565, 0x0e953, 0x1aa4a, 0x0e59d, 0x1d52c, 0x1a811, + 0x1cae7, 0x1abfc, 0x1d52d, 0x1cacf, 0x1cf05, 0x2c254, 0x34a72, 0x1f4ac, + 0x3976b, 0x34a71, 0x2c6d9, 0x2d873, 0x34a6a, 0x357e7, 0x3464c, 0x3e5f5, + 0x58433, 0x1f53a, 0x3500a, 0x357ea, 0x34a73, 0x3942f, 0x357e5, 0x39775, + 0x694cd, 0x39772, 0x7cba5, 0x6a3ef, 0x35483, 0x74b98, 0x5b0c1, 0x39770, + 0x3a5d7, 0x39433, 0x39434, 0x694ce, 0x580be, 0x3e5ff, 0x6a3ec, 0xb616f, + 0xd46b1, 0x6a3d1, 0x72de5, 0x74b6e, 0x72de9, 0x3e700, 0xd46b6, 0x6a3e9, + 0x74b69, 0xe5675, 0xd46b8, 0x7cbaa, 0x3a5d1, 0x0000c, 0x0003c, 0x000eb, + 0x001f1, 0x003a4, 0x006a8, 0x007d5, 0x00d43, 0x00e77, 0x016c5, 0x01cb1, + 0x02c5d, 0x03a55, 0x03a56, 0x03e51, 0x03bb5, 0x05b0a, 0x06a9f, 0x074b8, + 0x07d28, 0x0d187, 0x0d40e, 0x0d52e, 0x0d425, 0x0eae3, 0x0e1d3, 0x1612e, + 0x0e59e, 0x0eec2, 0x0e578, 0x0e51a, 0x0e579, 0x0e515, 0x0e960, 0x0d183, + 0x0d220, 0x0d2cb, 0x0e512, 0x16c3e, 0x16002, 0x16c42, 0x1cae9, 0x3461a, + 0x1d2fa, 0x1a308, 0x1a849, 0x1cf07, 0x1f38f, 0x34b65, 0x2c253, 0x1ef9e, + 0x1cbc3, 0x1cbc1, 0x2c255, 0x1f384, 0x58435, 0x2c5cd, 0x3a5f7, 0x2c252, + 0x3959c, 0x2c6d8, 0x3a5d3, 0x6ad78, 0x6a3f2, 0x7cba9, 0xb6176, 0x72deb, + 0x39764, 0x3e5f6, 0x3a5d8, 0x74a8c, 0x6a3e6, 0x694d1, 0x6ad79, 0x1a4592, + 0xe59fb, 0x7cbb3, 0x5b0cd, 0x00017, 0x000b5, 0x002c3, 0x005b7, 0x00b1c, + 0x00e5c, 0x0163f, 0x01ab2, 0x01efa, 0x0348a, 0x0396e, 0x058da, 0x06963, + 0x06a30, 0x072cd, 0x073cf, 0x07ce7, 0x0d2ca, 0x0d2d8, 0x0e764, 0x0e794, + 0x16008, 0x16167, 0x1617e, 0x1aa49, 0x1a30b, 0x1a813, 0x2c6da, 0x1a580, + 0x1cbc2, 0x0f9ca, 0x1617f, 0x1d2fe, 0x0f7fc, 0x16c40, 0x0e513, 0x0eec5, + 0x0f7c3, 0x1d508, 0x1a81e, 0x1d2fd, 0x39430, 0x35486, 0x3e5fd, 0x2c24c, + 0x2c75a, 0x34a74, 0x3a5f4, 0x3464d, 0x694ca, 0x3a5f1, 0x1d509, 0x1d5c0, + 0x34648, 0x3464e, 0x6a3d5, 0x6a3e8, 0x6a3e7, 0x5b0c3, 0x2c248, 0x1f38a, + 0x3a5f2, 0x6a3e5, 0x00029, 0x00168, 0x0058c, 0x00b67, 0x00f9d, 0x01c3d, + 0x01cbf, 0x02c20, 0x0351d, 0x03df6, 0x06af9, 0x072b5, 0x0b1d7, 0x0b0b2, + 0x0d40a, 0x0d52b, 0x0e952, 0x0e797, 0x163c3, 0x1c3a0, 0x1f386, 0x1ca21, + 0x34655, 0x2c247, 0x1f53b, 0x2c250, 0x2c24f, 0x1f385, 0x1ef5d, 0x1cf15, + 0x1caea, 0x1ab0a, 0x1cf19, 0x1f53d, 0x1d5c2, 0x1d2fb, 0x1ef58, 0x34a78, + 0x357ec, 0x1f533, 0x3a5e1, 0x694d2, 0x58482, 0x3a5ee, 0x2c6dc, 0x357eb, + 0x5b0c4, 0x39778, 0x6a3e1, 0x7cbb4, 0x3a5e1, 0x74b68, 0x3a5ef, 0x3a5d2, + 0x39424, 0x72de2, 0xe59f6, 0xe59f7, 0x3e702, 0x3e5ec, 0x1f38b, 0x0003b, + 0x001f0, 0x00777, 0x00fa8, 0x01cb2, 0x02d84, 0x03a57, 0x03dd6, 0x06917, + 0x06a11, 0x07d07, 0x0eae2, 0x0e796, 0x0f9c9, 0x0f7fb, 0x16166, 0x16160, + 0x1ab1b, 0x1abfa, 0x2d87b, 0x1d2f7, 0x39768, 0x1f38c, 0x34653, 0x34651, + 0x6a3d9, 0x35001, 0x3abbd, 0x38742, 0x39426, 0x34a76, 0x3a5ec, 0x34a75, + 0x35000, 0x35488, 0x1cf10, 0x2c6db, 0x357ed, 0x357e8, 0x357e9, 0x3a5f0, + 0x694c2, 0xb6178, 0x72df5, 0x39425, 0x3942b, 0x74b6d, 0x74b6f, 0xb6177, + 0xb6179, 0x74b6a, 0xb6172, 0x58487, 0x3e5ee, 0x3e5ed, 0x72df2, 0x72df4, + 0x7cbae, 0x6a3ca, 0x70e86, 0x34bcf, 0x6a3c8, 0x00059, 0x00384, 0x00d5b, + 0x01c38, 0x03560, 0x0395b, 0x0584e, 0x06964, 0x073cd, 0x0b1e7, 0x0e798, + 0x0e78d, 0x0fa43, 0x1a848, 0x1a32f, 0x1aa4e, 0x3464a, 0x1f4ab, 0x1f38d, + 0x3a5eb, 0x3a5d4, 0x3548a, 0x6a3c7, 0x5b0d0, 0x6a3c5, 0x7cbb0, 0x694cb, + 0x3a5e5, 0x3e5e2, 0x3942c, 0x2d872, 0x1f4ae, 0x3a5d5, 0x694d3, 0x58481, + 0x35009, 0x39774, 0x58432, 0xb616c, 0x5b0db, 0x3548b, 0xb6174, 0x1d5d95, + 0xb004c, 0x7cbb2, 0x3a5e5, 0x74a8f, 0xe59f9, 0x72df6, 0xe59fd, 0x7cbad, + 0xd427d, 0x72cff, 0x3977a, 0x5b0d9, 0xb616d, 0xb616b, 0x1a4593, 0x7cbaf, + 0x5b0da, 0x00071, 0x003eb, 0x01603, 0x02c6c, 0x03961, 0x068c8, 0x06a31, + 0x072bd, 0x0d2c2, 0x0e51b, 0x0e5e6, 0x1abfb, 0x1d2ff, 0x1cae5, 0x1ef5c, + 0x1ef5e, 0x1cf13, 0x34a6d, 0x3976d, 0xb616a, 0x3e5f2, 0x6a3c4, 0xb6169, + 0x3e5dc, 0x580b9, 0x74b99, 0x75764, 0x58434, 0x3a5d9, 0x6945a, 0x69459, + 0x3548c, 0x3a5e9, 0x69457, 0x72df1, 0x6945e, 0x6a35e, 0x3e701, 0xb6168, + 0x5b0dd, 0x3a5de, 0x6a3c2, 0xd4278, 0x6a3cc, 0x72dfd, 0xb6165, 0x16009a, + 0x7cbb1, 0xd427c, 0xb6162, 0xe765e, 0x1cecbe, 0x7cbb6, 0x69454, 0xb6160, + 0xd427a, 0x1d5d96, 0xb1d6d, 0xe59f4, 0x72de8, 0x3a5db, 0x0007a, 0x006ae, + 0x01c3c, 0x03aba, 0x058e9, 0x072cc, 0x0d2dd, 0x0d22d, 0x0eec1, 0x0eedb, + 0x1d2a2, 0x1ef5b, 0x357e2, 0x3abbf, 0x1d2f9, 0x35004, 0x3a5dc, 0x351fc, + 0x3976c, 0x6a3c6, 0x6a3cb, 0x3e5ea, 0xe59f3, 0x6a3ce, 0x69452, 0xe59f0, + 0x74b90, 0xd4279, 0xd427b, 0x7cbb5, 0x5b0c5, 0x3a5e3, 0x3a5e2, 0x000d0, + 0x00775, 0x01efe, 0x03dd5, 0x0728c, 0x07cb9, 0x0e1a2, 0x0ea85, 0x0eed8, + 0x1a30a, 0x1aa4f, 0x3a5df, 0x35008, 0x3a5e0, 0x3e5f4, 0x3e5f7, 0xb1d6c, + 0x5843e, 0x34a70, 0x72df8, 0x74b6b, 0xd427f, 0x72df0, 0x5b0bf, 0x5b0c0, + 0xd46b0, 0x72def, 0xe59f8, 0x162e64, 0xb1d6f, 0x3a5e0, 0x39427, 0x69166, + 0x6a3e2, 0x6a3e3, 0x74a8d, 0xd427e, 0x1d5d97, 0xd46b4, 0x5b0d8, 0x6a3d3, + 0x000e0, 0x00b63, 0x034cc, 0x06a33, 0x073c9, 0x0e1a0, 0x0f7fd, 0x0f9cc, + 0x1617d, 0x1caeb, 0x1f4a9, 0x3abb3, 0x69450, 0x39420, 0x39777, 0x3e5e0, + 0x6a3d4, 0x6a3ed, 0xb6166, 0xe59f1, 0xb1d6e, 0xe5676, 0x6a3ea, 0xe5674, + 0xb6163, 0xd46b7, 0x7cba6, 0xd46ba, 0x1d5d94, 0xb6164, 0x6a3f1, 0x7cba2, + 0x69451, 0x72dfa, 0xd46bb, 0x72df7, 0x74b94, 0x1cecbf, 0xe59fa, 0x16009b, + 0x6a3e4, 0x000e6, 0x00e94, 0x03876, 0x070ef, 0x0d52a, 0x16015, 0x16014, + 0x1abf9, 0x1cf17, 0x34a79, 0x34650, 0x3e705, 0x6a3d0, 0x58430, 0x74b9d, + 0x7be7e, 0x5b0be, 0x39773, 0x6a3de, 0x000fb, 0x00f7b, 0x03dd7, 0x07bd0, + 0x0e59c, 0x0f9cd, 0x1cf18, 0x1d2ff, 0x34a7a, 0x39429, 0x3500c, 0x72de0, + 0x69456, 0x7be7c, 0xd46b5, 0xd46b2, 0x6a3dd, 0x001a2, 0x0163b, 0x06913, + 0x0b016, 0x0fa42, 0x1a32d, 0x1cf06, 0x34a7c, 0x34a7d, 0xb6161, 0x35481, + 0x3e5fa, 0x7cba0, 0x7be7f, 0x7cba3, 0x7cba7, 0x5b0d3, 0x72de6, 0x6a3dc, + 0x001a9, 0x01ab4, 0x06a34, 0x0d46a, 0x16130, 0x1ef5f, 0x1f532, 0x1f536, + 0x3942e, 0x58436, 0x6a3db, 0x6945b, 0x001c9, 0x01ca0, 0x0728b, 0x0eed9, + 0x1f539, 0x1ca1d, 0x39765, 0x39766, 0x58439, 0x6945d, 0x39767, 0x001d3, + 0x01f2c, 0x07bfc, 0x16161, 0x34652, 0x3a5ed, 0x3548d, 0x58438, 0x6a3da, + 0x002c1, 0x02c5e, 0x0d335, 0x1ab1a, 0x2d874, 0x35006, 0x35484, 0x5b0cc, + 0x74b9a, 0x72df3, 0x6a3d6, 0x002da, 0x034b3, 0x0d5ae, 0x1caee, 0x2d871, + 0x357e3, 0x74b97, 0x72df9, 0x580ba, 0x5b0d4, 0x0034d, 0x0354e, 0x0f750, + 0x1cbc0, 0x3a5e7, 0x3a5e4, 0x00385, 0x03a58, 0x16c41, 0x2c5cf, 0x3e5e1, + 0x74b6c, 0xe5677, 0x6a3df, 0x00390, 0x03e50, 0x163c2, 0x2d876, 0x35482, + 0x5b0d6, 0x5843a, 0x0039f, 0x0585e, 0x1a583, 0x3500f, 0x74b93, 0x39771, + 0x003e4, 0x06912, 0x16c43, 0x357e1, 0x0058a, 0x0696f, 0x1f538, 0x5b0c9, + 0x6a3cf, 0x005b6, 0x06af8, 0x1f534, 0x58483, 0x6a3e0, 0x00695, 0x07d02, + 0x1cae8, 0x58485, 0x006a2, 0x0754a, 0x357ee, 0x3977b, 0x00748, 0x074b2, + 0x34a7b, 0x00729, 0x0b1e0, 0x34649, 0x3e5e3, 0x0073d, 0x0d2c4, 0x3e5e6, + 0x007bb, 0x0b099, 0x39762, 0x5b0ce, 0x6945f, 0x007d1, 0x0d5ab, 0x39779, + 0x007d3, 0x0d52f, 0x39763, 0x6945c, 0x00b1a, 0x0d2c5, 0x35489, 0x00d23, + 0x0eaed, 0x3e5f8, 0x00d32, 0x16016, 0x3e5fb, 0x00d41, 0x0e768, 0x3a5ed, + 0x00e1f, 0x16017, 0x58027, 0x00ead, 0x0fa07, 0x69455, 0x00e54, 0x1612b, + 0x00e55, 0x1a581, 0x00f78, 0x1a32b, 0x580bc, 0x6a3ee, 0x00f79, 0x1abfd, + 0x00f95, 0x1ab18, 0x6a3f0, 0x01637, 0x1aa4d, 0x0162d, 0x1f53c, 0x6a3f3, + 0x01a31, 0x1a810, 0x39769, 0x01a50, 0x1caef, 0x01a36, 0x1a32e, 0x01a67, + 0x1f38e, 0x01a85, 0x1ef59, 0x01aa6, 0x1ef83, 0x01d51, 0x2c012, 0x01d53, + 0x2d879, 0x01d5e, 0x35005, 0x01cba, 0x1cf04, 0x69453, 0x01d2d, 0x351ff, + 0x01f2d, 0x2d86f, 0x01f29, 0x35007, 0x02c22, 0x351fa, 0x02c03, 0x3a5ec, + 0x02c5f, 0x3a5eb, 0x02c58, 0x34a6b, 0x03469, 0x356be, 0x02c59, 0x34a6c, + 0x0346a, 0x3a5ea, 0x034bd, 0x034bf, 0x356bf, 0x0386a, 0x03ab9, 0x5843f, + 0x0386b, 0x3a5f5, 0x03a4b, 0x39421, 0x03aa4, 0x3a5e9, 0x03a5a, 0x03960, + 0x3977e, 0x03de9, 0x03958, 0x03df7, 0x039e1, 0x3e5e4, 0x0395f, 0x69458, + 0x03e91, 0x03df2, 0x39428, 0x058f2, 0x03e80, 0x6a3c3, 0x03e93, 0x694c0, + 0x058b8, 0x5b0ca, 0x0584f, 0x694c1, 0x058f1, 0x068d6, 0x06a10, 0x06ac3, + 0x06a32, 0x070d2, 0x06911, 0x074b1, 0x07494, 0x06ad4, 0x06ad6, 0x072b8, + 0x06afa, 0x074b3, 0x07540, 0x073ce, 0x0b005, 0x074b3, 0x07495, 0x074b9, + 0x0d336, 0x07bff, 0x07763, 0x073c8, 0x07d29, 0x0b622, 0x0d221, 0x0d181, + 0x0b1d1, 0x074b8, 0x0b1d0, 0x0d19b, 0x0d2c3, 0x0b172, 0x0d2dc, 0x0b623, + 0x0d5aa, 0x0d426, 0x0d182, 0x0e795, 0x0e1d1, 0x0d337, 0x0e96c, 0x0e5e4, + 0x0e514, 0x0eaee, 0x16000, 0x0e767, 0x0e1a1, 0x0e78f, 0x16004, 0x0f7c2, + 0x0e799, 0x0e5e7, 0x0e566, 0x0e769, 0x0f751, 0x0eede, 0x0fa06, 0x16005, + 0x0fa9f, 0x1a5e6, 0x0e766, 0x1636f, 0x0eedd, 0x0eec0, 0x1a309, 0x1ceca, + 0x163cd, 0x0f9cb, 0x0eedf, 0x1a582, 0x1612d, 0x0e5e5, 0x1abf8, 0x1a30c, + 0x1ca1f, 0x163cc, 0x1a35c, 0x1ca1e, 0x1aa51, 0x163ac, 0x1a84e, 0x1a53f, + 0x1cf16, 0x1d2fc, 0x1a5b3, 0x1ab19, 0x1a81f, 0x1d5c3, 0x16c3f, 0x1d5c1, + 0x1d2fc, 0x1f4aa, 0x1a812, 0x1f535, 0x1cf12, 0x1a817, 0x1617c, 0x1ab0b, + 0x1d2f8, 0x1ef82, 0x2d87a, 0x1d52f, 0x1f530, 0x1aa48, 0x35487, 0x1d2fd, + 0x1f4ad, 0x1cf11, 0x3461b, 0x35485, 0x1ca20, 0x1caed, 0x1cae6, 0x1abff, + 0x3464f, 0x34a6f, 0x1ef81, 0x3464b, 0x39d96, 0x1f383, 0x1f537, 0x1cf14, + 0x2c5ce, 0x3500e, 0x2c251, 0x1caec, 0x1f387, 0x34654, 0x357e4, 0x2d878, + 0x3500b, 0x35480, 0x3a5e8, 0x3548e, 0x34b64, 0x1f4a8, 0x35003, 0x3e5df, + 0x2d870, 0x357e6, 0x3e5f0, 0x1ef5a, 0x3a5ea, 0x1f388, 0x3e703, 0x2c24e, + 0x3a5e2, 0x351fd, 0x2c6dd, 0x3e704, 0x351fe, 0x2d875, 0x5b0c7, 0x3976a, + 0x3a5e6, 0x39423, 0x58480, 0x2c246, 0x3a5e3, 0x2d877, 0x3e5f1, 0x3abbe, + 0x58489, 0x3e5f9, 0x357e0, 0x3abbc, 0x5b0c6, 0x69167, 0x69165, 0x3e5e9, + 0x39422, 0x3976f, 0x3977d, 0x3e5de, 0x6a3c9, 0x58b98, 0x3a5f6, 0x3a5d0, + 0x58486, 0x6a3c1, 0x3e5fc, 0x5b0dc, 0x3548f, 0x3942d, 0x694c9, 0x58484, + 0x3a5e8, 0x74b9b, 0x74b96, 0x694d0, 0x58488, 0x3a5e4, 0x3942a, 0x72ec2, + 0x39776, 0x5b0d1, 0x5b0cf, 0x3a5d6, 0xe59fc, 0x5b0c8, 0x3e5e7, 0x7cbb7, + 0x70e87, 0x7cbab, 0x5b0c2, 0x694c3, 0x74a8e, 0x3e5f3, 0x6a3cd, 0x72dfe, + 0x73b2e, 0x72ec0, 0x694c5, 0x58437, 0x694c8, 0x72dff, 0x39435, 0x5843d, + 0x6a3d7, 0x72ec1, 0xd22c8, 0x694cf, 0xb6173, 0x3e5fe, 0x580bb, 0xe59f2, + 0xb616e, 0xb6175, 0x3a5da, 0x5b0bd, 0x694cc, 0x5843c, 0x694c7, 0x74b92, + 0x72ec3, 0x694c6, 0xb6170, 0x7cbac, 0xb1733, 0x7cba4, 0xb6167, 0x72de7, + 0x72de4, 0x6a3c0, 0x3e5ef, 0x162e65, 0x72de3, 0x72dfb, 0x6a35f, 0x6a3eb, +}; + +static const uint8_t coef2_huffbits[1336] = { + 11, 9, 2, 3, 4, 4, 5, 6, + 6, 7, 7, 8, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 10, 11, 11, + 11, 11, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 16, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 18, 17, 17, 17, 17, + 17, 17, 17, 18, 18, 17, 17, 18, + 17, 17, 18, 17, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 20, + 18, 18, 18, 19, 19, 18, 19, 18, + 19, 19, 18, 19, 19, 18, 19, 19, + 19, 19, 18, 19, 19, 19, 19, 19, + 19, 19, 20, 20, 20, 19, 19, 20, + 19, 20, 19, 19, 20, 19, 19, 20, + 20, 20, 20, 19, 20, 21, 19, 3, + 5, 7, 8, 9, 9, 10, 11, 11, + 12, 12, 12, 13, 13, 13, 13, 14, + 14, 14, 14, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 16, 16, + 15, 15, 15, 15, 16, 16, 16, 16, + 17, 16, 17, 17, 16, 17, 17, 17, + 17, 17, 17, 16, 17, 17, 17, 17, + 18, 17, 17, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 19, + 19, 18, 18, 18, 18, 19, 18, 19, + 19, 19, 20, 19, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 20, + 20, 19, 20, 19, 20, 19, 20, 19, + 19, 21, 20, 20, 19, 4, 7, 8, + 10, 11, 11, 12, 12, 13, 13, 14, + 14, 14, 14, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 16, 16, + 16, 16, 17, 17, 17, 17, 18, 18, + 18, 17, 17, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 19, 18, 18, 18, + 19, 18, 19, 19, 19, 20, 20, 20, + 19, 19, 19, 19, 19, 19, 19, 21, + 21, 20, 19, 5, 8, 10, 11, 12, + 13, 13, 13, 14, 14, 15, 15, 15, + 15, 16, 16, 16, 16, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 18, 17, + 18, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 19, 18, 19, 18, + 18, 18, 18, 18, 19, 18, 17, 17, + 18, 18, 19, 19, 19, 19, 18, 18, + 18, 19, 6, 9, 11, 12, 13, 13, + 14, 14, 14, 15, 15, 16, 16, 16, + 16, 16, 16, 17, 17, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 17, 18, 18, 17, 18, 18, 18, + 18, 18, 18, 19, 19, 18, 18, 18, + 19, 19, 19, 20, 19, 19, 18, 19, + 19, 20, 21, 21, 19, 19, 18, 6, + 10, 12, 13, 14, 14, 14, 15, 15, + 15, 16, 16, 17, 17, 17, 17, 17, + 17, 17, 18, 18, 19, 18, 18, 18, + 19, 18, 18, 18, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 19, 20, 20, 19, 19, 19, 19, 20, + 20, 19, 20, 19, 19, 19, 20, 20, + 20, 19, 19, 18, 19, 7, 10, 12, + 13, 14, 15, 15, 15, 16, 16, 17, + 17, 17, 17, 17, 17, 18, 18, 18, + 18, 19, 18, 19, 19, 19, 20, 19, + 18, 19, 19, 18, 18, 19, 19, 19, + 18, 19, 19, 20, 19, 18, 20, 21, + 20, 20, 19, 19, 21, 20, 21, 20, + 20, 20, 19, 19, 20, 20, 21, 20, + 19, 7, 11, 13, 14, 15, 15, 15, + 16, 16, 17, 17, 17, 17, 18, 18, + 18, 18, 18, 19, 20, 19, 19, 20, + 19, 19, 19, 19, 19, 19, 19, 19, + 18, 18, 19, 20, 19, 19, 19, 20, + 19, 19, 19, 20, 19, 20, 20, 21, + 20, 20, 20, 21, 22, 20, 19, 20, + 20, 21, 20, 21, 20, 19, 8, 11, + 13, 14, 15, 16, 16, 16, 17, 17, + 17, 18, 18, 18, 18, 18, 19, 18, + 19, 19, 19, 19, 21, 19, 19, 21, + 19, 20, 20, 20, 19, 18, 18, 8, + 12, 14, 15, 16, 16, 16, 16, 17, + 17, 17, 19, 18, 18, 19, 19, 20, + 19, 18, 20, 19, 20, 20, 19, 19, + 20, 20, 21, 21, 20, 19, 19, 19, + 19, 19, 19, 20, 21, 20, 19, 19, + 8, 12, 14, 15, 16, 16, 17, 17, + 17, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 20, 21, 20, 21, 19, 21, + 20, 20, 20, 20, 21, 20, 19, 20, + 19, 20, 20, 20, 19, 22, 21, 21, + 19, 9, 12, 14, 15, 16, 17, 17, + 17, 18, 18, 18, 19, 19, 19, 19, + 20, 19, 19, 19, 9, 13, 15, 16, + 17, 17, 18, 18, 18, 19, 18, 20, + 19, 20, 20, 20, 19, 9, 13, 15, + 16, 17, 17, 18, 18, 18, 20, 18, + 19, 20, 20, 20, 20, 19, 20, 19, + 9, 13, 15, 16, 17, 18, 18, 18, + 19, 19, 19, 19, 10, 14, 16, 17, + 18, 18, 19, 19, 19, 19, 19, 10, + 14, 16, 17, 18, 18, 18, 19, 19, + 10, 14, 16, 17, 18, 18, 18, 19, + 19, 20, 19, 10, 14, 16, 18, 18, + 18, 19, 20, 19, 19, 10, 14, 17, + 18, 18, 18, 10, 15, 17, 18, 19, + 19, 21, 19, 11, 15, 17, 18, 18, + 19, 19, 11, 15, 17, 18, 19, 19, + 11, 15, 17, 18, 11, 15, 18, 19, + 19, 11, 15, 18, 19, 19, 11, 16, + 18, 19, 11, 15, 18, 19, 11, 16, + 18, 12, 16, 18, 19, 12, 16, 19, + 12, 16, 19, 19, 19, 12, 16, 19, + 12, 16, 19, 19, 12, 16, 18, 12, + 16, 19, 12, 17, 19, 12, 17, 19, + 12, 17, 19, 12, 17, 19, 13, 17, + 13, 17, 13, 17, 19, 19, 13, 17, + 13, 17, 19, 13, 17, 13, 18, 19, + 13, 17, 19, 13, 18, 13, 17, 13, + 18, 13, 18, 13, 18, 13, 18, 13, + 18, 13, 18, 14, 18, 19, 14, 18, + 14, 18, 14, 18, 14, 18, 14, 19, + 14, 19, 14, 18, 14, 18, 14, 18, + 14, 19, 14, 14, 18, 14, 14, 19, + 14, 18, 14, 19, 14, 19, 14, 15, + 19, 15, 15, 15, 15, 19, 15, 19, + 15, 15, 19, 15, 15, 19, 15, 19, + 15, 19, 15, 19, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, + 15, 15, 15, 16, 16, 16, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 17, 16, 16, 16, 17, + 17, 16, 17, 17, 16, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 18, + 17, 17, 17, 17, 17, 17, 17, 17, + 18, 17, 17, 18, 17, 17, 17, 17, + 18, 18, 17, 17, 17, 17, 17, 17, + 17, 18, 17, 18, 18, 17, 17, 17, + 18, 18, 18, 17, 18, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 17, + 18, 18, 18, 18, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, + 18, 18, 19, 18, 18, 18, 19, 18, + 19, 18, 18, 19, 18, 18, 19, 19, + 19, 19, 19, 18, 19, 18, 19, 18, + 19, 19, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 18, 19, + 19, 19, 19, 19, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 20, + 19, 19, 19, 19, 21, 19, 19, 20, + 19, 20, 19, 19, 19, 19, 19, 20, + 20, 20, 19, 19, 19, 20, 19, 19, + 19, 20, 20, 19, 20, 19, 19, 21, + 20, 20, 19, 19, 19, 19, 19, 19, + 20, 19, 20, 20, 20, 20, 20, 20, + 20, 19, 19, 21, 20, 20, 19, 19, +}; + +static const uint32_t coef3_huffcodes[1072] = { + 0x001b2, 0x00069, 0x00000, 0x00004, 0x00006, 0x0000e, 0x00014, 0x00019, + 0x00016, 0x0002b, 0x00030, 0x0003d, 0x0003c, 0x0005a, 0x0005f, 0x0006d, + 0x0007e, 0x0005f, 0x0007f, 0x000b6, 0x000bc, 0x000d8, 0x000f2, 0x000fe, + 0x000bc, 0x000fc, 0x00161, 0x0016e, 0x00174, 0x00176, 0x001a2, 0x001e3, + 0x001f3, 0x00174, 0x0017a, 0x001ea, 0x002a8, 0x002c4, 0x002e6, 0x00314, + 0x00346, 0x00367, 0x003e9, 0x002e5, 0x002ee, 0x003d6, 0x00555, 0x00554, + 0x00557, 0x005c3, 0x005d6, 0x006e0, 0x0062f, 0x006e2, 0x00799, 0x00789, + 0x007fa, 0x005ce, 0x007fe, 0x005ec, 0x007cc, 0x007af, 0x00aa7, 0x00b19, + 0x00b94, 0x00b85, 0x00b9f, 0x00c48, 0x00c45, 0x00dd8, 0x00c4c, 0x00c4b, + 0x00d99, 0x00d1f, 0x00dc2, 0x00f95, 0x00fa2, 0x00bb5, 0x00b9f, 0x00f5d, + 0x00bbf, 0x00f47, 0x0154a, 0x00fd5, 0x00f45, 0x00f7f, 0x0160d, 0x01889, + 0x01757, 0x01722, 0x018b3, 0x0172d, 0x01a39, 0x01a18, 0x01bb3, 0x01b30, + 0x01e63, 0x0173c, 0x01b35, 0x01723, 0x01e80, 0x01fee, 0x01761, 0x01ffc, + 0x01f7f, 0x02c7c, 0x01fa1, 0x0177b, 0x01755, 0x0175a, 0x01fa6, 0x02eab, + 0x0310a, 0x02c69, 0x03669, 0x03127, 0x03103, 0x02e43, 0x03662, 0x03165, + 0x03124, 0x0313b, 0x03111, 0x03668, 0x0343b, 0x03c52, 0x03efc, 0x02e6c, + 0x03fda, 0x03ef8, 0x02e7b, 0x03ee2, 0x03cc5, 0x03d72, 0x058c0, 0x03df8, + 0x02ea9, 0x03e7e, 0x0556d, 0x05c82, 0x03d71, 0x03e7b, 0x03c42, 0x058d7, + 0x03f4e, 0x06200, 0x03d70, 0x05cb2, 0x05c96, 0x05cb0, 0x03f45, 0x05cb1, + 0x02e6d, 0x03110, 0x02f68, 0x05c90, 0x07ca6, 0x07c88, 0x06204, 0x062c8, + 0x078a6, 0x07986, 0x079d5, 0x0b1ad, 0x07989, 0x0b079, 0x05cdd, 0x0aad4, + 0x05de8, 0x07dcd, 0x07987, 0x05d67, 0x05d99, 0x0b91d, 0x07cf1, 0x05d9b, + 0x079d7, 0x0b07b, 0x05c85, 0x05d9a, 0x07dcc, 0x07ebf, 0x07dce, 0x07dfb, + 0x07ec0, 0x07d1a, 0x07a07, 0x05c84, 0x0c471, 0x07cf2, 0x0baef, 0x0b9d2, + 0x05deb, 0x07bd6, 0x0b845, 0x05d98, 0x0b91a, 0x0bae8, 0x0c4e0, 0x0dc31, + 0x0f93d, 0x0bbce, 0x0d1d2, 0x0f7a9, 0x0d9b9, 0x0bbcb, 0x0b900, 0x0aad7, + 0x0babd, 0x0c4e1, 0x0f46f, 0x0c588, 0x0c58b, 0x160e6, 0x0bbcf, 0x0bac3, + 0x0f945, 0x0f7a3, 0x0d1c1, 0x0fb8e, 0x0f7a4, 0x0fb8c, 0x0f40c, 0x0c473, + 0x0fd72, 0x0bbcd, 0x0fffa, 0x0f940, 0x0bbc9, 0x0f7a8, 0x1a1ed, 0x0bbc5, + 0x1f26f, 0x163fd, 0x160c7, 0x1a1f5, 0x0f947, 0x163fc, 0x154b3, 0x0fff6, + 0x163f6, 0x160e9, 0x1a1f0, 0x0bab9, 0x0baba, 0x17086, 0x0b903, 0x0fd75, + 0x0f308, 0x176f3, 0x163ff, 0x0fd7d, 0x1bb78, 0x163fb, 0x188db, 0x1a1f7, + 0x154b2, 0x172fd, 0x163f4, 0x1bb73, 0x172ff, 0x0babc, 0x0f97d, 0x1a1f3, + 0x1bb6d, 0x1ffd5, 0x1a1f4, 0x1f272, 0x17380, 0x17382, 0x1ffe7, 0x0bac8, + 0x0bbc4, 0x188d3, 0x160e0, 0x0fd7b, 0x1725f, 0x172f5, 0x1bb79, 0x1fad9, + 0x1f269, 0x188d0, 0x0bac4, 0x0bac5, 0x31185, 0x188d2, 0x188cc, 0x31187, + 0x3e7fe, 0x188d1, 0x1bb6c, 0x1f268, 0x1fad2, 0x1ffd9, 0x1a1ea, 0x1bb68, + 0x1facb, 0x3fdb2, 0x1e81a, 0x188ce, 0x172fb, 0x1a1ef, 0x1face, 0x1bb70, + 0x0bac1, 0x1bb6b, 0x172f8, 0x1bb66, 0x1ffdf, 0x1bb6a, 0x1ffd7, 0x1f266, + 0x176f8, 0x37653, 0x1fa7e, 0x31182, 0x1fac8, 0x2c7e3, 0x370ee, 0x176ec, + 0x176e9, 0x2e4bc, 0x160c5, 0x3765a, 0x3ce9c, 0x17373, 0x176e8, 0x188d4, + 0x176f1, 0x176ef, 0x37659, 0x1bb7c, 0x1ffde, 0x176f2, 0x3118b, 0x2c7d4, + 0x37651, 0x5ce9f, 0x37650, 0x31191, 0x3f4f6, 0x3f4f5, 0x7a06c, 0x1fac1, + 0x5c97b, 0x2c7e0, 0x79d3a, 0x3e7fd, 0x2c7df, 0x3f4f0, 0x7a06d, 0x376c1, + 0x79d3b, 0x00004, 0x00014, 0x00059, 0x000ab, 0x000b8, 0x00177, 0x001f5, + 0x001f2, 0x00315, 0x003fc, 0x005bd, 0x0062d, 0x006e8, 0x007dd, 0x00b04, + 0x007cd, 0x00b1e, 0x00d1e, 0x00f15, 0x00f3b, 0x00f41, 0x01548, 0x018b0, + 0x0173b, 0x01884, 0x01a1c, 0x01bb4, 0x01f25, 0x017b5, 0x0176d, 0x01ef8, + 0x02e73, 0x03107, 0x03125, 0x03105, 0x02e49, 0x03ce8, 0x03ef9, 0x03e5e, + 0x02e72, 0x03471, 0x03fd9, 0x0623f, 0x078a0, 0x06867, 0x05cb3, 0x06272, + 0x068ec, 0x06e9a, 0x079d4, 0x06e98, 0x0b1aa, 0x06e1a, 0x07985, 0x068ee, + 0x06e9b, 0x05c88, 0x0b1ac, 0x07dfa, 0x05d65, 0x07cf0, 0x07cbf, 0x0c475, + 0x160eb, 0x1bb7e, 0x0f7a6, 0x1fedd, 0x160e3, 0x0fffb, 0x0fb8d, 0x0fff9, + 0x0d1c0, 0x0c58c, 0x1a1e9, 0x0bab8, 0x0f5cf, 0x0fff5, 0x376c5, 0x1a1ec, + 0x160ed, 0x1fede, 0x1fac9, 0x1a1eb, 0x1f224, 0x176ee, 0x0fd79, 0x17080, + 0x17387, 0x1bb7a, 0x1ffe9, 0x176f7, 0x17385, 0x17781, 0x2c7d5, 0x17785, + 0x1ffe3, 0x163f5, 0x1fac2, 0x3e7f9, 0x3118d, 0x3fdb1, 0x1ffe2, 0x1f226, + 0x3118a, 0x2c7d9, 0x31190, 0x3118c, 0x3f4f3, 0x1bb7f, 0x1bb72, 0x31184, + 0xb92f4, 0x3e7fb, 0x6e1d9, 0x1faca, 0x62300, 0x3fdb8, 0x3d037, 0x3e7fc, + 0x62301, 0x3f4f2, 0x1f26a, 0x0000e, 0x00063, 0x000f8, 0x001ee, 0x00377, + 0x003f7, 0x006e3, 0x005cc, 0x00b05, 0x00dd2, 0x00fd4, 0x0172e, 0x0172a, + 0x01e23, 0x01f2d, 0x01763, 0x01769, 0x0176c, 0x02e75, 0x03104, 0x02ec1, + 0x03e58, 0x0583f, 0x03f62, 0x03f44, 0x058c5, 0x0623c, 0x05cf4, 0x07bd7, + 0x05d9d, 0x0aad2, 0x05d66, 0x0b1a9, 0x0b078, 0x07cfe, 0x0b918, 0x0c46f, + 0x0b919, 0x0b847, 0x06e1b, 0x0b84b, 0x0aad8, 0x0fd74, 0x172f4, 0x17081, + 0x0f97c, 0x1f273, 0x0f7a0, 0x0fd7c, 0x172f7, 0x0fd7a, 0x1bb77, 0x172fe, + 0x1f270, 0x0fd73, 0x1bb7b, 0x1a1bc, 0x1bb7d, 0x0bbc3, 0x172f6, 0x0baeb, + 0x0fb8f, 0x3f4f4, 0x3fdb4, 0x376c8, 0x3e7fa, 0x1ffd0, 0x62303, 0xb92f5, + 0x1f261, 0x31189, 0x3fdb5, 0x2c7db, 0x376c9, 0x1fad6, 0x1fad1, 0x00015, + 0x000f0, 0x002e0, 0x0058e, 0x005d7, 0x00c4d, 0x00fa1, 0x00bdb, 0x01756, + 0x01f70, 0x02c19, 0x0313c, 0x0370f, 0x03cc0, 0x02ea8, 0x058c6, 0x058c7, + 0x02eb7, 0x058d0, 0x07d18, 0x0aa58, 0x0b848, 0x05d9e, 0x05d6c, 0x0b84c, + 0x0c589, 0x0b901, 0x163f8, 0x0bac9, 0x0b9c5, 0x0f93c, 0x188d8, 0x0bbc7, + 0x160ec, 0x0fd6f, 0x188d9, 0x160ea, 0x0f7a7, 0x0f944, 0x0baab, 0x0dc3a, + 0x188cf, 0x176fb, 0x2c7d8, 0x2c7d7, 0x1bb75, 0x5ce9e, 0x62302, 0x370ed, + 0x176f4, 0x1ffd1, 0x370ef, 0x3f4f8, 0x376c7, 0x1ffe1, 0x376c6, 0x176ff, + 0x6e1d8, 0x176f6, 0x17087, 0x0f5cd, 0x00035, 0x001a0, 0x0058b, 0x00aac, + 0x00b9a, 0x0175f, 0x01e22, 0x01e8c, 0x01fb2, 0x0310b, 0x058d1, 0x0552e, + 0x05c27, 0x0686e, 0x07ca7, 0x0c474, 0x0dc33, 0x07bf2, 0x05de9, 0x07a35, + 0x0baaa, 0x0b9eb, 0x0fb95, 0x0b9b8, 0x17381, 0x1f262, 0x188cd, 0x17088, + 0x172fa, 0x0f7a2, 0x1fad3, 0x0bac0, 0x3765c, 0x1fedf, 0x1f225, 0x1fad4, + 0x2c7da, 0x5ce9d, 0x3e7f8, 0x1e203, 0x188d7, 0x00054, 0x002c0, 0x007a1, + 0x00f78, 0x01b36, 0x01fa3, 0x0313a, 0x03436, 0x0343a, 0x07d1d, 0x07bd8, + 0x05cdf, 0x0b846, 0x0b189, 0x0d9b8, 0x0fff8, 0x0d9be, 0x0c58a, 0x05dea, + 0x0d1d3, 0x160e4, 0x1f26b, 0x188da, 0x1e202, 0x2c7d2, 0x163fe, 0x31193, + 0x17782, 0x376c2, 0x2c7d1, 0x3fdb0, 0x3765d, 0x2c7d0, 0x1fad0, 0x1e201, + 0x188dd, 0x2c7e2, 0x37657, 0x37655, 0x376c4, 0x376c0, 0x176ea, 0x0006f, + 0x003cf, 0x00dd5, 0x01f23, 0x02c61, 0x02ed0, 0x05d54, 0x0552d, 0x07883, + 0x0b1a8, 0x0b91c, 0x0babf, 0x0b902, 0x0f7aa, 0x0f7a5, 0x1a1e8, 0x1ffd6, + 0x0babe, 0x1a1bf, 0x163f3, 0x1ffd8, 0x1fad7, 0x1f275, 0x1ffdc, 0x0007d, + 0x005bc, 0x01549, 0x02a99, 0x03def, 0x06273, 0x079d6, 0x07d1b, 0x0aad3, + 0x0d0fc, 0x2c7dd, 0x188d6, 0x0bac2, 0x2c7e1, 0x1bb76, 0x1a1bd, 0x31186, + 0x0fd78, 0x1a1be, 0x31183, 0x3fdb6, 0x3f4f1, 0x37652, 0x1fad5, 0x3f4f9, + 0x3e7ff, 0x5ce9c, 0x3765b, 0x31188, 0x17372, 0x000bd, 0x0078b, 0x01f21, + 0x03c43, 0x03ded, 0x0aad6, 0x07ec1, 0x0f942, 0x05c86, 0x17089, 0x0babb, + 0x1ffe8, 0x2c7de, 0x1f26e, 0x1fac4, 0x3f4f7, 0x37656, 0x1fa7d, 0x376c3, + 0x3fdb3, 0x3118f, 0x1fac6, 0x000f8, 0x007ed, 0x01efd, 0x03e7a, 0x05c91, + 0x0aad9, 0x0baec, 0x0dc32, 0x0f46e, 0x1e200, 0x176fa, 0x3765e, 0x3fdb7, + 0x2c7d6, 0x3fdb9, 0x37654, 0x37658, 0x3118e, 0x1ffdb, 0x000f6, 0x00c43, + 0x03106, 0x068ef, 0x0b84d, 0x0b188, 0x0bbcc, 0x1f264, 0x1bb69, 0x17386, + 0x1fac0, 0x00171, 0x00f39, 0x03e41, 0x068ed, 0x0d9bc, 0x0f7a1, 0x1bb67, + 0x1ffdd, 0x176f9, 0x001b9, 0x00f7d, 0x03f63, 0x0d0fd, 0x0b9ea, 0x188dc, + 0x1fac3, 0x1a1f2, 0x31192, 0x1ffe4, 0x001f6, 0x01754, 0x06865, 0x0f309, + 0x160e5, 0x176f5, 0x3765f, 0x1facc, 0x001e9, 0x01a1a, 0x06201, 0x0f105, + 0x176f0, 0x002df, 0x01756, 0x05d6d, 0x163fa, 0x176ed, 0x00342, 0x02e40, + 0x0d0ff, 0x17082, 0x003cd, 0x02a98, 0x0fffc, 0x2c7dc, 0x1fa7f, 0x003fe, + 0x03764, 0x0fffd, 0x176fc, 0x1fac5, 0x002f7, 0x02ed1, 0x0fb97, 0x0058a, + 0x02edc, 0x0bbc8, 0x005d4, 0x0623d, 0x160e8, 0x0062e, 0x05830, 0x163f9, + 0x006eb, 0x06205, 0x1f274, 0x007de, 0x062c9, 0x1f265, 0x005c9, 0x05cde, + 0x1ffd3, 0x005d4, 0x07988, 0x007ce, 0x0b849, 0x00b1b, 0x05c89, 0x1fac7, + 0x00b93, 0x05c83, 0x00b9e, 0x0f14f, 0x00c4a, 0x0b9c7, 0x00dd4, 0x0c470, + 0x1f271, 0x00f38, 0x0fb96, 0x176eb, 0x00fa0, 0x163f7, 0x00bb2, 0x0b91b, + 0x00bbe, 0x0f102, 0x00f44, 0x0f946, 0x1facd, 0x00f79, 0x0d9bd, 0x0154d, + 0x0bbc6, 0x00fd2, 0x160e7, 0x0172b, 0x188cb, 0x0175e, 0x0fd76, 0x0175c, + 0x1bb71, 0x0189f, 0x1a1ee, 0x01f24, 0x1a1f6, 0x01ba7, 0x0bbca, 0x01f7d, + 0x0ffff, 0x01f2e, 0x1bb65, 0x01bb5, 0x172f9, 0x01fef, 0x1f26c, 0x01f3e, + 0x0fd77, 0x01762, 0x1bb6e, 0x01ef9, 0x172fc, 0x01fa0, 0x02ab7, 0x02e4a, + 0x1f267, 0x01fb3, 0x1ffda, 0x02e42, 0x03101, 0x17780, 0x0313d, 0x03475, + 0x17784, 0x03126, 0x1facf, 0x03c51, 0x17783, 0x03e40, 0x1ffe5, 0x03663, + 0x1ffe0, 0x03e8f, 0x1f26d, 0x0343c, 0x03cc1, 0x176fd, 0x03e45, 0x02ec0, + 0x03f61, 0x03dee, 0x03fd8, 0x0583e, 0x02e45, 0x03e59, 0x03d02, 0x05ce8, + 0x05568, 0x176fe, 0x02f69, 0x1fad8, 0x058c1, 0x05c83, 0x1ffe6, 0x06271, + 0x06e1c, 0x062c7, 0x068e1, 0x0552f, 0x06864, 0x06866, 0x06e99, 0x05cbc, + 0x07ca5, 0x078a1, 0x05c82, 0x07dcf, 0x0623b, 0x0623e, 0x068e8, 0x07a36, + 0x05d9c, 0x0b077, 0x07cf3, 0x07a34, 0x07ca4, 0x07d19, 0x079d2, 0x07d1c, + 0x07bd9, 0x0b84a, 0x0fb94, 0x0aad5, 0x0dc30, 0x07bf3, 0x0baee, 0x0b07a, + 0x0c472, 0x0b91e, 0x0d9ba, 0x05d9f, 0x0d0fe, 0x0b9c6, 0x05c87, 0x0f14e, + 0x0baed, 0x0b92e, 0x0f103, 0x0b9c4, 0x0fb91, 0x0d9bb, 0x0b1ab, 0x0c58d, + 0x0fffe, 0x0f93b, 0x0f941, 0x0baea, 0x0b91f, 0x0f5cc, 0x0d9bf, 0x0f943, + 0x0f104, 0x1f260, 0x0fb92, 0x0f93f, 0x0f3a6, 0x0bac7, 0x0f7ab, 0x0bac6, + 0x17383, 0x0fd6d, 0x0bae9, 0x0fd6e, 0x1e74f, 0x188ca, 0x1f227, 0x0fb93, + 0x0fb90, 0x0fff7, 0x17085, 0x17083, 0x160e1, 0x17084, 0x0f93e, 0x160e2, + 0x160c6, 0x1a1f1, 0x1bb6f, 0x17384, 0x0fd70, 0x1f263, 0x188d5, 0x173a6, + 0x0f5ce, 0x163f2, 0x0fd71, 0x1ffd2, 0x160c4, 0x1ffd4, 0x2c7d3, 0x1bb74, +}; + +static const uint8_t coef3_huffbits[1072] = { + 9, 7, 2, 3, 4, 4, 5, 5, + 6, 6, 6, 6, 7, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 12, 11, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 14, 13, 14, 14, 13, 14, 13, + 13, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 15, + 14, 14, 15, 14, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 14, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 16, 15, 16, 16, 16, + 16, 15, 15, 16, 16, 16, 16, 16, + 15, 16, 16, 16, 15, 16, 15, 15, + 16, 15, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 17, 16, 17, 16, 17, 17, 16, + 17, 16, 17, 16, 16, 17, 17, 17, + 16, 17, 16, 16, 17, 16, 17, 16, + 17, 17, 16, 16, 17, 17, 17, 17, + 17, 17, 17, 17, 16, 17, 17, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 16, 18, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 16, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 18, + 17, 17, 17, 17, 18, 17, 17, 18, + 19, 17, 17, 17, 18, 17, 17, 17, + 18, 18, 18, 17, 17, 17, 18, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 17, 18, 18, 18, 18, 17, + 18, 18, 18, 17, 17, 18, 18, 18, + 18, 19, 18, 18, 19, 19, 20, 18, + 19, 18, 19, 19, 18, 19, 20, 18, + 19, 4, 6, 7, 8, 9, 9, 9, + 10, 10, 10, 11, 11, 11, 11, 12, + 12, 12, 12, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 16, 15, 15, 15, + 15, 16, 16, 15, 16, 16, 15, 16, + 17, 17, 17, 17, 17, 16, 16, 16, + 16, 16, 17, 17, 17, 16, 18, 17, + 17, 17, 18, 17, 17, 18, 17, 17, + 17, 17, 17, 18, 17, 18, 18, 18, + 17, 17, 18, 19, 18, 18, 17, 17, + 18, 18, 18, 18, 19, 17, 17, 18, + 20, 19, 19, 18, 19, 18, 19, 19, + 19, 19, 17, 5, 7, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 15, + 14, 15, 15, 15, 15, 15, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 15, 16, 16, 17, 17, 17, + 16, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 16, + 16, 19, 18, 18, 19, 17, 19, 20, + 17, 18, 18, 18, 18, 18, 18, 6, + 8, 10, 11, 12, 12, 12, 13, 13, + 13, 14, 14, 14, 14, 15, 15, 15, + 15, 15, 15, 16, 16, 16, 16, 16, + 16, 17, 17, 17, 16, 16, 17, 17, + 17, 17, 17, 17, 17, 16, 16, 16, + 17, 18, 18, 18, 17, 19, 19, 18, + 18, 17, 18, 19, 18, 17, 18, 18, + 19, 18, 17, 17, 6, 9, 11, 12, + 13, 13, 13, 14, 14, 14, 15, 15, + 15, 15, 15, 16, 16, 16, 16, 16, + 16, 17, 16, 17, 17, 17, 17, 17, + 17, 17, 18, 17, 18, 17, 17, 18, + 18, 19, 19, 17, 17, 7, 10, 12, + 13, 13, 14, 14, 14, 14, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 17, 17, 17, 17, 18, 17, 18, + 18, 18, 18, 18, 18, 18, 18, 17, + 17, 18, 18, 18, 18, 18, 18, 7, + 10, 12, 13, 14, 15, 15, 15, 15, + 16, 16, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 18, 17, 17, 8, + 11, 13, 14, 15, 15, 15, 15, 16, + 16, 18, 17, 17, 18, 17, 17, 18, + 17, 17, 18, 18, 19, 18, 18, 19, + 19, 19, 18, 18, 18, 8, 11, 13, + 14, 15, 16, 16, 16, 16, 17, 17, + 17, 18, 17, 18, 19, 18, 18, 18, + 18, 18, 18, 8, 12, 14, 15, 15, + 16, 16, 16, 17, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 17, 9, 12, + 14, 15, 16, 16, 17, 17, 17, 17, + 18, 9, 12, 14, 15, 16, 17, 17, + 17, 18, 9, 13, 15, 16, 17, 17, + 18, 17, 18, 17, 9, 13, 15, 16, + 17, 18, 18, 18, 10, 13, 15, 16, + 18, 10, 14, 16, 17, 18, 10, 14, + 16, 17, 10, 14, 16, 18, 18, 10, + 14, 16, 18, 18, 11, 15, 16, 11, + 15, 17, 11, 15, 17, 11, 15, 17, + 11, 15, 17, 11, 15, 17, 12, 16, + 17, 12, 15, 12, 16, 12, 16, 18, + 12, 16, 12, 16, 12, 16, 12, 16, + 17, 12, 16, 18, 12, 17, 13, 16, + 13, 16, 13, 16, 18, 13, 16, 13, + 17, 13, 17, 13, 17, 13, 17, 13, + 17, 13, 17, 13, 17, 13, 17, 13, + 16, 13, 17, 13, 17, 13, 17, 14, + 17, 14, 17, 14, 17, 14, 14, 14, + 17, 14, 17, 14, 14, 18, 14, 14, + 18, 14, 18, 14, 18, 14, 17, 14, + 17, 14, 17, 14, 14, 18, 14, 15, + 15, 15, 14, 15, 15, 14, 15, 15, + 15, 18, 15, 18, 15, 15, 17, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 16, 15, 15, 15, 15, 16, + 16, 16, 16, 16, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 16, 16, + 16, 17, 16, 16, 16, 17, 17, 17, + 17, 17, 16, 17, 17, 17, 17, 16, + 16, 16, 17, 17, 17, 17, 16, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 18, 17, +}; + +static const uint32_t coef4_huffcodes[476] = { + 0x00f01, 0x0001e, 0x00000, 0x00004, 0x00006, 0x0000d, 0x0000a, 0x00017, + 0x0001d, 0x00017, 0x0002c, 0x00031, 0x00039, 0x0003e, 0x00039, 0x0005a, + 0x00066, 0x00070, 0x0007b, 0x00070, 0x00077, 0x000af, 0x000c9, 0x000f2, + 0x000f4, 0x000b2, 0x000e3, 0x0015b, 0x0015d, 0x00181, 0x0019d, 0x001e3, + 0x001c5, 0x002b5, 0x002db, 0x00338, 0x003c3, 0x003cc, 0x003f0, 0x002cd, + 0x003fa, 0x003a1, 0x005b4, 0x00657, 0x007ab, 0x0074d, 0x0074c, 0x00ac1, + 0x00ac5, 0x0076b, 0x00ca8, 0x00f04, 0x00f00, 0x00fe3, 0x00f3c, 0x00f10, + 0x00f39, 0x00fe6, 0x00e26, 0x00e90, 0x016c5, 0x01827, 0x01954, 0x015c5, + 0x01958, 0x01f8a, 0x01c4a, 0x02b0f, 0x02b41, 0x02b0e, 0x033c6, 0x03050, + 0x01c4f, 0x02d88, 0x0305c, 0x03c18, 0x02b4f, 0x02cc2, 0x03a47, 0x05680, + 0x0569d, 0x06442, 0x06443, 0x06446, 0x0656e, 0x06444, 0x07120, 0x0748a, + 0x0c1ba, 0x07e22, 0x07aa6, 0x07f25, 0x07aa7, 0x07e20, 0x0c11b, 0x0c118, + 0x07aa5, 0x0ad0a, 0x0f389, 0x19ebb, 0x0caad, 0x0fe42, 0x0fe40, 0x16c34, + 0x2b4e5, 0x33d65, 0x16c30, 0x1e7ae, 0x1e25c, 0x18370, 0x1e703, 0x19eba, + 0x16c37, 0x0e234, 0x16c6e, 0x00004, 0x0002a, 0x00061, 0x00075, 0x000cb, + 0x000ff, 0x00190, 0x001eb, 0x001d1, 0x002b9, 0x00307, 0x00339, 0x0033f, + 0x003fb, 0x003b4, 0x0060c, 0x00679, 0x00645, 0x0067d, 0x0078a, 0x007e3, + 0x00749, 0x00ac4, 0x00ad2, 0x00ae3, 0x00c10, 0x00c16, 0x00ad1, 0x00cf4, + 0x00fe2, 0x01586, 0x00e9d, 0x019f1, 0x01664, 0x01e26, 0x01d38, 0x02b4d, + 0x033c5, 0x01fc2, 0x01fc3, 0x01d28, 0x03c1d, 0x0598e, 0x0f094, 0x07aa4, + 0x0ad38, 0x0ac0c, 0x0c11a, 0x079ea, 0x0c881, 0x0fe44, 0x0b635, 0x0ac0d, + 0x0b61e, 0x05987, 0x07121, 0x0f382, 0x0f387, 0x0e237, 0x0fe47, 0x0f383, + 0x0f091, 0x0f385, 0x0e233, 0x182ee, 0x19eb8, 0x1663e, 0x0f093, 0x00014, + 0x00058, 0x00159, 0x00167, 0x00300, 0x003d4, 0x005b5, 0x0079d, 0x0076a, + 0x00b67, 0x00b60, 0x00f05, 0x00cf0, 0x00f17, 0x00e95, 0x01822, 0x01913, + 0x016c2, 0x0182f, 0x01959, 0x01fcb, 0x01e27, 0x01c40, 0x033c7, 0x01e7b, + 0x01c49, 0x02d89, 0x01e23, 0x01660, 0x03f12, 0x02cc6, 0x033e1, 0x05b34, + 0x0609a, 0x06569, 0x07488, 0x07e21, 0x0cf5f, 0x0712c, 0x0389d, 0x067cf, + 0x07f28, 0x1663f, 0x33d67, 0x1663d, 0x1e25d, 0x3c1ab, 0x15c44, 0x16c36, + 0x0001f, 0x000ec, 0x00323, 0x005b2, 0x0079f, 0x00ac2, 0x00f16, 0x00e9e, + 0x01956, 0x01e0f, 0x019ea, 0x01666, 0x02b89, 0x02b02, 0x02d8c, 0x03c1b, + 0x03c19, 0x032b5, 0x03f9c, 0x02ccf, 0x03897, 0x05b35, 0x0ad02, 0x07f29, + 0x06441, 0x03884, 0x07888, 0x0784e, 0x06568, 0x0c1bb, 0x05986, 0x067cc, + 0x0fe49, 0x0fe48, 0x0c1bc, 0x0fe41, 0x18371, 0x1663c, 0x0e231, 0x0711e, + 0x0ad09, 0x0f092, 0x0002d, 0x001db, 0x00781, 0x00c1a, 0x00f55, 0x01580, + 0x01ea8, 0x02d9b, 0x032af, 0x03f16, 0x03c1c, 0x07834, 0x03c45, 0x0389c, + 0x067ce, 0x06445, 0x0c1b9, 0x07889, 0x07f3a, 0x0784f, 0x07f2b, 0x0ad0b, + 0x0f090, 0x0c11d, 0x0e94e, 0x0711f, 0x0e9f1, 0x0f38e, 0x079e9, 0x0ad03, + 0x0f09b, 0x0caae, 0x0fe46, 0x2b4e6, 0x0e9f0, 0x19eb6, 0x67ac1, 0x67ac0, + 0x33d66, 0x0f388, 0x00071, 0x003a0, 0x00ca9, 0x01829, 0x01d39, 0x02b43, + 0x02cc4, 0x06554, 0x0f09a, 0x0b61f, 0x067cd, 0x0711c, 0x0b636, 0x07f2a, + 0x0b634, 0x0c11f, 0x0cf5e, 0x0b61d, 0x0f06b, 0x0caab, 0x0c1be, 0x0e94c, + 0x0f099, 0x182ed, 0x0e94f, 0x0c119, 0x0e232, 0x2b4e4, 0x0f38a, 0x19eb4, + 0x1e25f, 0x0e94d, 0x000b7, 0x00785, 0x016cc, 0x03051, 0x033c4, 0x0656f, + 0x03891, 0x0711d, 0x0caaf, 0x0f097, 0x07489, 0x0f098, 0x0c880, 0x0caaa, + 0x0f386, 0x19eb7, 0x16c6f, 0x0f384, 0x182e8, 0x182e9, 0x0e230, 0x1e700, + 0x33d62, 0x33d63, 0x33d64, 0x16c33, 0x0e216, 0x000fd, 0x00c15, 0x01665, + 0x03c4a, 0x07f3b, 0x07896, 0x0c11c, 0x0e215, 0x16c32, 0x0f38b, 0x0f38d, + 0x182ea, 0x1e701, 0x712df, 0x15c46, 0x00194, 0x00fe0, 0x03f13, 0x0748b, + 0x0f096, 0x0cf80, 0x1e25e, 0xe25bd, 0x33d61, 0x16c31, 0x001f9, 0x01912, + 0x05710, 0x0f3d0, 0x0c1bf, 0x00301, 0x01e24, 0x0ad08, 0x003cd, 0x01c41, + 0x0c1bd, 0x00563, 0x03a52, 0x0f3d1, 0x00570, 0x02cce, 0x0e217, 0x0067b, + 0x0655d, 0x0074b, 0x06447, 0x00c12, 0x074fb, 0x00f08, 0x0b61c, 0x00e22, + 0x0fe43, 0x016c7, 0x01836, 0x019f2, 0x01c43, 0x01d3f, 0x01fcf, 0x02b4c, + 0x0304c, 0x032b6, 0x03a46, 0x05607, 0x03f17, 0x02cc5, 0x0609b, 0x0655c, + 0x07e23, 0x067c1, 0x07f26, 0x07f27, 0x0f095, 0x0e9f3, 0x0cf81, 0x0c11e, + 0x0caac, 0x0f38f, 0x0e9f2, 0x074fa, 0x0e236, 0x0fe45, 0x1c428, 0x0e235, + 0x182ef, 0x19eb5, 0x0f3d6, 0x182ec, 0x16c35, 0x0f38c, 0x2b4e7, 0x15c47, + 0xe25bc, 0x1e702, 0x1c4b6, 0x0e25a, 0x3c1aa, 0x15c45, 0x1c429, 0x19eb9, + 0x1e7af, 0x182eb, 0x1e0d4, 0x3896e, +}; + +static const uint8_t coef4_huffbits[476] = { + 12, 6, 2, 3, 4, 4, 5, 5, + 5, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 11, + 10, 11, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 13, 13, 13, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 16, 16, + 16, 15, 15, 15, 15, 15, 16, 16, + 15, 16, 16, 17, 16, 16, 16, 17, + 18, 18, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 4, 6, 7, 8, 8, + 8, 9, 9, 10, 10, 10, 10, 10, + 10, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 13, 13, 13, 14, 13, 14, 14, + 14, 13, 13, 14, 14, 16, 16, 15, + 16, 16, 16, 15, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 16, 16, + 16, 16, 17, 17, 17, 18, 16, 5, + 8, 9, 10, 10, 10, 11, 11, 12, + 12, 12, 12, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 14, 14, 13, + 14, 14, 13, 14, 14, 15, 14, 15, + 15, 15, 16, 15, 16, 16, 15, 15, + 15, 18, 18, 18, 17, 18, 17, 17, + 6, 9, 10, 11, 11, 12, 12, 13, + 13, 13, 13, 14, 14, 14, 14, 14, + 14, 14, 14, 15, 15, 15, 16, 15, + 15, 15, 15, 15, 15, 16, 16, 15, + 16, 16, 16, 16, 17, 18, 17, 16, + 16, 16, 7, 10, 11, 12, 12, 13, + 13, 14, 14, 14, 14, 15, 14, 15, + 15, 15, 16, 15, 15, 15, 15, 16, + 16, 16, 17, 16, 17, 16, 15, 16, + 16, 16, 16, 18, 17, 17, 19, 19, + 18, 16, 7, 11, 12, 13, 14, 14, + 15, 15, 16, 16, 15, 16, 16, 15, + 16, 16, 16, 16, 16, 16, 16, 17, + 16, 17, 17, 16, 17, 18, 16, 17, + 17, 17, 8, 11, 13, 14, 14, 15, + 15, 16, 16, 16, 16, 16, 16, 16, + 16, 17, 17, 16, 17, 17, 17, 17, + 18, 18, 18, 17, 17, 8, 12, 14, + 14, 15, 15, 16, 17, 17, 16, 16, + 17, 17, 20, 17, 9, 12, 14, 16, + 16, 16, 17, 21, 18, 17, 9, 13, + 15, 16, 16, 10, 13, 16, 10, 14, + 16, 11, 15, 16, 11, 15, 17, 11, + 15, 12, 15, 12, 16, 12, 16, 13, + 16, 13, 13, 13, 14, 14, 13, 14, + 14, 14, 15, 15, 14, 15, 15, 15, + 15, 15, 15, 15, 16, 17, 16, 16, + 16, 16, 17, 16, 17, 16, 18, 17, + 17, 17, 16, 17, 17, 16, 18, 17, + 21, 17, 18, 17, 18, 17, 18, 17, + 17, 17, 17, 19, +}; + +static const uint32_t coef5_huffcodes[435] = { + 0x00347, 0x0000b, 0x00001, 0x00001, 0x0000c, 0x00004, 0x00010, 0x00015, + 0x0001f, 0x0000b, 0x00023, 0x00026, 0x00029, 0x00035, 0x00037, 0x00001, + 0x00015, 0x0001a, 0x0001d, 0x0001c, 0x0001e, 0x0004e, 0x00049, 0x00051, + 0x00078, 0x00004, 0x00000, 0x00008, 0x0000d, 0x0007b, 0x00005, 0x00032, + 0x00095, 0x00091, 0x00096, 0x000a1, 0x000d9, 0x00003, 0x00019, 0x00061, + 0x00066, 0x00060, 0x00017, 0x0000e, 0x00063, 0x001a0, 0x001b7, 0x001e6, + 0x001e7, 0x001b6, 0x00018, 0x001e8, 0x00038, 0x00031, 0x00005, 0x0003d, + 0x00027, 0x001ea, 0x0001a, 0x000c5, 0x000f9, 0x000ff, 0x000db, 0x00250, + 0x000fc, 0x0025c, 0x00008, 0x00075, 0x003d7, 0x003d3, 0x001b0, 0x0007c, + 0x003ca, 0x00036, 0x00189, 0x004a6, 0x004a2, 0x004fb, 0x000c0, 0x0007f, + 0x0009a, 0x00311, 0x0006e, 0x0009b, 0x0068c, 0x006c0, 0x00484, 0x00012, + 0x000c3, 0x0094f, 0x00979, 0x009f9, 0x00d09, 0x00da6, 0x00da8, 0x00901, + 0x000c1, 0x00373, 0x00d08, 0x009fa, 0x00d8b, 0x00d85, 0x00d86, 0x000df, + 0x006e2, 0x000ce, 0x00f24, 0x009fe, 0x001f7, 0x007c1, 0x000cf, 0x009fc, + 0x009ff, 0x00d89, 0x00da9, 0x009fd, 0x001f8, 0x01a36, 0x0128c, 0x0129d, + 0x01a37, 0x00196, 0x003ea, 0x00f8b, 0x00d93, 0x01e45, 0x01e58, 0x01e4b, + 0x01e59, 0x013f1, 0x00309, 0x00265, 0x00308, 0x0243a, 0x027e1, 0x00f89, + 0x00324, 0x03cbc, 0x03c86, 0x03695, 0x0243c, 0x0243b, 0x0243e, 0x01e4a, + 0x003a5, 0x03468, 0x03428, 0x03c84, 0x027e0, 0x025e2, 0x01880, 0x00197, + 0x00325, 0x03cb7, 0x0791e, 0x007ec, 0x06c75, 0x004c8, 0x04bc7, 0x004c6, + 0x00983, 0x0481e, 0x01b53, 0x0251b, 0x01b58, 0x00984, 0x04fa8, 0x03cbb, + 0x00f8a, 0x00322, 0x0346a, 0x0243d, 0x00326, 0x03469, 0x0481f, 0x0481d, + 0x00746, 0x09032, 0x01b50, 0x01d13, 0x0d8e4, 0x0481b, 0x06c74, 0x0796b, + 0x07969, 0x00985, 0x0d8e3, 0x00986, 0x00fa2, 0x01301, 0x06c7c, 0x00987, + 0x03cb8, 0x0f4af, 0x00e88, 0x1b1c0, 0x00fce, 0x033eb, 0x03f6a, 0x03f69, + 0x00fcf, 0x0791f, 0x004c9, 0x04871, 0x00fcd, 0x00982, 0x00fcc, 0x00fa3, + 0x01d12, 0x0796c, 0x01b47, 0x00321, 0x0796a, 0x0d8e2, 0x04872, 0x04873, + 0x0000e, 0x00014, 0x0000a, 0x000a0, 0x00012, 0x0007d, 0x001a2, 0x0003b, + 0x0025f, 0x000dd, 0x0027c, 0x00343, 0x00368, 0x0036b, 0x0003e, 0x001fa, + 0x00485, 0x001b3, 0x0007f, 0x001b1, 0x0019e, 0x004ba, 0x007ad, 0x00339, + 0x00066, 0x007a4, 0x00793, 0x006c6, 0x0007e, 0x000f1, 0x00372, 0x009fb, + 0x00d83, 0x00d8a, 0x00947, 0x009f4, 0x001d0, 0x01b09, 0x01b4b, 0x007ec, + 0x003e1, 0x000ca, 0x003ec, 0x02539, 0x04fa9, 0x01b57, 0x03429, 0x03d2a, + 0x00d97, 0x003a7, 0x00dc0, 0x00d96, 0x00dc1, 0x007eb, 0x03cba, 0x00c43, + 0x00c41, 0x01b52, 0x007ef, 0x00323, 0x03cb9, 0x03c83, 0x007d0, 0x007ed, + 0x06c7f, 0x09033, 0x03f6c, 0x36383, 0x1e95d, 0x06c78, 0x00747, 0x01b51, + 0x00022, 0x00016, 0x00039, 0x00252, 0x00079, 0x00486, 0x00338, 0x00369, + 0x00d88, 0x00026, 0x00d87, 0x00f4b, 0x00d82, 0x00027, 0x001e1, 0x01a15, + 0x007c7, 0x012f0, 0x001e0, 0x006d0, 0x01a16, 0x01e44, 0x01e5f, 0x03690, + 0x00d90, 0x00c42, 0x00daf, 0x00d92, 0x00f80, 0x00cfb, 0x0342f, 0x0487f, + 0x01b46, 0x07968, 0x00d95, 0x00d91, 0x01b55, 0x03f68, 0x04bc6, 0x03cbd, + 0x00f81, 0x00320, 0x00069, 0x000fe, 0x006d5, 0x0033f, 0x000de, 0x007c6, + 0x01e40, 0x00d94, 0x00f88, 0x03c8e, 0x03694, 0x00dae, 0x00dad, 0x00267, + 0x003a6, 0x00327, 0x0487e, 0x007ee, 0x00749, 0x004c7, 0x03692, 0x01b56, + 0x00fd1, 0x07a56, 0x06c77, 0x09031, 0x00748, 0x06c7a, 0x0796d, 0x033ea, + 0x06c76, 0x00fd0, 0x36382, 0x1e417, 0x00745, 0x04faf, 0x0d8e1, 0x03f6b, + 0x1e95c, 0x04fad, 0x0009e, 0x004bd, 0x0067c, 0x01b08, 0x003eb, 0x01b45, + 0x03691, 0x0d8e5, 0x07904, 0x00981, 0x007ea, 0x019f4, 0x06c7d, 0x04fab, + 0x04fac, 0x06c7e, 0x01300, 0x06c7b, 0x0006f, 0x003f7, 0x03c85, 0x004c4, + 0x0001e, 0x006e1, 0x03693, 0x01b44, 0x00241, 0x01e46, 0x0019d, 0x00266, + 0x004bb, 0x02538, 0x007ac, 0x01b54, 0x00902, 0x04870, 0x00da7, 0x00900, + 0x00185, 0x06c79, 0x006e3, 0x003e9, 0x01e94, 0x003ed, 0x003f2, 0x0342e, + 0x0346b, 0x0251a, 0x004c5, 0x01881, 0x0481c, 0x01b59, 0x03c87, 0x04fae, + 0x007e9, 0x03f6d, 0x0f20a, 0x09030, 0x04faa, 0x0d8e6, 0x03f6f, 0x0481a, + 0x03f6e, 0x1e416, 0x0d8e7, +}; + +static const uint8_t coef5_huffbits[435] = { + 10, 4, 2, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 6, 6, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 8, 8, 8, 8, 7, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 10, 9, 10, 10, 10, 10, + 10, 9, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 10, 10, 11, 11, + 10, 11, 11, 11, 11, 11, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 13, + 13, 13, 12, 12, 13, 13, 13, 12, + 12, 12, 12, 12, 13, 13, 13, 13, + 13, 14, 14, 14, 14, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, + 15, 14, 14, 14, 14, 14, 14, 13, + 14, 14, 14, 14, 14, 14, 15, 14, + 15, 14, 15, 15, 15, 15, 15, 15, + 16, 15, 15, 14, 15, 16, 15, 14, + 14, 15, 14, 14, 15, 14, 15, 15, + 15, 16, 15, 17, 16, 15, 15, 15, + 15, 16, 16, 16, 16, 17, 15, 16, + 14, 16, 16, 17, 16, 16, 16, 16, + 16, 15, 15, 15, 16, 16, 16, 16, + 17, 15, 15, 15, 15, 16, 15, 15, + 4, 7, 8, 8, 9, 9, 9, 10, + 10, 10, 10, 10, 10, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 12, + 12, 11, 11, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 13, 13, 13, 13, + 12, 13, 14, 14, 15, 15, 14, 14, + 14, 14, 14, 14, 14, 15, 14, 14, + 14, 15, 15, 15, 14, 14, 15, 15, + 15, 16, 16, 18, 17, 15, 15, 15, + 6, 9, 10, 10, 11, 11, 12, 12, + 12, 13, 12, 12, 12, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 15, + 15, 15, 14, 14, 15, 16, 15, 14, + 14, 15, 7, 10, 11, 12, 13, 13, + 13, 14, 14, 14, 14, 14, 14, 14, + 14, 15, 15, 15, 15, 15, 14, 15, + 16, 15, 15, 16, 15, 15, 15, 16, + 15, 16, 18, 17, 15, 15, 16, 16, + 17, 15, 8, 11, 13, 13, 14, 15, + 14, 16, 15, 16, 15, 15, 15, 15, + 15, 15, 17, 15, 9, 12, 14, 15, + 10, 13, 14, 15, 10, 13, 11, 14, + 11, 14, 11, 15, 12, 15, 12, 12, + 13, 15, 13, 14, 13, 14, 14, 14, + 14, 14, 15, 15, 15, 15, 14, 15, + 15, 16, 16, 16, 15, 16, 16, 15, + 16, 17, 16, +}; + +static const uint16_t levels0[60] = { +317, 92, 62, 60, 19, 17, 10, 7, + 6, 5, 5, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, +}; + +static const uint16_t levels1[40] = { +311, 91, 61, 28, 10, 6, 5, 2, + 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t levels2[340] = { +181,110, 78, 63, 61, 62, 60, 61, + 33, 41, 41, 19, 17, 19, 12, 11, + 9, 11, 10, 6, 8, 7, 6, 4, + 5, 5, 4, 4, 3, 4, 3, 5, + 3, 4, 3, 3, 3, 3, 3, 3, + 2, 2, 4, 2, 3, 2, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, + 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 2, 1, 2, 2, + 2, 2, 1, 2, 1, 1, 1, 2, + 2, 1, 2, 1, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, +}; + +static const uint16_t levels3[180] = { +351,122, 76, 61, 41, 42, 24, 30, + 22, 19, 11, 9, 10, 8, 5, 5, + 4, 5, 5, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 3, 2, 2, 2, + 3, 3, 2, 2, 2, 3, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, + 2, 2, 1, 2, 1, 2, 2, 2, + 2, 2, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, +}; + +static const uint16_t levels4[70] = { +113, 68, 49, 42, 40, 32, 27, 15, + 10, 5, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t levels5[40] = { +214, 72, 42, 40, 18, 4, 4, 2, + 2, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const CoefVLCTable coef_vlcs[6] = { + { + sizeof(coef0_huffbits), coef0_huffcodes, coef0_huffbits, levels0, + }, + { + sizeof(coef1_huffbits), coef1_huffcodes, coef1_huffbits, levels1, + }, + { + sizeof(coef2_huffbits), coef2_huffcodes, coef2_huffbits, levels2, + }, + { + sizeof(coef3_huffbits), coef3_huffcodes, coef3_huffbits, levels3, + }, + { + sizeof(coef4_huffbits), coef4_huffcodes, coef4_huffbits, levels4, + }, + { + sizeof(coef5_huffbits), coef5_huffcodes, coef5_huffbits, levels5, + }, +}; + +/*table of the values of 10^(index*.05)*/ +const fixed64 pow_table[] ICONST_ATTR_WMA_XL_IRAM = + { 0x199a, 0x1cb9, 0x203a, 0x2429, 0x2893, 0x2d86, 0x3314, 0x3950, 0x404e, + 0x4827, 0x50f4, 0x5ad5, 0x65ea, 0x725a, 0x804e, 0x8ff6, 0xa186, 0xb53c, + 0xcb59, 0xe429, 0x10000LL,0x11f3dLL,0x14249LL,0x1699cLL,0x195bcLL, + 0x1c73dLL,0x1fec9LL,0x23d1dLL,0x2830bLL,0x2d182LL, 0x3298bLL,0x38c53LL, + 0x3fb28LL,0x47783LL,0x5030aLL,0x59f98LL,0x64f40LL,0x71457LL,0x7f17bLL, + 0x8e99aLL,0xa0000LL,0xb385eLL,0xc96d9LL,0xe2019LL,0xfd954LL,0x11c865LL, + 0x13f3dfLL,0x166320LL,0x191e6eLL,0x1c2f10LL,0x1f9f6eLL,0x237b39LL, + 0x27cf8bLL,0x2cab1aLL,0x321e65LL,0x383bf0LL,0x3f1882LL,0x46cb6aLL, + 0x4f6eceLL,0x592006LL,0x640000LL,0x7033acLL,0x7de47eLL,0x8d40f6LL, + 0x9e7d44LL,0xb1d3f4LL,0xc786b7LL,0xdfdf43LL,0xfb304bLL,0x119d69aLL, + 0x13c3a4eLL,0x162d03aLL,0x18e1b70LL,0x1beaf00LL,0x1f52feeLL, + 0x2325760LL,0x276f514LL,0x2c3f220LL,0x31a5408LL,0x37b403cLL,0x3e80000LL, + 0x46204b8LL,0x4eaece8LL,0x58489a0LL,0x630e4a8LL,0x6f24788LL,0x7cb4328LL, + 0x8beb8a0LL,0x9cfe2f0LL,0xb026200LL,0xc5a4710LL,0xddc2240LL,0xf8d1260LL, + 0x1172d600LL,0x1393df60LL,0x15f769c0LL,0x18a592c0LL,0x1ba77540LL, + 0x1f074840LL,0x22d08280LL,0x27100000LL,0x2bd42f40LL,0x312d4100LL, + 0x372d6000LL,0x3de8ee80LL,0x4576cb80LL,0x4df09f80LL,0x57733600LL, + 0x621edd80LL,0x6e17d480LL,0x7b86c700LL,0x8a995700LL,0x9b82b800LL, + 0xae7c5c00LL,0xc3c6b900LL,0xdbaa2200LL,0xf677bc00LL,0x1148a9400LL, + 0x13648d200LL,0x15c251800LL,0x186a00000LL,0x1b649d800LL,0x1ebc48a00LL, + 0x227c5c000LL,0x26b195000LL,0x2b6a3f000LL,0x30b663c00LL,0x36a801c00LL, + 0x3d534a400LL,0x44cee4800LL,0x4d343c800LL,0x569fd6000LL,0x6131b2800LL, + 0x6d0db9800LL,0x7a5c33800LL,0x894a55000LL,0x9a0ad6000LL,0xacd69d000LL, + 0xc1ed84000LL,0xd9972f000LL,0xf42400000LL,0x111ee28000LL,0x1335ad6000LL, + 0x158db98000LL,0x182efd4000LL,0x1b22676000LL,0x1e71fe6000LL, + 0x2229014000LL,0x26540e8000LL,0x2b014f0000LL,0x3040a5c000LL, + 0x3623e60000LL,0x3cbf0fc000LL,0x4428940000LL,0x4c79a08000LL, + 0x55ce758000LL,0x6046c58000LL,0x6c06220000LL,0x7934728000LL, + 0x87fe7d0000LL,0x9896800000LL,0xab34d90000LL,0xc018c60000LL, + 0xd7893f0000LL,0xf1d5e40000LL,0x10f580a0000LL,0x13073f00000LL, + 0x1559a0c0000LL,0x17f48900000LL,0x1ae0d160000LL,0x1e286780000LL, + 0x21d66fc0000LL,0x25f769c0000LL,0x2a995c80000LL,0x2fcc0440000LL, + 0x35a10940000LL,0x3c2c3b80000LL,0x4383d500000LL,0x4bc0c780000LL, + 0x54ff0e80000LL,0x5f5e1000000LL,0x6b010780000LL,0x780f7c00000LL, + 0x86b5c800000LL,0x9725ae00000LL,0xa9970600000LL,0xbe487500000LL, + 0xd5804700000LL,0xef8d5a00000LL,0x10cc82e00000LL,0x12d940c00000LL, + 0x152605c00000LL,0x17baa2200000LL,0x1a9fd9c00000LL,0x1ddf82a00000LL, + 0x2184a5c00000LL,0x259ba5400000LL,0x2a3265400000LL,0x2f587cc00000LL, + 0x351f69000000LL,0x3b9aca000000LL,0x42e0a4800000LL,0x4b09ad800000LL, + 0x54319d000000LL,0x5e778d000000LL,0x69fe64000000LL,0x76ed49800000LL, + 0x85702c000000LL,0x95b858000000LL,0xa7fd1c000000LL,0xbc7c87000000LL, + 0xd37c3a000000LL,0xed4a55000000LL,0x10a3e82000000LL,0x12abb1a000000LL, + 0x14f2e7a000000LL,0x1781474000000LL,0x1a5f7f4000000LL,0x1d974de000000LL, + 0x2133a18000000LL + }; + +/* 10^(index/16). We'll need to accomidate negative indicies too. + The algorithm sort of implies that there should be 128 values starting at -60, + however this has not been confirmed. More values may be needed. +*/ + +#define ICONST_ATTR +const fixed32 pow_10_to_yover16[] ICONST_ATTR= +{ + /*60 negative indicies (-60 to -1)*/ + 0xc, 0xd, 0x10, 0x12, 0x15, 0x18, 0x1c, 0x20, 0x25, 0x2b, 0x31, 0x39, 0x42, + 0x4c, 0x57, 0x65, 0x75, 0x87, 0x9b, 0xb3, 0xcf, 0xef, 0x114, 0x13f, 0x171, + 0x1aa, 0x1eb, 0x238, 0x28f, 0x2f5, 0x36a, 0x3f1, 0x48d, 0x542, 0x612, 0x703, + 0x818, 0x959, 0xacc, 0xc77, 0xe65, 0x10a0, 0x1333, 0x162b, 0x199a, 0x1d90, + 0x2223, 0x276c, 0x2d86, 0x3492, 0x3cb5, 0x461b, 0x50f4, 0x5d7c, 0x6bf4, + 0x7caa, 0x8ff6, 0xa63e, 0xbff9, 0xddb0, + /*non-negative indicies (0-68)*/ + 0x10000, 0x127a0, 0x15562, 0x18a39, 0x1c73d, 0x20db4, 0x25f12, 0x2bd09, + 0x3298b, 0x3a6d9, 0x4378b, 0x4dea3, 0x59f98, 0x67e6b, 0x77fbb, 0x8a8de, + 0xa0000, 0xb8c3e, 0xd55d1, 0xf6636, 0x11c865, 0x148906, 0x17b6b7, 0x1b625b, + 0x1f9f6e, 0x248475, 0x2a2b6e, 0x30b25e, 0x383bf0, 0x40f02b, 0x4afd4b, + 0x5698b0, 0x640000, 0x737a6b, 0x855a26, 0x99fe1e, 0xb1d3f4, 0xcd5a3e, + 0xed232b, 0x111d78b, 0x13c3a4f, 0x16d2c94, 0x1a5b24e, 0x1e6f7b0, 0x2325761, + 0x28961b3, 0x2ede4eb, 0x361f6de, 0x3e80000, 0x482c830, 0x535857d, 0x603ed31, + 0x6f24787, 0x8058668, 0x9435fab, 0xab26b6d, 0xc5a4715, 0xe43bdc4, + 0x1078f70c, 0x1305acdd, 0x15f769cb, 0x195dd0fa, 0x1d4af12d, 0x21d3a4ab, + 0x27100000, 0x2d1bd1e1, 0x341736de, 0x3c2743e8, 0x4576cb4a +}; + +const fixed32 pow_a_table[] ICONST_ATTR_WMA_XL_IRAM = +{ + 0x1004,0x1008,0x100c,0x1010,0x1014,0x1018,0x101c,0x1021,0x1025,0x1029,0x102d, + 0x1031,0x1036,0x103a,0x103e,0x1043,0x1047,0x104b,0x1050,0x1054,0x1059,0x105d, + 0x1062,0x1066,0x106b,0x106f,0x1074,0x1078,0x107d,0x1082,0x1086,0x108b,0x1090, + 0x1095,0x1099,0x109e,0x10a3,0x10a8,0x10ad,0x10b2,0x10b7,0x10bc,0x10c1,0x10c6, + 0x10cb,0x10d0,0x10d5,0x10da,0x10df,0x10e5,0x10ea,0x10ef,0x10f5,0x10fa,0x10ff, + 0x1105,0x110a,0x1110,0x1115,0x111b,0x1120,0x1126,0x112c,0x1131,0x1137,0x113d, + 0x1143,0x1149,0x114f,0x1155,0x115a,0x1161,0x1167,0x116d,0x1173,0x1179,0x117f, + 0x1186,0x118c,0x1192,0x1199,0x119f,0x11a6,0x11ac,0x11b3,0x11b9,0x11c0,0x11c7, + 0x11ce,0x11d4,0x11db,0x11e2,0x11e9,0x11f0,0x11f8,0x11ff,0x1206,0x120d,0x1215, + 0x121c,0x1223,0x122b,0x1233,0x123a,0x1242,0x124a,0x1251,0x1259,0x1261,0x1269, + 0x1271,0x127a,0x1282,0x128a,0x1293,0x129b,0x12a4,0x12ac,0x12b5,0x12be,0x12c7, + 0x12d0,0x12d9,0x12e2,0x12eb,0x12f4,0x12fe,0x1307 +}; + + +/* 32.32 unsigned fixed format */ +/* This is a table of exponent values for an IEEE SP float. Theres never anything less then about index 115 + * making the size of this table fairly ridiculous. + */ + + +const fixed64 lsp_pow_e_table[] ICONST_ATTR_WMA_XL_IRAM = +{ + 0xb504f30000000000LL, 0x9837f00000000000LL, 0x8000000000000000LL, 0x6ba27e8000000000LL, 0x5a82798000000000LL, + 0x4c1bf80000000000LL, 0x4000000000000000LL, 0x35d13f4000000000LL, 0x2d413cc000000000LL, 0x260dfc0000000000LL, + 0x2000000000000000LL, 0x1ae89fa000000000LL, 0x16a09e6000000000LL, 0x1306fe0000000000LL, 0x1000000000000000LL, + 0xd744fd000000000LL, 0xb504f3000000000LL, 0x9837f0000000000LL, 0x800000000000000LL, 0x6ba27e800000000LL, + 0x5a8279800000000LL, 0x4c1bf8000000000LL, 0x400000000000000LL, 0x35d13f400000000LL, 0x2d413cc00000000LL, + 0x260dfc000000000LL, 0x200000000000000LL, 0x1ae89fa00000000LL, 0x16a09e600000000LL, 0x1306fe000000000LL, + 0x100000000000000LL, 0xd744fd00000000LL, 0xb504f300000000LL, 0x9837f000000000LL, 0x80000000000000LL, + 0x6ba27e80000000LL, 0x5a827980000000LL, 0x4c1bf800000000LL, 0x40000000000000LL, 0x35d13f40000000LL, + 0x2d413cc0000000LL, 0x260dfc00000000LL, 0x20000000000000LL, 0x1ae89fa0000000LL, 0x16a09e60000000LL, + 0x1306fe00000000LL, 0x10000000000000LL, 0xd744fd0000000LL, 0xb504f30000000LL, 0x9837f00000000LL, + 0x8000000000000LL, 0x6ba27e8000000LL, 0x5a82798000000LL, 0x4c1bf80000000LL, 0x4000000000000LL, + 0x35d13f4000000LL, 0x2d413cc000000LL, 0x260dfc0000000LL, 0x2000000000000LL, 0x1ae89fa000000LL, + 0x16a09e6000000LL, 0x1306fe0000000LL, 0x1000000000000LL, 0xd744fd000000LL, 0xb504f3000000LL, + 0x9837f0000000LL, 0x800000000000LL, 0x6ba27e800000LL, 0x5a8279800000LL, 0x4c1bf8000000LL, + 0x400000000000LL, 0x35d13f400000LL, 0x2d413cc00000LL, 0x260dfc000000LL, 0x200000000000LL, + 0x1ae89fa00000LL, 0x16a09e600000LL, 0x1306fe000000LL, 0x100000000000LL, 0xd744fd00000LL, + 0xb504f300000LL, 0x9837f000000LL, 0x80000000000LL, 0x6ba27e80000LL, 0x5a827980000LL, + 0x4c1bf800000LL, 0x40000000000LL, 0x35d13f40000LL, 0x2d413cc0000LL, 0x260dfc00000LL, + 0x20000000000LL, 0x1ae89fa0000LL, 0x16a09e60000LL, 0x1306fe00000LL, 0x10000000000LL, + 0xd744fd0000LL, 0xb504f30000LL, 0x9837f00000LL, 0x8000000000LL, 0x6ba27e8000LL, + 0x5a82798000LL, 0x4c1bf80000LL, 0x4000000000LL, 0x35d13f4000LL, 0x2d413cc000LL, + 0x260dfc0000LL, 0x2000000000LL, 0x1ae89fa000LL, 0x16a09e6000LL, 0x1306fe0000LL, + 0x1000000000LL, 0xd744fd000LL, 0xb504f3000LL, 0x9837f0000LL, 0x800000000LL, + 0x6ba27e800LL, 0x5a8279800LL, 0x4c1bf8000LL, 0x400000000LL, 0x35d13f400LL, + 0x2d413cc00LL, 0x260dfc000LL, 0x200000000LL, 0x1ae89fa00LL, 0x16a09e600LL, + 0x1306fe000LL, 0x100000000LL, 0xd744fd00LL, 0xb504f300LL, 0x9837f000LL, + 0x80000000LL, 0x6ba27e80LL, 0x5a827980LL, 0x4c1bf800LL, 0x40000000LL, + 0x35d13f40LL, 0x2d413cc0LL, 0x260dfc00LL, 0x20000000LL, 0x1ae89fa0LL, + 0x16a09e60LL, 0x1306fe00LL, 0x10000000LL, 0xd744fd0LL, 0xb504f30LL, + 0x9837f00LL, 0x8000000LL, 0x6ba27e8LL, 0x5a82798LL, 0x4c1bf80LL, + 0x4000000LL, 0x35d13f4LL, 0x2d413ccLL, 0x260dfc0LL, 0x2000000LL, + 0x1ae89faLL, 0x16a09e6LL, 0x1306fe0LL, 0x1000000LL, 0xd744fdLL, + 0xb504f3LL, 0x9837f0LL, 0x800000LL, 0x6ba27eLL, 0x5a8279LL, + 0x4c1bf8LL, 0x400000LL, 0x35d13fLL, 0x2d413cLL, 0x260dfcLL, + 0x200000LL, 0x1ae89fLL, 0x16a09eLL, 0x1306feLL, 0x100000LL, + 0xd744fLL, 0xb504fLL, 0x9837fLL, 0x80000LL, 0x6ba27LL, + 0x5a827LL, 0x4c1bfLL, 0x40000LL, 0x35d13LL, 0x2d413LL, + 0x260dfLL, 0x20000LL, 0x1ae89LL, 0x16a09LL, 0x1306fLL, + 0x10000LL, 0xd744LL, 0xb504LL, 0x9837LL, 0x8000LL, + 0x6ba2LL, 0x5a82LL, 0x4c1bLL, 0x4000LL, 0x35d1LL, + 0x2d41LL, 0x260dLL, 0x2000LL, 0x1ae8LL, 0x16a0LL, + 0x1306LL, 0x1000LL, 0xd74LL, 0xb50LL, 0x983LL, + 0x800LL, 0x6baLL, 0x5a8LL, 0x4c1LL, 0x400LL, + 0x35dLL, 0x2d4LL, 0x260LL, 0x200LL, 0x1aeLL, + 0x16aLL, 0x130LL, 0x100LL, 0xd7LL, 0xb5LL, + 0x98LL, 0x80LL, 0x6bLL, 0x5aLL, 0x4cLL, + 0x40LL, 0x35LL, 0x2dLL, 0x26LL, 0x20LL, + 0x1aLL, 0x16LL, 0x13LL, 0x10LL, 0xdLL, + 0xbLL, 0x9LL, 0x8LL, 0x6LL, 0x5LL, + 0x4LL, 0x4LL, 0x3LL, 0x2LL, 0x2LL, + 0x2LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL, + 0x0LL +}; + +/* table of exp noise values multiplied by 16 in order to reduce rounding error, + * note that that first value (0x5) is used as a magic number in the init code*/ +fixed32 noisetable_exp[] = +{ + 0x5, 0xfffffa2e, 0xc2c, 0xb47, 0xffffaebe, 0xfffffa63, 0xfffff7ff, 0x16bd, + 0xffffe704, 0xffffe34e, 0x71ee, 0x396e, 0xffff8bfd, 0x3b4, 0x562f, 0xffffc362, + 0x5327, 0xffffae19, 0x6cb4, 0x26b0, 0x87c4, 0x21dc, 0x8017, 0x1db0, + 0xffffe49e, 0xffffb162, 0xffffc808, 0xffffafea, 0xfffffe80, 0xfffffeb8, 0xffff8b6e, 0xffffc7a1, + 0x3f46, 0x5e8, 0x374f, 0xffff8fba, 0x87fd, 0x21e7, 0xffff9198, 0x78a0, + 0x7f7c, 0x864f, 0xffffca94, 0x42a7, 0xfffffcd6, 0xffffb916, 0x247a, 0x5679, + 0x8d9f, 0xffffb350, 0xffff9592, 0xffffcf73, 0x552d, 0xffffeb8c, 0x8622, 0xffff8091, + 0x238, 0x3ee8, 0x5c2f, 0x6e25, 0xffffe5cb, 0x86a1, 0xffffa8ca, 0xfe2, + 0x5dac, 0x2da2, 0x5ad1, 0xffffa94f, 0x729, 0xfffffdc0, 0xffff825c, 0x8bcd, + 0xffff7d05, 0xffff7d9e, 0xffffb5b6, 0x58a3, 0xffff8a3f, 0xffffd9c0, 0xffff8142, 0x596f, + 0x78aa, 0x2694, 0x78f5, 0xffff8a84, 0x43b3, 0x498a, 0xffffdfe5, 0xffffbba9, + 0xffff7228, 0xffff72c9, 0xfffff174, 0xffff9a76, 0x64d5, 0x221c, 0x88dd, 0xffffd319, + 0xfffffe14, 0xfffff99f, 0xffff8ba4, 0x6e34, 0x6cc, 0x3208, 0xfffffb14, 0x6670, + 0xffffd5ff, 0xffffa502, 0x641d, 0xffff75b6, 0xec2, 0xffffedf2, 0xffffb925, 0xffffe271, + 0xffffb727, 0xffff7450, 0xfffff421, 0x89e7, 0xfffff635, 0xffffa841, 0xffffda00, 0xffffc94e, + 0xef9, 0x28cc, 0xffffd477, 0xffff82b9, 0x2a7, 0xffff7540, 0x24c2, 0x4349, + 0xffffdf34, 0xdf7, 0x323d, 0xffffbce7, 0x29c5, 0x4700, 0x10b0, 0x1eb6, + 0x1172, 0x84be, 0xffffcee4, 0xffffe7bd, 0x1166, 0xffff7df0, 0xffffe115, 0x2383, + 0x23a0, 0x784a, 0x6f8e, 0xffff9043, 0x2b66, 0xffffc79e, 0xffff8966, 0xffffbfac, + 0x5fb1, 0xffffb183, 0x3602, 0x3d19, 0xffff7df4, 0x3ffe, 0xffffc919, 0x5ac7, + 0xffffa3e8, 0xfffff2ea, 0x47b9, 0xffffe344, 0x12f0, 0xffffc4e8, 0xfffff3fc, 0xffffcacd, + 0xffffd23b, 0x893a, 0x5e82, 0xffff8d36, 0x50e0, 0x49a6, 0x29dd, 0x16fa, + 0x451d, 0x8315, 0xffffe455, 0x749, 0x8624, 0x2fe5, 0x3ab5, 0xffffb4f1, + 0x72d, 0xffffccdf, 0x2b05, 0xffffa816, 0xffff9570, 0xffffd2e7, 0xffffa6ac, 0x2fc2, + 0xae4, 0x4c93, 0xfffffce1, 0xffffdb9f, 0x8102, 0x6bb1, 0xffffd5bf, 0xffff80e0, + 0xffffd70e, 0x568f, 0xc12, 0xffff9823, 0x700c, 0xffffa1aa, 0xffffa86c, 0xffffd303, + 0xffffbe7a, 0x38c9, 0xffff9f18, 0xffffcd7a, 0xffff8d75, 0x6955, 0xffffe70a, 0xffffbf49, + 0xffffc423, 0x31f, 0xffffe44a, 0x118a, 0xffffebfa, 0xffffedec, 0xffffee42, 0xffffd865, + 0xffff9b30, 0xffff8759, 0xffff827c, 0xffffbc26, 0xfffffb02, 0xffff8bee, 0xffffe6c2, 0x72f3, + 0xffffc2c9, 0xffff74ff, 0x2434, 0x1eb4, 0x11c9, 0x61c1, 0xffffa964, 0x89a3, + 0x6a43, 0x3d7f, 0xffffd09f, 0x14d8, 0x37bc, 0xfffffc31, 0xffffdb03, 0xfffff4e1, + 0x5547, 0xffffdc87, 0xffff929a, 0x73cc, 0x246f, 0x194e, 0xffffb4ce, 0x86b5, + 0x2f57, 0x7f05, 0x252b, 0xffff9b05, 0x5b7a, 0x164, 0x57cf, 0x7f86, + 0x5421, 0xffffa478, 0xffffbbda, 0x1b3c, 0xfffff4cb, 0xffffda7e, 0x5d8e, 0x1957, + 0xffffb3a7, 0x1979, 0xffff8ddd, 0xffffd7b9, 0xfffff028, 0xffff8c90, 0x476a, 0x6be6, + 0x419e, 0xfffffd2d, 0x8294, 0xffffc931, 0xffffe1ab, 0xffffdd4f, 0x46f0, 0x1930, + 0x4e5e, 0x8429, 0xffffde0a, 0xffff8e69, 0x2972, 0x387f, 0x3dd8, 0xffffbcc6, + 0x121b, 0x6d3d, 0x1fa4, 0xffffa3ea, 0xffffbbef, 0xffffcbd2, 0xffffbe04, 0xffffb424, + 0xffff7533, 0x70cd, 0x2370, 0x4822, 0xffff756e, 0xffffbe8c, 0x4131, 0x1ead, + 0x47de, 0xffffed53, 0xffff917e, 0x5f93, 0xffffe264, 0xffffde05, 0xffff9dc3, 0xffffc1d9, + 0xffff9b25, 0x3ade, 0xfffff9b7, 0xffffac80, 0x239e, 0xffffb980, 0xffffc9a4, 0x788c, + 0xffffbb6d, 0x3bb7, 0x6483, 0xffffeac0, 0x25ea, 0xffffbdfc, 0x333d, 0x8c0d, + 0x6d9a, 0xffffafe8, 0xffff8a74, 0x6067, 0xffff8642, 0x1a64, 0xfffff921, 0x3f3b, + 0xae4, 0x5112, 0x43a4, 0x1573, 0xffffc977, 0xffffa3b4, 0x21be, 0xffff96df, + 0xfffff035, 0x473b, 0xffff8d26, 0xb75, 0xffffecdc, 0x4455, 0x47d5, 0xffff7581, + 0xeca, 0xffffb3fe, 0xffff9f6a, 0xffffea15, 0xffffb9c3, 0x5516, 0xffffb654, 0x7f91, + 0x80b, 0xffff96b7, 0x2b60, 0x36b7, 0xffffc581, 0x285b, 0xffffa002, 0xffffc7e5, + 0x4965, 0xffff94d4, 0xffff764b, 0x1cd2, 0x5599, 0xffffd272, 0xffffcbfb, 0xffffae6d, + 0xffffd496, 0x3183, 0xffffe4f5, 0xffffa59f, 0x43df, 0x4569, 0xffffb185, 0x1d56, + 0xffff933a, 0xffff7a2c, 0x38d0, 0xffffb815, 0x5203, 0xfffffd89, 0xffff93ea, 0xffffa4dd, + 0x1f13, 0xffffad7d, 0xffffff4f, 0xffffe13c, 0xffffd60a, 0x8c88, 0x8276, 0xffffeaaf, + 0xffff8a66, 0xffff7888, 0xffff91e9, 0x8bdf, 0xdcf, 0xfffff282, 0xffffe91b, 0x1eb1, + 0x6fc, 0xffff81f6, 0x1617, 0xffffad02, 0xffffafaf, 0x60d5, 0x6f2b, 0x4e8b, + 0x2347, 0x3257, 0x29cf, 0x86c4, 0x75b3, 0x7745, 0xfffffcc7, 0x49cd, + 0x558f, 0xffff7c7a, 0x52e1, 0xffff7626, 0x7690, 0xffffb357, 0xffff7dbf, 0xffffa1ee, + 0xffffa874, 0xffff846f, 0xffffab72, 0x5cef, 0xffffb0cf, 0xffff8c24, 0xffff8e10, 0xffffe200, + 0x2a45, 0xfffff883, 0x5155, 0x37c9, 0xad6, 0x1ed9, 0x79e2, 0x1f4c, + 0x45f8, 0x48ec, 0xffffa331, 0x34a1, 0xffffc7b0, 0x2eb5, 0x5dc, 0x4cdd, + 0x4e5c, 0xffffa7c7, 0x3b08, 0x2776, 0x2e1a, 0x788d, 0x162b, 0x1fa7, + 0x466c, 0x5ca2, 0xfffff3ac, 0xffffa62f, 0xfffffd4c, 0x5f48, 0x779, 0x2a5e, + 0xffffe14e, 0x196, 0xffffaba1, 0x404c, 0xffffdc5b, 0x238f, 0x274, 0xffffa5c6, + 0xffff9e2b, 0x6201, 0xfffff195, 0xfffff3b0, 0x2285, 0xffffc7f0, 0xffffdff4, 0xffffc43d, + 0xffffac57, 0xffffb7a6, 0xffffe88c, 0xffffd3ac, 0xffffbb5c, 0x2cbd, 0x44d6, 0x5e30, + 0xffffeb53, 0x6d8b, 0xffff7f8b, 0xffff99a3, 0xffff7a4e, 0xffffbc82, 0x6a49, 0xfffff220, + 0xffffeaca, 0x4146, 0x8d72, 0xffffdcb7, 0xffffe2f3, 0xfffff736, 0x557f, 0x13fd, + 0x66a, 0x5d9, 0x29ee, 0xffffda1e, 0xd38, 0xffffe70f, 0xffffbbd7, 0xffffe1ee, + 0x4a0d, 0x502e, 0xffff8c37, 0xffffaccc, 0xffffdd0b, 0xffff7401, 0x3a89, 0x73b4, + 0x71b7, 0x5b43, 0xffff9baf, 0x4d76, 0x25f, 0x7f97, 0xffffcb71, 0x6b4c, + 0xffffe999, 0x3fd5, 0xffffd40b, 0x3f0d, 0xffffc17b, 0x3de9, 0x87f7, 0x6446, + 0x5be, 0xffffd88a, 0x7d05, 0xfffffe16, 0x467e, 0x1454, 0xffffca4e, 0xffffa047, + 0xffff92ac, 0xffffddc9, 0x72a9, 0xffffc902, 0x3605, 0xe47, 0x280c, 0x7662, + 0x609d, 0xffffae0a, 0x78e0, 0xffffa02a, 0x1c87, 0xfffff91b, 0xffff7792, 0xffff745e, + 0xffff8097, 0xffff8583, 0xffffe7e4, 0x61a5, 0x36a8, 0x7fe7, 0xffffaecc, 0xffff90f7, + 0x5ad9, 0x7e2f, 0xffffffca, 0x75c7, 0x7134, 0xffffd7fe, 0x3c22, 0x314c, + 0x7c97, 0x2068, 0xffff7926, 0x3e7c, 0x6926, 0x67f9, 0x3e28, 0x7c65, + 0x76b9, 0x25cf, 0x1039, 0xffffdf97, 0x8779, 0xffffe8fd, 0xffff9f74, 0x770a, + 0x8a50, 0xffffd241, 0xffffddee, 0x5aab, 0xffffc97f, 0x4572, 0x3276, 0xffffe7ec, + 0xffff8cc2, 0x6331, 0xfffffedf, 0x3b86, 0x3038, 0xffffd628, 0x2645, 0xffff737c, + 0x72fe, 0xffff8474, 0x23fb, 0x78f, 0x194c, 0x95a, 0xffff91d0, 0xffff8014, + 0x56e9, 0x2efe, 0xffffae5b, 0x614, 0xffffca3d, 0xffffd77e, 0x73e1, 0x35f7, + 0x71f3, 0xffff9279, 0xffffe6f3, 0x404b, 0x548d, 0x32a3, 0xc11, 0x637a, + 0xffff7605, 0x2ba8, 0xffff8f35, 0x8157, 0x423f, 0xffff9711, 0xffffb980, 0xffffb4b1, + 0x3494, 0xffffc9dd, 0x6c43, 0x563f, 0x52c, 0xffff9680, 0x8b7a, 0xffffcf49, + 0xffffa40b, 0x6daf, 0xffff840e, 0x29cd, 0xffffbf5c, 0x68b7, 0xffffedf3, 0xffffe329, + 0xfffff634, 0x8619, 0x33bc, 0x28b4, 0x5ed8, 0xffffcfbb, 0x883a, 0xfffffdf6, + 0xffffb980, 0x7bac, 0xfffffd6d, 0x418f, 0x4a25, 0xffffbed3, 0x4272, 0xffffef42, + 0x800f, 0x78e3, 0x82c8, 0x24e1, 0xffffcfa3, 0xffffb385, 0x86b, 0x645b, + 0x38aa, 0x6a22, 0xffffc21b, 0x60f0, 0x9b6, 0x912, 0x7621, 0xffff94cc, + 0xffffd5c9, 0xfffffdb5, 0xffffd93a, 0x2a11, 0xffff8b3d, 0xffffc0d2, 0xffffa00f, 0xffffe965, + 0xfffffa0f, 0xffffbfa9, 0x5e78, 0xffff925b, 0xffffeac8, 0xffffd5af, 0xffffba37, 0x395a, + 0xffffdc75, 0xfffffdf2, 0xffff7c7b, 0xffff89a3, 0x3766, 0xffffe8a9, 0x7118, 0x399e, + 0xffff7ff5, 0xffffac9a, 0xffff7d74, 0xffffa5d2, 0x4c27, 0x787f, 0x586, 0x7ce4, + 0xffffb38e, 0xffffb93d, 0x240d, 0x5a90, 0xffffb448, 0xffff8e29, 0xffffbc06, 0x3bf3, + 0xffffda90, 0xffffb78d, 0xffffc747, 0xffffa5c0, 0xffffe2dd, 0x7fbd, 0x8946, 0xffff8d50, + 0x2451, 0x18f9, 0xffffc1d4, 0xffffb689, 0xffffc37b, 0xffffbe2f, 0xffffbe9e, 0x8117, + 0x7050, 0xfffff504, 0x2b9, 0x464f, 0x298d, 0x2367, 0xffffe8c3, 0x79f1, + 0x4e38, 0x5cc8, 0x2928, 0xffffb486, 0x7cd6, 0xffffdbd9, 0xfffff110, 0xffffeff7, + 0x19b8, 0xffffeb99, 0xffff847c, 0xffff7612, 0xffffd542, 0x2966, 0xffff8ce2, 0x38fe, + 0xffffdeaa, 0x5238, 0x67c4, 0xffffa5e7, 0x4e6d, 0xffffd82e, 0x5973, 0x351b, + 0x74e8, 0xffffafcd, 0x66dd, 0x20e4, 0x609d, 0xffffade3, 0x509f, 0xffffa21f, + 0x2cce, 0x54c2, 0x1953, 0x85ce, 0x6bee, 0x3222, 0x6ff6, 0x3773, + 0x5a64, 0xffffe40f, 0xffffc6df, 0x3556, 0x80a9, 0xffff76c5, 0x495b, 0x1ae4, + 0xffffca33, 0x31f2, 0x833e, 0x89c3, 0x5f43, 0xffffbee7, 0x3ab2, 0x87af, + 0x4c74, 0xffff810b, 0xffffbed0, 0x6795, 0xffff785c, 0xffffbc0b, 0x520e, 0x4348, + 0xe03, 0x4541, 0x2557, 0xffff9110, 0x4044, 0x1947, 0x4dab, 0xcbe, + 0x3f72, 0x4507, 0xffffa362, 0xffffc20b, 0x6c1b, 0x27c7, 0xffff9bf2, 0x6506, + 0xffff89cc, 0x5c3e, 0x4509, 0x409a, 0xffff98db, 0x1674, 0xffff9324, 0x7328, + 0xffff99cf, 0xcd8, 0x730a, 0x14b9, 0x672d, 0xffffd620, 0x1dd8, 0x3bec, + 0xffff94b6, 0xffffb689, 0x7dfd, 0x3ffd, 0xffff9cb6, 0x3560, 0xffffbaf8, 0xffff8604, + 0x8795, 0xffff7aec, 0x66a5, 0x6a0b, 0x564b, 0xffff8d00, 0xffffed20, 0x11b8, + 0xffffdc27, 0x595d, 0xffffddf0, 0xfffffc70, 0xffffd5bf, 0x6714, 0xffffaf69, 0xdb2, + 0x3786, 0xffffbf9d, 0x7ca7, 0x5a53, 0xffff7c6a, 0xffff8465, 0xffffe4c6, 0xffffa238, + 0xffff7f9b, 0x6887, 0x3838, 0x7115, 0x5bce, 0xeae, 0x47c, 0xffffd54a, + 0xffffb9d5, 0x6183, 0x9c3, 0xbd5, 0xffffe217, 0x8237, 0x51d7, 0x52fe, + 0x6424, 0xffffb192, 0xffff7ebb, 0xffffd373, 0xffff9cf7, 0x390b, 0xffffa473, 0x8953, + 0xffff90c9, 0x594a, 0xc6e, 0x32ba, 0xffffae73, 0x86c7, 0xffffd7a0, 0xffffa82e, + 0x8d66, 0xffffabcf, 0xffff84d0, 0x3a84, 0xffffe8bd, 0x4948, 0x3f2a, 0xfffff4e5, + 0xffffb0bd, 0x4961, 0xffffd95b, 0xffffd96c, 0xffffce34, 0x57ff, 0xffffdf08, 0x2330, + 0xffffa8c7, 0x24cb, 0x740a, 0xffffdbcf, 0xffffad36, 0x306f, 0xffffa30b, 0xffffc488, + 0xffff8022, 0x464a, 0x6f00, 0xffffb419, 0xffff8450, 0x2ddb, 0x2731, 0x63fd, + 0x2946, 0x5c28, 0xffffb064, 0xffffb277, 0x1e0f, 0x6d71, 0xffff7ff3, 0xfffffb02, + 0xf2a, 0xffffd69c, 0x638, 0xffffe8ff, 0xffffbd7e, 0xffffb26f, 0xffffe153, 0xffff9879, + 0xffff849c, 0x1f73, 0xffff9b21, 0x2bb1, 0xffffa95b, 0xffffd582, 0xffffdbfa, 0xd2c, + 0xffffa86f, 0x2ab3, 0xffff9d78, 0x1074, 0xffffbcb5, 0x3990, 0xffffe869, 0xffffb422, + 0x2dc8, 0xffffca25, 0xffffcfe8, 0xaf1, 0xffff82c8, 0x36a, 0x2f4e, 0xfffffdcd, + 0x77fa, 0xffffad4f, 0xffffa54a, 0x50b9, 0x6eab, 0x5178, 0x8982, 0xffffe4dd, + 0xffff9a82, 0x45a2, 0x784e, 0xffffbd6e, 0x5019, 0xffffcc5c, 0x8009, 0x5d96, + 0xffffac8d, 0xffff8ec9, 0x4c, 0x4222, 0xfffffa7f, 0x3227, 0x67ea, 0xffffe679, + 0x3dc8, 0xffffb5b5, 0x1424, 0x3e4a, 0xfffff175, 0xffffaf4b, 0x4657, 0x1374, + 0xffff7233, 0x7190, 0x332, 0xaf0, 0x68c0, 0xffff85ad, 0xffffd0af, 0x2b1, + 0xffff8d54, 0x1f99, 0xffffe8d5, 0xffffc30b, 0x2877, 0xffff9d40, 0xffff8852, 0xffffb01a, + 0x4b32, 0x3279, 0xffff9099, 0x5f4f, 0xffffe08c, 0xffff9fe0, 0xffff9ecc, 0xfffff557, + 0xfffffc25, 0xffffa719, 0xffff920a, 0x62ac, 0xfffff11d, 0x152d, 0xfffff5d6, 0x5223, + 0xfffff438, 0xffff73f3, 0x34e1, 0x49a9, 0x6a73, 0x2ad3, 0x1f51, 0x824, + 0x1bc9, 0x5170, 0x552d, 0x52b5, 0xfffff12a, 0xffffec44, 0x7924, 0x5294, + 0xb63, 0x822f, 0xffff9afd, 0x7e29, 0x2d91, 0x42ad, 0xfffff589, 0xfffff6e9, + 0x2792, 0x4269, 0xffff9639, 0xffff726f, 0x4074, 0xffffa179, 0x8a6b, 0xffffb431, + 0x850f, 0xffff903f, 0x6b22, 0x738, 0x16a0, 0xffff917f, 0x8a5a, 0xb61, + 0xffffcce6, 0x6369, 0xffffb671, 0x66c0, 0x68e6, 0x41aa, 0x2fc3, 0x2382, + 0xffffabd5, 0x62c, 0x5041, 0xffff9903, 0x846b, 0x86f6, 0x8111, 0x15c, + 0x62ed, 0xfffff411, 0x517c, 0xffffbb6d, 0x8256, 0x141e, 0xfffffd31, 0x8777, + 0xffffabbe, 0x4eb5, 0xffffbae4, 0x75a2, 0x2bfc, 0xffff799f, 0x26bd, 0x2296, + 0x7b36, 0xffffddc6, 0x7517, 0x155a, 0x16b1, 0x25b4, 0xfffff8ce, 0x54e9, + 0xffffeb3c, 0x7e5e, 0xffffa981, 0xfffffdbb, 0x87f7, 0xfffff4fe, 0x5657, 0x2add, + 0x5113, 0x7bff, 0xffffbcec, 0x37fb, 0x59a3, 0xffffd989, 0xffff9ac8, 0xffff8e9e, + 0x5ea9, 0x1bbf, 0x8ca1, 0xffff7365, 0x4d65, 0x874c, 0x4119, 0x63ee, + 0xffff91ea, 0x8074, 0x8a3c, 0xffff74b0, 0xffffb940, 0x3c7a, 0x50f, 0xffffe11e, + 0x6c76, 0x5731, 0xf34, 0xffff8ace, 0xffffdb12, 0x4cb2, 0xffffa624, 0x8999, + 0xffff94e3, 0x469e, 0x4101, 0xffffe271, 0x850d, 0xffff95cf, 0xffff93fa, 0x3357, + 0x8fe, 0xffff9b75, 0xffffbd9b, 0x6a34, 0x1db7, 0xb19, 0xffffee5f, 0xffffc9c1, + 0x763, 0xffff9c09, 0x26a7, 0xffffb6c5, 0xf48, 0xe3e, 0x854f, 0xfffffa24, + 0xffffb689, 0x34bc, 0xffff7a74, 0xffff7240, 0x5849, 0xfffffa7f, 0xffffbd17, 0x17e4, + 0x8e6, 0xfffff805, 0xffffd6d6, 0xffffecd0, 0xffff8b9c, 0xffffed0b, 0x198e, 0x5422, + 0x8549, 0x8dc7, 0xffffb649, 0x1cb6, 0x5ba9, 0xffffc4f6, 0x7b31, 0xffff8611, + 0x62a9, 0xc49, 0xffff7b22, 0xffffd5f0, 0xffff9fce, 0x3f16, 0xffff72a8, 0xffff9a53, + 0xffffa401, 0xffff9f41, 0x53b8, 0xffffca3e, 0x86a2, 0xffffa27c, 0xffffb022, 0x7c4, + 0x3425, 0x344e, 0xffffcb0a, 0x6d47, 0x63b3, 0x677c, 0x4077, 0x72b, + 0x5a90, 0x4348, 0xffff8b9d, 0xffffbcef, 0xffff8e3f, 0x58fa, 0xffffe0a8, 0xffffaf0c, + 0x4698, 0x3da0, 0xffffd44c, 0xffffe85d, 0x455f, 0x5746, 0x5168, 0xfffff3ad, + 0xffffd7bb, 0x56b0, 0xffff7845, 0xffff8d1d, 0x8fa, 0xffffe8c1, 0xffffb00f, 0x6f65, + 0xffffb97c, 0x83b9, 0x4e67, 0x5e2a, 0x787f, 0x8d66, 0x397e, 0x7e75, + 0x4789, 0x7be7, 0x8a38, 0x7ce2, 0xffff9005, 0x3391, 0x873d, 0x5ade, + 0x71e5, 0xffffb84e, 0x4718, 0x438, 0x8700, 0xffffdf0d, 0xfffffed4, 0x88, + 0xfffff494, 0xffffab9a, 0x6c68, 0xffffece3, 0xffff9e05, 0x5590, 0xffffeda6, 0x491d, + 0x7376, 0x6e88, 0x75df, 0xffffd5a8, 0x88b7, 0xffffe707, 0x356d, 0xffff9881, + 0xffffef0f, 0xffffa40f, 0xffff8f5e, 0x3b0f, 0x3da, 0xfffff8d1, 0x6809, 0x83dd, + 0x876d, 0x3c44, 0xffffe878, 0x3faf, 0x78f, 0xffff7a85, 0xffffc78b, 0xffffd711, + 0xffff9d6b, 0x79c8, 0xd65, 0xffffe3e3, 0x478, 0x7129, 0xffff7dda, 0xffffab18, + 0xffffcd44, 0xffff7cfc, 0x723a, 0x5c3, 0x3737, 0x3451, 0x650a, 0xffffa327, + 0xfd9, 0xffff7bae, 0x1f5b, 0x2978, 0x8c99, 0x4cd4, 0xffffb3d6, 0x4036, + 0x2a0e, 0x35ea, 0x50b, 0xffff9518, 0xffff85c1, 0xffffcdc6, 0xffffdc56, 0xffff8d75, + 0xffff90f3, 0x11cb, 0xffffa7dd, 0xffff884c, 0xffffc35a, 0xffffc3cf, 0xffffad4a, 0xffffc75a, + 0xffffa170, 0x8adb, 0x7441, 0xffffe8d1, 0x42b4, 0xffffe1ad, 0xffffdd4a, 0xffff98bf, + 0x4cc2, 0xffff8b07, 0x334c, 0x5e4d, 0xffffb14a, 0xffff9c04, 0xffffb744, 0xffffa616, + 0x187d, 0x495a, 0xffffb1c3, 0x524d, 0xffffc04b, 0x6110, 0x6dff, 0x55b8, + 0x8de1, 0x3394, 0x886f, 0xc21, 0xffff995f, 0xd71, 0xffff90e8, 0xffff983a, + 0xffff92d8, 0xffffcce2, 0xffff90e7, 0xffff94ff, 0x4e0b, 0xffff9334, 0xffffeacb, 0xffff8f75, + 0x48aa, 0x7631, 0xfffffbf9, 0xffffd3e0, 0x6850, 0xffffa651, 0xffff8745, 0xffffe780, + 0xfffff596, 0xfffffed5, 0x3b41, 0x55cd, 0x5a08, 0xffffa0cf, 0xffff75a0, 0xe58, + 0xffffff64, 0x6763, 0xffff8c5f, 0x69b7, 0x453b, 0xffffba78, 0x7554, 0x4fba, + 0x6031, 0x1ed6, 0x30a2, 0x3c52, 0xfffffc1a, 0xffffecfe, 0xffffa280, 0xffff9d76, + 0xffffa66c, 0xffff8dc0, 0xffffaa2b, 0xffffbc38, 0x1cd9, 0xfffff3fa, 0x7078, 0xfffffecb, + 0x800e, 0xfffffa73, 0xffff9a9f, 0xffffb5c5, 0xffffda01, 0x68c8, 0x7787, 0xffffe959, + 0xffffc008, 0x357a, 0x37fb, 0xffff9b65, 0x4df5, 0x8ad5, 0x53aa, 0xffffcc5a, + 0xffff74a9, 0xffffed23, 0x4c8e, 0xffffbd47, 0xb95, 0x774c, 0x5109, 0xffffd8ef, + 0x4095, 0xffffad7a, 0x8a82, 0x2d80, 0xffff8d9a, 0xd43, 0x6bf9, 0x223, + 0x3eed, 0xffffc475, 0x3854, 0xffffa438, 0x1ac0, 0x990, 0x50f8, 0xfffffce9, + 0xffff72ab, 0x41f2, 0x845e, 0xffffef06, 0x7241, 0xffffcf1a, 0x7888, 0x5bf5, + 0xffffc6a5, 0xffffdbe1, 0x1573, 0x65ba, 0x1f5a, 0xffff9e88, 0xffffef80, 0x580c, + 0xffff8254, 0x5da1, 0xffff7a42, 0x220e, 0xffff7947, 0xffff7a6b, 0xffffaa90, 0x7b4, + 0xfffff0e5, 0xf4, 0xd7c, 0x3754, 0xffffa34c, 0x4314, 0x4e93, 0x5f33, + 0xffffd600, 0x150b, 0xffff867a, 0x5eee, 0x54fd, 0x630d, 0xfffff8e2, 0xffffdd08, + 0xffffdd29, 0xffff7350, 0xffffbc1a, 0x1429, 0xffffda45, 0x3e79, 0xffffca86, 0x1523, + 0x620c, 0xa9e, 0xfffffdb9, 0xffffb00f, 0xffff82bf, 0xfffffb63, 0xffff78de, 0x25ad, + 0x54ac, 0x3831, 0x66b6, 0x696e, 0x4e31, 0xffff81c0, 0xffff854a, 0xa8e, + 0x8ce6, 0x52dd, 0xffffa6c6, 0xffffe575, 0xffff9907, 0xffff9743, 0x2156, 0xffff8199, + 0x76ea, 0x7361, 0x8d23, 0xfffffa98, 0xfffffb0d, 0xffffa7b3, 0x12e3, 0x4239, + 0x4aeb, 0x7461, 0xe02, 0x987, 0x68b5, 0xfffffc95, 0x7ac, 0x7238, + 0xfffff148, 0xfffff26d, 0x58f4, 0x50b3, 0xffff869d, 0xffff8582, 0x5d94, 0x30fd, + 0x1e62, 0x83ab, 0xfffffa33, 0xffffb49d, 0x18e9, 0x4781, 0x6d8, 0x7bab, + 0x1aef, 0x2ca6, 0x81a9, 0x2f34, 0x248d, 0xffff9a23, 0xffffdd8a, 0xffffd9a2, + 0xfffffba7, 0x754, 0xffffdbe5, 0x28cc, 0xffff9659, 0x2219, 0x6bea, 0xffffe7ad, + 0xffff856e, 0xffffd3c1, 0x14ff, 0x350, 0x42f3, 0xffffd69d, 0xffffb4b5, 0xffffccd7, + 0x6500, 0x2fb6, 0xffff95b5, 0xffffe293, 0x5baa, 0xffffc45a, 0xffffda2f, 0xffff8de6, + 0xffff87ec, 0x5f0e, 0xffffca76, 0xffffac52, 0xfffff9a4, 0xffff9e0d, 0x771a, 0xd62, + 0x32f3, 0x8367, 0xffff982d, 0x240a, 0x20d, 0xfffff430, 0xffffba8d, 0xffffb810, + 0xffffcfd1, 0x8044, 0xffffcba1, 0xffff9772, 0xffffee63, 0xfffffd51, 0xfffff324, 0x101e, + 0xffffe7c7, 0xfffffb15, 0xffffc5eb, 0x8585, 0x427, 0xffffcdbf, 0xffffcc26, 0x21fb, + 0xffff7c96, 0xffff7705, 0xffffb428, 0xffffa3f8, 0x3906, 0x5787, 0xffffd8af, 0xffffd7d1, + 0xffff77d7, 0x5504, 0xffff73a1, 0x116e, 0x32d8, 0x16f2, 0x5c09, 0xfffff98c, + 0x7350, 0x6462, 0xffffada1, 0x3f1b, 0x6378, 0xffff81e0, 0x2dd3, 0xfffff52a, + 0x8142, 0x89e0, 0xffff9fc6, 0xffff7bf1, 0xffffd116, 0xffffebf0, 0xd84, 0x1669, + 0xffff9bca, 0x5050, 0x6f8a, 0x2c50, 0x8590, 0x32fd, 0x6abf, 0x6af0, + 0xffffa4de, 0x2042, 0xffff9f0b, 0x726, 0xffffcb98, 0x12a1, 0x497b, 0xffffa677, + 0xfffff6f1, 0x2433, 0xffffebc9, 0xffffd8cd, 0x2939, 0x2438, 0xffff79b3, 0xffff9226, + 0xffff9ca1, 0x4884, 0x6fe7, 0x2f89, 0x812a, 0xffffa72e, 0xffffb33c, 0xffff815e, + 0xffff8866, 0x3b83, 0xfffff5b5, 0x3fb2, 0x8221, 0xffffd486, 0x2665, 0xffffa540, + 0x5ce5, 0x893c, 0x4b34, 0x1b5d, 0xffff8b00, 0x8b56, 0xffffb3ab, 0xfffff0d7, + 0x353f, 0x63ce, 0xffff9b0b, 0xffff9689, 0xfffffe5a, 0x50c5, 0x3f3d, 0x1917, + 0x3045, 0xffffdb17, 0x2f69, 0x7ecc, 0xffff7f93, 0xffffa392, 0x9ed, 0xffff94dc, + 0x11e, 0xffffdcb5, 0xffff934b, 0xfffff44a, 0xffffd194, 0xffffe03b, 0x5841, 0xffffd49a, + 0x26f3, 0xfffffc5a, 0x8d0e, 0x6441, 0x2fc5, 0xffffed7a, 0xffffe739, 0xffffd2ff, + 0xffffb541, 0xffff8f9e, 0x807, 0xffff8e7d, 0xffff85b9, 0xffff8fc7, 0x778a, 0x8451, + 0xffffa75f, 0xffffe5b1, 0x2aeb, 0x7fe6, 0xffffc2b3, 0x8534, 0x268a, 0x6711, + 0xffff8cf8, 0xffffd800, 0xffff7913, 0x7c1b, 0x4e76, 0xffffde5d, 0x1545, 0xfffff355, + 0xffffc1bb, 0x398c, 0xffff798a, 0xffffdc27, 0x40ed, 0xfffff8fc, 0xfffff918, 0x7ef5, + 0x5182, 0x8369, 0x47af, 0xffffd6d5, 0xffff7e09, 0xffffa12e, 0x5363, 0xffffce2c, + 0xffffdc79, 0xfffff095, 0xffff7760, 0x4905, 0xffffd192, 0xffff9ca8, 0x39dc, 0xffffd67b, + 0x680, 0xffffb5a4, 0xffffd7d7, 0xffffb5a5, 0x7fcd, 0x7305, 0xffff8e3b, 0x179d, + 0xffffebf4, 0xffffad3c, 0xffff791f, 0xffffb513, 0x7d2e, 0x361f, 0x1a0f, 0xffffd336, + 0xffff7531, 0xffff73ec, 0x8acc, 0x85bf, 0xffff8a29, 0xd3c, 0x392, 0x4482, + 0x7272, 0xffff8403, 0x7d3e, 0xfffff055, 0x6ae2, 0xffffc5b3, 0x74ac, 0x30f6, + 0xfffff4bd, 0x19ba, 0xffffc488, 0xffffeec2, 0x877, 0xa9d, 0xfc1, 0x57a0, + 0x4879, 0x175a, 0xffffa0c0, 0x533, 0x8765, 0x2d23, 0x7ae9, 0x1d9e, + 0x16b2, 0x58c4, 0xffffe64f, 0xffff79ba, 0x68cd, 0x5c30, 0xffffb8e0, 0xffffc5d1, + 0xfffff04f, 0x5fec, 0x19ca, 0xffff8c02, 0x15ab, 0x8897, 0xffffebeb, 0x70d7, + 0x1662, 0x8c83, 0x8bc8, 0x21c8, 0xffffa728, 0x6513, 0xffff92f4, 0xffffadb2, + 0x7a29, 0xffffe450, 0x2136, 0xffffc6db, 0x26e, 0x8221, 0x3097, 0x5883, + 0xffffa134, 0x8284, 0xffffa6d9, 0x1c76, 0xffff8524, 0x164e, 0xffffa415, 0xffff841e, + 0x309d, 0xffffd4e1, 0xffff99a3, 0x4e11, 0xffff90a2, 0x51bf, 0xffffec39, 0xffff9073, + 0xe4e, 0xffff7a6a, 0x26b0, 0x64e4, 0x1a95, 0xffffeed3, 0x8049, 0x67b0, + 0x23e0, 0xffffb836, 0xf72, 0x2c0f, 0xffffacff, 0xffffa183, 0x87b8, 0xffff7e3a, + 0xffffef41, 0xffff796e, 0xfffffd33, 0x4c73, 0xffffd590, 0xffffdfac, 0xfffff5fb, 0xffff9594, + 0xffffba62, 0xffffa2d2, 0x496a, 0x1501, 0xffff9a7a, 0xffffc542, 0xffff8a89, 0xffffdda6, + 0xffff7f5e, 0xffffbf34, 0xffffe1e1, 0xffffb26c, 0xffffe9c3, 0x67cc, 0xffffb506, 0x6416, + 0x454, 0x3724, 0xffff9c3d, 0x2f27, 0x45cb, 0x670f, 0xffff7969, 0xffffdc9e, + 0xffff87e1, 0x1948, 0xfffffe4e, 0x1fdd, 0xffffe119, 0x5c64, 0xffffc383, 0x1062, + 0x6828, 0x6dd8, 0x2238, 0x12d5, 0xffffd611, 0xffff8739, 0x137a, 0x52c6, + 0x441c, 0xffffc74c, 0xffffee23, 0x583a, 0xffffd369, 0x3c68, 0xffff99a0, 0xffffb914, + 0xffffbe62, 0xffffcd86, 0x1438, 0xffffe64d, 0x53da, 0x2358, 0x89f6, 0x6e04, + 0x459f, 0xffffb2a5, 0xffffdaf4, 0xfffface2, 0x6673, 0xfffff8df, 0x594d, 0xffffeedd, + 0xffffa520, 0xffff8687, 0x70b0, 0x5dba, 0xffffe645, 0x3bbc, 0xffff8028, 0xffffea28, + 0xffffc7ba, 0x36ca, 0x7c40, 0x34ce, 0xffff7a62, 0x10bf, 0x5ee1, 0xffff98ab, + 0x10be, 0x3b49, 0x8c53, 0x8386, 0xffff7a09, 0xffff7a77, 0xffff7acd, 0x2cc4, + 0xffff93aa, 0x574, 0xffffc3ed, 0x2586, 0xffffeca4, 0x750e, 0xffffb075, 0x6308, + 0x67ac, 0xffffc8a3, 0x49c1, 0xfffff006, 0x89c9, 0x4f36, 0x3909, 0xffffd5d0, + 0xffffe4c1, 0xffff7a19, 0xffff8552, 0x7a2b, 0xffff9d63, 0x88e9, 0xfffffde4, 0x190a, + 0xffff826f, 0xffffecd9, 0x1983, 0xffffe551, 0xffff92e2, 0x2c5c, 0xffffd03c, 0x4adf, + 0x6865, 0xffff7e20, 0xffffea03, 0x841d, 0x4e37, 0x3d59, 0x3171, 0x673a, + 0x1afc, 0xffffa098, 0xffffde36, 0xfffffbbd, 0x47a5, 0x65be, 0x3738, 0x2beb, + 0x3e11, 0x6cff, 0x8da8, 0x22a6, 0xffffdf4a, 0x1151, 0xffffc349, 0x3485, + 0xffffee00, 0xffff864e, 0x865, 0x5989, 0x4145, 0xffff8999, 0xffff835e, 0xffffc2ad, + 0x2f00, 0xffffdc98, 0x7dfe, 0xffffc2fe, 0x1234, 0xfffff5da, 0xffffd55c, 0x119e, + 0xffff7dc3, 0xffffb27e, 0x7aae, 0xffff7b34, 0xffffde8e, 0x797, 0xffffab7e, 0xffffe6ce, + 0x7685, 0x600f, 0x7285, 0x6045, 0xffffe2f4, 0x69e7, 0xffffdfd8, 0x14a, + 0xffffda78, 0xffffabc0, 0x89c3, 0xffffbeac, 0xc37, 0x6df4, 0xffffe0d2, 0xffffc632, + 0xffffa62e, 0xffff8d46, 0xffff78fa, 0x3003, 0xfffff74e, 0x42a9, 0xffffe8d6, 0xffff7863, + 0x6a8e, 0xffff8696, 0x1844, 0xffffa06f, 0xd36, 0xffffd8d8, 0xffffe27c, 0x387e, + 0x30fb, 0xfffff762, 0x808a, 0x2d5b, 0x6717, 0xffffff14, 0x845b, 0xffff9586, + 0x68b, 0xffffe56f, 0xffff96b9, 0x6295, 0xffffb26c, 0x2a02, 0xfffffd8b, 0x6b98, + 0xffff8ca4, 0x501a, 0x5f44, 0xffffa9ac, 0xffffa063, 0xffff9030, 0xffff80d2, 0xffffcd8c, + 0x4c8c, 0xffffc0f8, 0x397, 0x819c, 0x767c, 0x7d99, 0xfffff123, 0x1b50, + 0x2c29, 0xffffd70f, 0xffffcca8, 0xffffa017, 0xfffff2b7, 0xffff74f0, 0xffffa9ed, 0x233b, + 0x1516, 0xffffbb9f, 0xffff97bc, 0x23c4, 0xfffff299, 0x7db1, 0xa52, 0xffff9161, + 0xffff8541, 0xffff75a7, 0xe20, 0x7dd3, 0xffffcc27, 0xffff9e5e, 0xffffe9ee, 0xb6e, + 0xffffe271, 0xffffe9e6, 0x6d72, 0xfffffd38, 0xffffa167, 0x6246, 0x83b, 0xffffa571, + 0xaeb, 0xffff8759, 0xffffa37f, 0xffffea7c, 0x6061, 0x8b6c, 0xffffb904, 0xffff88ea, + 0xffffa8f7, 0xffffd266, 0xffffa1bf, 0x343a, 0x6f9c, 0xffffd56b, 0x37ef, 0xffff8566, + 0x4eb7, 0xffffd9b3, 0xffffd22e, 0x8af7, 0x1d78, 0xfffff575, 0x391e, 0x4836, + 0xffffeaf1, 0xffff89a2, 0x6ac6, 0x611f, 0x8458, 0x2af6, 0x588f, 0x8e5, + 0x8bf6, 0xffffac56, 0x35d8, 0x6e0, 0x371b, 0xffff7743, 0xffffc693, 0x146c, + 0xffff80e3, 0xffffb207, 0xffffe58c, 0xffff8e50, 0xffffb07b, 0xfffff121, 0xffff9b54, 0x5dd4, + 0x700d, 0xffffe8a8, 0xffffdc38, 0xffffe745, 0x3734, 0x1db6, 0xffff8353, 0xffff7e3b, + 0x8eb, 0x6019, 0x2c5c, 0xffff8bd0, 0x8a7f, 0x7bc1, 0xfffff710, 0x4002, + 0x3650, 0xffffce4a, 0xffff7cce, 0xb70, 0x359a, 0x3013, 0x362, 0xffffa441, + 0x5b8e, 0xfffffe99, 0xffff7813, 0x7fdf, 0xffff8fc1, 0x5912, 0xffff8122, 0xfffff92a, + 0xffff8c22, 0x46a0, 0x5d05, 0xffffc4c0, 0xffffbc37, 0xffff9f62, 0x3103, 0xfffffb57, + 0xffffdf3b, 0xffffbde0, 0xffffe2fd, 0xffffcb24, 0x7291, 0xffffc112, 0x305d, 0x60f4, + 0xffffc8ae, 0xffff7574, 0xffffe0d9, 0xe58, 0xfffffeba, 0x66e, 0xffff8463, 0x8643, + 0xffffa427, 0x405e, 0xffffa5f5, 0xffffcb8f, 0xffffb04c, 0xffff79aa, 0x1a22, 0xffff896c, + 0xffff7d81, 0x7bda, 0x6989, 0x3996, 0x870e, 0x3a69, 0x3b4a, 0xffff9e08, + 0x2c97, 0x7ebd, 0xffffbf71, 0x1973, 0xffffdf6b, 0xffffbad9, 0x196a, 0x81e8, + 0x1c4, 0x61c5, 0x76e9, 0x25c5, 0x5131, 0xffff9e6e, 0xffff9637, 0xffff7d1a, + 0x5111, 0xffffff97, 0xffff8424, 0xffffbf3b, 0xffffb4f9, 0x2eaf, 0x7b44, 0x409e, + 0xffffe706, 0x1099, 0x328c, 0x401c, 0x2e7, 0x5b34, 0xffffd2f2, 0xffff9853, + 0xffff7804, 0xfffff344, 0xfffff283, 0x8ce9, 0xffff8fc2, 0xfffff155, 0xffffe2fe, 0xffff9d35, + 0x846f, 0xffffe3cf, 0x53f2, 0x67e4, 0xffffb405, 0xffff9c2a, 0x69a7, 0xfffff279, + 0xffffcd7b, 0xffffe05c, 0x5f40, 0x7110, 0x5c7d, 0xffffc8b4, 0xffffb97c, 0xfffffd3e, + 0x6b8f, 0xffffa8f4, 0xffffe8d7, 0xffffee7e, 0xa4e, 0xffff8a06, 0x4499, 0x65, + 0xffff9c0e, 0xffffdb63, 0xffff9123, 0x1fdb, 0x424a, 0xffffecca, 0xffffbde3, 0xb4, + 0xffffd7b7, 0xffffbb82, 0xffffa8bb, 0xffffcf0c, 0x1c1, 0xffff87e5, 0xfffff7cc, 0xffffc4dd, + 0xfffff3f1, 0x86c6, 0x3063, 0xffffbf8c, 0x2ddf, 0x7a9, 0x3d41, 0xfffff150, + 0xffff9224, 0xffffe905, 0xffffbd32, 0x76c2, 0x4021, 0xffff86cd, 0xffff895a, 0xffffd092, + 0x3b93, 0xffffbf5b, 0xffffe7f1, 0x44e, 0x7e09, 0x514f, 0xffffdae2, 0xffff8ae4, + 0xffffd626, 0x8cf6, 0xffffc1e5, 0xffff8d3e, 0xffffc16c, 0x5b5, 0xffff8d48, 0x264a, + 0x6750, 0x5f3f, 0x442e, 0xfffff88b, 0xffffe7d2, 0x73ce, 0xffffffac, 0x3302, + 0x5125, 0x590c, 0xffffe068, 0xffffb765, 0x473d, 0xffffd9cc, 0x9ae, 0x3ae0, + 0xffffdd98, 0x4346, 0xbe1, 0x506e, 0xffffe5dd, 0xffff8b4d, 0x6ac3, 0x89a1, + 0x229b, 0xffffa8bf, 0xffffb463, 0xffffb8aa, 0xffffb1bb, 0xffff8205, 0x76ba, 0x1117, + 0xffffae9e, 0xddf, 0xffffaf93, 0x1661, 0x490b, 0xffff798e, 0x4d5f, 0xffffbca8, + 0x13c4, 0x814a, 0x8340, 0xfffffe42, 0xffffc27f, 0xb42, 0xffffbeae, 0x39a3, + 0x5caa, 0xffffd38d, 0x2dba, 0xfffffe91, 0x5451, 0x768d, 0x827a, 0xffffbf93, + 0x5ff2, 0xffffeaa2, 0xffffb0fc, 0x677a, 0xffff758a, 0xffffbcc6, 0xffff9166, 0xffff9b70, + 0xffffa468, 0x36bf, 0xffffbf31, 0x2f3d, 0xffffd890, 0xfffff4af, 0x3b4b, 0xffffc047, + 0xffff98b3, 0xffffea02, 0xffff9ed7, 0x45b0, 0x8c73, 0xffffa371, 0xfffff4fa, 0xffffe309, + 0x3fce, 0x3020, 0x7e45, 0x40bb, 0x506c, 0x63a1, 0x52cd, 0xffff7a93, + 0x3108, 0xffffbf0a, 0xffffe87a, 0xffff782f, 0xffffcb8e, 0x3e37, 0x619a, 0xfffff75a, + 0xffffeb8a, 0x621f, 0xffff87fb, 0x594b, 0x70ee, 0x519c, 0xfffffa39, 0x540b, + 0xffff9ea8, 0x5321, 0xffff9ba2, 0xffff8804, 0x1049, 0x6249, 0xffffc186, 0x6915, + 0x45ba, 0xffffc569, 0x1275, 0x1141, 0xffff7d0c, 0xfffff6a0, 0xc88, 0xffffd0cf, + 0x5493, 0xffffca10, 0x8ba5, 0x5479, 0x56a5, 0xffff72c4, 0xffffc49a, 0x1f28, + 0x26e2, 0x1842, 0x5690, 0xffff8ee0, 0xffff7d53, 0x1896, 0xffffbaf2, 0x724a, + 0xffffc881, 0x2913, 0xffff8e93, 0x1318, 0x288c, 0xffff985d, 0x70ef, 0xffffaa46, + 0x114b, 0x5357, 0x36e9, 0xffff8651, 0xffffb4bb, 0xffffd3a5, 0xffffe071, 0xffffbc9d, + 0x6d70, 0xffff93f4, 0xffff939a, 0xffffbf01, 0xffff9dd5, 0x3632, 0x22dd, 0x290a, + 0xfffff94e, 0xfffffd3f, 0x240b, 0x1dd7, 0xfffff422, 0xffffedb5, 0xffffae3f, 0x3131, + 0xffffb91a, 0xff0, 0xffffa875, 0xffffc56b, 0x7819, 0x2174, 0xfffffc53, 0xfffff477, + 0x6134, 0x4655, 0x94, 0xffffd1ee, 0xffff7e80, 0xffff82ef, 0xffffff54, 0x7000, + 0x1e7c, 0xffffc0d0, 0x84a4, 0x5a2, 0xffff7ba9, 0xffffd915, 0xffff757e, 0x2b2b, + 0x2182, 0xffff9958, 0x3d0d, 0xffffe4af, 0x5c62, 0x7512, 0x4e8, 0xffffa6ed, + 0x2f28, 0xffff8ff9, 0x1a0f, 0xffffd103, 0xffff85f6, 0x69f7, 0xffffb04f, 0x41fe, + 0xffffbc7e, 0x427b, 0xffffa03e, 0xffffee6f, 0xffff9910, 0xffffa897, 0xffff7e20, 0xffffc977, + 0x266c, 0xffffd8e3, 0x3c0a, 0x22b0, 0xffff92ff, 0x1b5d, 0x24f4, 0x3bb7, + 0x425b, 0xffff90a5, 0xffffb687, 0x156d, 0x58ef, 0x1b16, 0xffffd3e1, 0x582, + 0xffffb1b1, 0x691d, 0xfffff853, 0x4c0a, 0x4887, 0xfffffa27, 0xffffbdae, 0xffff8d31, + 0xfffffdb2, 0xffffd009, 0x6287, 0xfffff1ff, 0xffffa748, 0xffffccdf, 0xffffa977, 0x16dd, + 0x281e, 0x8047, 0x66a, 0x2c5a, 0xffff86b5, 0x854a, 0x2a5a, 0x70dd, + 0xfffffeb6, 0x873f, 0xffffdd1a, 0xffffaa65, 0xffff8ca8, 0xffff83da, 0x67c9, 0x4745, + 0x1b41, 0xffffebf0, 0xffff740b, 0x30d7, 0x2afa, 0xffff761e, 0x5539, 0x23e9, + 0xffffabd8, 0xffff931a, 0x408b, 0xfffff2cb, 0x67dc, 0xffff7807, 0xffff964a, 0x5288, + 0xffffc66d, 0x2366, 0x148e, 0x38cb, 0x157f, 0xffff8346, 0xffffb678, 0xffffc4f2, + 0x1549, 0xffffcdb8, 0xffffc5b7, 0xffffd59b, 0xffffd217, 0x6f4e, 0xffffb9ba, 0x8263, + 0xfffff2df, 0xffffd860, 0xffffd9d7, 0xffff9597, 0xffffec05, 0xffff81f3, 0x8be0, 0xffffe4a7, + 0xffff85a4, 0x2fc4, 0x86e9, 0x701, 0x61d3, 0x69ff, 0xffff7563, 0xffff76ce, + 0xffffc010, 0x822f, 0xffff7b66, 0x5e31, 0xffffc663, 0xfffff119, 0x15f0, 0x85d0, + 0x28f1, 0x3fd6, 0xffffa127, 0xffff9166, 0xffffb044, 0x2e04, 0x322c, 0xffffb132, + 0xfffff73e, 0xffffb6b0, 0x3ea8, 0xffffac4d, 0x4a5b, 0xffffa5e8, 0xffff7697, 0x16e, + 0x49ca, 0x1272, 0x4a93, 0x44ce, 0x53e2, 0xfffff35b, 0xffff778a, 0xffffd189, + 0xffffb7e4, 0x90c, 0xffff8795, 0xffff96e2, 0x73ed, 0x3b2c, 0x5db2, 0xffff761f, + 0xffffdc8b, 0x4a06, 0xffffa033, 0xfc9, 0xffffe5e2, 0x7fed, 0xffffca3a, 0x218d, + 0xffffcb3d, 0x2af8, 0xffffb770, 0x8b27, 0xffffcd03, 0x8615, 0xffff7dd4, 0xffff7494, + 0x7f51, 0xffffdf3d, 0xffffbc52, 0xffffa686, 0xffffe0e6, 0xffffd409, 0xffffcd88, 0x5d0f, + 0x6c9c, 0x77ed, 0x69e2, 0x30b8, 0xffff894c, 0xffffe9c1, 0xffffa2b0, 0xffffff92, + 0xffffeecb, 0xffff7486, 0xfffff3a4, 0x4b1a, 0x15cf, 0xffffd171, 0xffffce83, 0xffffb1f3, + 0x2d8f, 0xffffa1a2, 0xffff90d0, 0x10a2, 0x4e89, 0xffff730e, 0xffffb689, 0x8bf3, + 0xffffc917, 0x3a3c, 0x28c6, 0x7a05, 0xffffc793, 0xffff944b, 0xffff8c4f, 0x13b6, + 0x6540, 0x3b3c, 0x1b68, 0xa31, 0xfffffce2, 0xffffa0f0, 0x4d63, 0xa6, + 0x290, 0xffff7f48, 0xffffb06c, 0x5986, 0xffffe2e9, 0xffffe281, 0x6fd1, 0xffff9467, + 0xffffa53c, 0xffffda9c, 0xfffffb90, 0x8a9b, 0x55f2, 0x646f, 0x517f, 0xa33, + 0x1a6, 0xffff8fda, 0xffff890b, 0xffff81f3, 0xffffaac7, 0xffffd83a, 0x7f, 0x2782, + 0x6083, 0xfffff711, 0xffffe8c7, 0x5553, 0x55b7, 0x4d1, 0x56e4, 0xffff8f89, + 0xffffbab6, 0xfffff28b, 0x232b, 0x5139, 0xbe4, 0x3b5e, 0xffffa73f, 0xffffdf16, + 0xcce, 0x5e29, 0xca2, 0xffffd78f, 0xffff861d, 0xffff8ef5, 0x63a9, 0x3d30, + 0xffffb006, 0xffffa007, 0x4596, 0x2801, 0x4936, 0x2816, 0x3f0a, 0xffff92c9, + 0x145, 0x4f85, 0x2c8, 0xc72, 0x36a8, 0xffff81cf, 0xffffeffc, 0xffffde3f, + 0xffffd5f2, 0x5692, 0x60d4, 0x4861, 0x339d, 0x6449, 0xffffdd43, 0xffff8c56, + 0xffffeb4d, 0xffff98b3, 0xfffff4cf, 0x455a, 0xffffb995, 0xffffce66, 0x1dce, 0x1f3e, + 0xffff92ea, 0xfffff303, 0x5783, 0x4aae, 0x29e6, 0xc20, 0x78b9, 0xffff878d, + 0x637, 0xffffb102, 0xffff7e5e, 0x6193, 0x5e68, 0xffffd7d8, 0x654c, 0xffffe71d, + 0xfffff721, 0x339e, 0xffff7e57, 0x5529, 0xfffffcf2, 0xffffe584, 0x26cf, 0xffffce2b, + 0xffffff6b, 0x6600, 0xffffe4e1, 0xffffb27a, 0xffff7760, 0xffff8f2d, 0xffffb0b8, 0xffffc68b, + 0x6907, 0x1110, 0xffffef9b, 0x27, 0xb8d, 0x2872, 0xffffc27e, 0x1bfd, + 0x123a, 0xffffdb77, 0xffffa828, 0x4f0a, 0x6fd6, 0xffff7358, 0xffffafee, 0xffffc050, + 0xffffc121, 0x2dc7, 0xffffe42c, 0x8dbf, 0x2698, 0x7efd, 0xffff98d6, 0xffff9eea, + 0xffffec08, 0x16a3, 0xd9f, 0x6ccb, 0xffff7e32, 0xffff7561, 0x6907, 0x651b, + 0xffff9d8d, 0xffff826f, 0x5a7e, 0x7a70, 0xffff9108, 0x54c, 0x84d0, 0x4a6e, + 0xffffc829, 0x5726, 0xffff9518, 0xffffeb06, 0xdcf, 0x143d, 0x385a, 0xffff8005, + 0xfffff2a7, 0xffffcd4e, 0xffff8b6d, 0xffffec7a, 0x536b, 0xffff8148, 0xffff7ff7, 0x3098, + 0x6fd7, 0x6a8c, 0xffff83fd, 0x52ca, 0x8cc1, 0x251c, 0x3fd6, 0xffffd96c, + 0x26de, 0x710, 0xffff9146, 0xffff9808, 0xffff790a, 0x46c7, 0xffff9cf3, 0x290d, + 0xffffe6b9, 0xffff9078, 0xffff75f7, 0x678a, 0xfffff708, 0x26f2, 0xfffff7aa, 0x583f, + 0x2e8f, 0xffffb64c, 0xffffc0bc, 0xffffa35b, 0x264a, 0xffffc82c, 0xcfc, 0x7d89, + 0x11e0, 0xffffce25, 0xffff9499, 0xffff7aa5, 0xe3c, 0xac7, 0x81c5, 0x7159, + 0x8c01, 0xb5c, 0xfffffc6c, 0xffffa6c9, 0x8249, 0x7524, 0xffff735e, 0xffffce06, + 0x10c7, 0x6334, 0xffff7b8d, 0xffffa314, 0xffffce5d, 0x4f8f, 0x3a7e, 0x277f, + 0x17b8, 0x8cd8, 0xffff9909, 0xffffc891, 0x5de9, 0xffffc012, 0x54d6, 0xffff8015, + 0xffff90d5, 0x15d, 0x703e, 0x3236, 0xffffdd2d, 0xffffca7a, 0x43c6, 0xb61, + 0x6fd2, 0x336c, 0xffff9509, 0xffffa109, 0x17f4, 0x18a4, 0x38d9, 0x6b5e, + 0xffffe932, 0x1fee, 0xffffd6a5, 0xffffeb7f, 0x5284, 0x1655, 0x15c9, 0x1fc6, + 0x6cd5, 0xffffa187, 0x60f5, 0x7248, 0xffff814d, 0xd14, 0x884e, 0xffff8616, + 0xffffab6c, 0x8c75, 0x1005, 0x57fc, 0xffff9c74, 0x84f, 0xffffb6a1, 0xffffd988, + 0xffff7530, 0x782, 0xffffa7be, 0xffff9cf5, 0x1497, 0xffffd560, 0xffffe680, 0xffffdf92, + 0x2ead, 0x8694, 0xffff9c30, 0x3b22, 0xa82, 0x1f5d, 0xffffba52, 0x5743, + 0xffffb4ee, 0xffffd01e, 0x119a, 0xffff7eff, 0x86da, 0x3771, 0xffffbc56, 0xffff89e1, + 0x483, 0xffffdbd8, 0xffffc090, 0x225, 0xac3, 0x4c86, 0x26f7, 0xfffff1fa, + 0xffff76a6, 0x2bb6, 0x6553, 0xffffb0ba, 0x1b0e, 0x4f6f, 0xffffc8f3, 0x787f, + 0x8416, 0x392, 0x18cd, 0xffff8c51, 0xffffb50d, 0xfffff2e8, 0x74bb, 0xffffc84a, + 0xffffca8d, 0xffff8508, 0xfffff79a, 0x5867, 0xffffbde9, 0xffffc76c, 0x5966, 0xffffa1a3, + 0x3ef6, 0xffffaf76, 0xffffb2a6, 0x62b4, 0xffffaf21, 0x1f61, 0xffff8de2, 0x6ae4, + 0x1711, 0x2848, 0xffffc6e4, 0xfffff285, 0xffffce37, 0xfffff33d, 0x10fa, 0x14a2, + 0x8c4b, 0x56d5, 0x6170, 0x2ce9, 0x10d8, 0x350e, 0x3e1e, 0xffffa4e0, + 0x5090, 0x8035, 0x43bb, 0xffffc129, 0x1cdb, 0x7cf4, 0x5897, 0xffffe38a, + 0xfffffda4, 0xffff8f8f, 0x1711, 0x73fe, 0x641b, 0x24f7, 0x53da, 0x3e9d, + 0xffffdd78, 0xffff857b, 0x34e7, 0x7881, 0xffffecc8, 0x80b8, 0xffffd388, 0xffffe600, + 0xffffea29, 0xffffecc9, 0xffff8b09, 0xfffffb67, 0xffffa4ea, 0x6e11, 0x631b, 0x332, + 0xffffcdfd, 0x1236, 0xaf1, 0x720, 0x2ab7, 0xffffa89c, 0xffffeab4, 0x65c1, + 0xffffff40, 0x203b, 0x2c2, 0x4c30, 0xffff94df, 0xffffe58b, 0x71fa, 0xffff8350, + 0xffff888f, 0x33d, 0xffffa878, 0x3d07, 0x199c, 0x644b, 0x5d3d, 0x2c5, + 0x783b, 0x855d, 0xfffffe0f, 0x29cf, 0x4bcf, 0x2631, 0xfffff8a4, 0xffffdd94, + 0x1d61, 0xfffffafc, 0xffff7e05, 0x24a0, 0xffff8a5a, 0x262a, 0x5c5b, 0x229f, + 0xffffe6a8, 0xffffcde6, 0xffffa684, 0x178, 0x37cf, 0x534, 0x190a, 0x86d9, + 0xffffd70b, 0xdf9, 0x8a0d, 0x7218, 0xfffff793, 0x420e, 0xffffa733, 0x811f, + 0xffffa1b0, 0x8cfc, 0xffffb39f, 0xffffb277, 0x8c8d, 0x188, 0x4b59, 0x660c, + 0xffffc5c1, 0xffffc2c9, 0xffffe996, 0x2fd7, 0x1650, 0x6209, 0xffffa6a9, 0x4c28, + 0x7291, 0x587e, 0x4ef5, 0xffffaa02, 0xffffb81c, 0xc34, 0xffff79d4, 0xbe0, + 0x6bc9, 0x49c7, 0xffffb6eb, 0x120a, 0x455f, 0xffffa242, 0x19e1, 0x5b62, + 0x5cec, 0xffff8be5, 0xfffff857, 0xffffc764, 0xa02, 0xffff8856, 0x702c, 0xffff7b18, + 0xffff85d1, 0xdb3, 0x6296, 0x3ef2, 0x55a0, 0xffffe47a, 0x3213, 0xffffdcb1, + 0x2a00, 0x2c6d, 0xfffff530, 0x77d2, 0xfffff051, 0xffff82cc, 0xffffe0f7, 0x603e, + 0xffffcdcf, 0x3ee8, 0xffff9788, 0x4ee3, 0xffff8a08, 0x44d7, 0xffffae63, 0xffffa7bc, + 0x151e, 0x5de1, 0xffffe129, 0x7ec1, 0xffff82e1, 0x7a8a, 0xffff7c0f, 0x866a, + 0x1c48, 0x63fd, 0xfffffdf7, 0x681d, 0xffffeb26, 0x6d6c, 0xfffff7b5, 0x63e, + 0xffffcbab, 0xffffedcd, 0xffffe5d6, 0x4967, 0x834b, 0x28eb, 0x6365, 0x7e4b, + 0xffffd7aa, 0xffff759e, 0x5cad, 0x22f6, 0xffffa019, 0xffff7a60, 0xffffb158, 0xffff9830, + 0xffff88fa, 0x5381, 0xffff9edf, 0xffffb70e, 0xffffb5e0, 0x28b9, 0xffffd778, 0x4aa9, + 0x1029, 0x4de8, 0x85a, 0xffffa5af, 0xffff9598, 0x694a, 0x442f, 0xffffc325, + 0x1646, 0x40b4, 0x51b0, 0x50c4, 0xfffff810, 0x6afc, 0x1611, 0x7c33, + 0x2c36, 0xffffadd9, 0xffffff75, 0xffffa472, 0x2a6f, 0x1ea3, 0x5389, 0x42ec, + 0xffff7734, 0x10df, 0x7e19, 0xffffbe25, 0x45dc, 0x52d1, 0xffff7b84, 0xfffff9d9, + 0x202c, 0x6f8c, 0xffff96b0, 0x4581, 0x13a9, 0x7c2c, 0x2c73, 0x456a, + 0xffff90d7, 0xffff918e, 0x4daf, 0xffff883f, 0x292d, 0xffffd140, 0x4599, 0x7022, + 0x6e51, 0x6fd8, 0xffffcc81, 0x55a, 0xffffb012, 0xffff8234, 0xffff8e12, 0xffff866e, + 0xffff82ab, 0x3a12, 0x77f1, 0xffff8e5c, 0xffffb9db, 0x8114, 0xffffb4d1, 0xffffaa27, + 0xffffef2b, 0x512b, 0xfffff599, 0x2614, 0xffffec61, 0x2e53, 0xffffe14a, 0x8762, + 0x15ea, 0xffffa04a, 0xa9c, 0x3db3, 0xffff9da7, 0x1ba7, 0x6f1, 0x7046, + 0x40d8, 0x2807, 0xfffff498, 0x4003, 0xb8b, 0x80d9, 0xffffc968, 0xffffb091, + 0x6a11, 0x575d, 0xffffbd30, 0x59b7, 0xffffec68, 0x3bc3, 0xffff9852, 0x8d97, + 0x3bdd, 0xffff7b05, 0x3a08, 0x796a, 0xffffde73, 0x23d7, 0xffff937c, 0xffff8364, + 0x2c86, 0xfffff529, 0xffffb941, 0x4f9f, 0x300a, 0xffffb69a, 0xffff8ae2, 0xffff76f4, + 0x6281, 0xffff7a7f, 0xffff8cae, 0x6a9b, 0xffffc3e3, 0x6b24, 0x1a7f, 0xffffbbaa, + 0xffff9898, 0xfffff100, 0xffff9a77, 0xfffffeb5, 0x8062, 0x26f6, 0x72a6, 0x82a8, + 0xffff8d48, 0xffffad0b, 0xffff78ed, 0x39d9, 0xffff8cbd, 0xffffe4fb, 0xffff73d3, 0xffff8749, + 0xffff7787, 0x186d, 0xffff8a66, 0xffffd430, 0x675d, 0x6208, 0x1e0a, 0xffffd207, + 0x7627, 0x272d, 0xffffe162, 0xffff7f78, 0xffff97cd, 0xffffe52f, 0xffff9648, 0xffffbde7, + 0x4a2, 0xffffab13, 0x408e, 0xffffaf5a, 0xfffffccf, 0xffffcaee, 0x3ce9, 0xffff9f86, + 0xffffbdf6, 0x6f7d, 0x1ac0, 0xffff7d8f, 0xffffb5f4, 0x15d5, 0xffffb317, 0xffff8d69, + 0xffffd179, 0xffff9256, 0xffffaed4, 0xfffffd69, 0xffffe67c, 0x8a5d, 0xffffb985, 0x7bd5, + 0x1eaa, 0xffff7ea6, 0x7a6, 0xffffcc73, 0x45fe, 0xffff9312, 0xffff8963, 0xffffcd75, + 0x3534, 0x29af, 0xffffa890, 0xffff81d1, 0x3c3a, 0xffffcbc4, 0x43ba, 0x320c, + 0x70c6, 0x2ec5, 0x189d, 0xffff768f, 0xfffffcf4, 0x3ea8, 0x8212, 0xffffabef, + 0xffffc162, 0x22d4, 0x5755, 0xffffc5a0, 0x87f4, 0xffffb7da, 0xffffa9f3, 0x6eb4, + 0x1abc, 0x5caf, 0x3043, 0x4be4, 0x557b, 0x18e5, 0x2499, 0x7f, + 0xffffcd2d, 0xffffd93e, 0x3af4, 0xffff8c49, 0xffffc5a9, 0xffffb1ba, 0xffff9c0c, 0x18ba, + 0x2cbe, 0xffff8efc, 0xffffa34b, 0x3b05, 0x49d, 0xffffe7b4, 0xffffd9de, 0xfffff909, + 0x5f8, 0x3651, 0xffff7d02, 0x5eda, 0xffffb6f3, 0xffffaa6d, 0x201e, 0xffffc0d0, + 0xd3c, 0x11dd, 0x8c01, 0xfffff81f, 0x84fb, 0xffffe312, 0x7cdc, 0x6d33, + 0xffff8b40, 0x79af, 0xfffff0d5, 0xffffe4ee, 0x73a8, 0x20e6, 0xffff927f, 0x8592, + 0xffffb092, 0x5012, 0x76b, 0xffffa971, 0x8ba1, 0xffffb512, 0x22f3, 0x8ae3, + 0x4217, 0x70e6, 0xffff8854, 0xffffa794, 0x69dd, 0xffffea58, 0x30f6, 0xffffa42d, + 0xffff9908, 0x5e1e, 0x2fd4, 0x329, 0x775a, 0xffff95b2, 0xffffa71e, 0xde7, + 0x2e22, 0x776e, 0x16d4, 0xffff8616, 0xffffb167, 0xffff85b5, 0x57da, 0x72eb, + 0xffffbaf7, 0xffffc299, 0x59ef, 0xfae, 0x1907, 0x4adb, 0x7242, 0x5bd3, + 0x189e, 0x5ad4, 0xffff8e3c, 0xffffedaa, 0xbe0, 0xffffffdc, 0xd45, 0x2ef8, + 0xffff7cd2, 0xffffaddd, 0x685a, 0x832e, 0xffffcf75, 0xffffd4dd, 0xbd6, 0x149f, + 0x3cdb, 0x7691, 0xffffc1e2, 0xffffa1c4, 0x7548, 0xffffa014, 0xffffe53b, 0xfffff6f1, + 0xffffeecb, 0xffffa681, 0xffffafc8, 0x6811, 0x875b, 0x1578, 0xffffdcbe, 0xffff8206, + 0x483f, 0xffff7c5c, 0xffffbf83, 0x2b71, 0x7789, 0xffff733b, 0xffffe5d4, 0x5b88, + 0x7751, 0xffffc109, 0x4a86, 0x7284, 0x67d8, 0x28d4, 0xffffa41e, 0xffff7baf, + 0x761d, 0xffffff5a, 0x3e9e, 0x4e25, 0x2a7a, 0xfffff846, 0xffff873f, 0x43a9, + 0xffffeeea, 0xffff840b, 0x716f, 0xffffacf0, 0x5da3, 0xffffb902, 0xffffaf05, 0x4b57, + 0x73da, 0xffff956d, 0x4cf1, 0x7716, 0x33dd, 0x464, 0xffffeb6c, 0x4007, + 0xfffff3b4, 0x1fe3, 0x721, 0xffffe758, 0xffffabb3, 0x19d8, 0xffffbc97, 0xffff751d, + 0x7cc7, 0xffffb5e3, 0xffff8625, 0x8590, 0xffff8fb2, 0x168b, 0x8a88, 0x5368, + 0x7a0a, 0xffffff50, 0xffff7c26, 0x2c26, 0x5a95, 0xffffd991, 0x19e2, 0xffff7a6d, + 0x3e4b, 0x2e49, 0x4b7a, 0xffffcaf0, 0xffffff91, 0x1fc2, 0x4ed5, 0xfffff2a5, + 0xffffcc85, 0x52ac, 0xffffcef3, 0x13ae, 0xffff7590, 0x4c03, 0x860a, 0x1715, + 0xfffff3b6, 0x3e42, 0xec, 0x5e30, 0x7f7b, 0xffff8325, 0xffffcc59, 0x3c5a, + 0x1730, 0xffff84b9, 0x543c, 0xffffc431, 0x210c, 0xffffff67, 0x3247, 0x78fa, + 0x6646, 0xffffb35a, 0xffffebe6, 0x74d8, 0xffff7d83, 0x696b, 0x2502, 0xffff898c, + 0xffffa4a3, 0xffffe1a7, 0xffffd2c6, 0xfffff1db, 0x8425, 0x4794, 0xfffff992, 0x5bec, + 0xffff999e, 0x4e2, 0xffffa80f, 0xffffee33, 0x6505, 0xfffffe03, 0xffffb529, 0x14ad, + 0xffff8511, 0xffffd437, 0xffffd6f4, 0xffffa716, 0x6fbe, 0xffffb2c5, 0x28fb, 0x9a7, + 0xffff72d3, 0xffffe490, 0x7ad4, 0x534e, 0x883e, 0x69a3, 0xffff9ebc, 0x36c1, + 0x3ac1, 0x8cc2, 0x4363, 0xffff980d, 0x42a1, 0xffff94ce, 0x7fa5, 0x59d0, + 0x2d35, 0xffffaddc, 0xffffc82e, 0x679d, 0xffffff04, 0xfffff390, 0x75c1, 0xfffff28e, + 0xffff8261, 0x7609, 0x6cc6, 0xffffeb00, 0xffffcdb1, 0xffff97c2, 0x2ec8, 0x7a4d, + 0x5a53, 0x4a2b, 0xfffff160, 0xffff7c7e, 0x8af1, 0xffffa8aa, 0x8a2, 0xffffd8c4, + 0x15e7, 0xffffa490, 0x35bb, 0x3846, 0x8b8f, 0xfffff39f, 0x115f, 0x26ed, + 0x3580, 0xffffdd48, 0xffff763b, 0xffffa8ec, 0xc2d, 0x7e4, 0x73c, 0xffffec28, + 0xffffb1ff, 0xffffd69c, 0xecc, 0xffff8a47, 0x1570, 0x5278, 0x7478, 0xffffa96c, + 0x87f7, 0x6c6d, 0xffff9c2a, 0x3e44, 0x4451, 0xffffe66f, 0x77a7, 0xffffa196, + 0xfffff4c8, 0x4d8, 0xffffda98, 0xffffb107, 0xffffe5f6, 0xffffd073, 0xfffffb60, 0xffffd970, + 0x7134, 0x1b66, 0xfffffed6, 0xfffffffb, 0x2f5d, 0xffffc33f, 0xffffb63a, 0x17aa, + 0xffffb6c7, 0xffffb5dd, 0x9a7, 0xffffb6ee, 0xffffce02, 0x4f50, 0xefc, 0xffffe4de, + 0xffff9e9b, 0xffffd397, 0xffffabfb, 0x771d, 0x7313, 0xffff8f5d, 0xbc, 0xffffa767, + 0xffff7a43, 0x1a04, 0x7e99, 0x5029, 0x2c61, 0xffffcf61, 0x6e6f, 0xffff8786, + 0x832e, 0xfffff079, 0x76f0, 0x6720, 0xb72, 0xffffc9bb, 0xffffb384, 0x8b40, + 0x4f6f, 0xffff9c0e, 0xffff7248, 0x8721, 0xffffb61c, 0x3264, 0x4af3, 0x26fa, + 0xffff78cb, 0x3f99, 0x519b, 0x3d38, 0xffff9e3c, 0x6363, 0xfffff082, 0x61, + 0x80e3, 0x882c, 0x1ad9, 0xfffff42c, 0xffffe5d7, 0xffff78aa, 0x7f81, 0x6333, + 0xe4b, 0x99, 0xfffff37c, 0xffffd8b0, 0x5f1f, 0xffffa399, 0x2fe4, 0x413f, + 0x2fb, 0x2d48, 0xffff9550, 0xffffd960, 0x8c72, 0xffff83f3, 0x3d50, 0x85ec, + 0xffffb965, 0x1cdd, 0xffff8626, 0xffffa6c0, 0xffffa058, 0xffffb314, 0x77c1, 0xffffa6dc, + 0x73d6, 0xffffbbbb, 0xfffffbf9, 0xffffcf13, 0xffffd10c, 0x8c3e, 0x5f5c, 0x4af5, + 0xffffd141, 0xffffd407, 0xffffc119, 0xffff86b0, 0xffffb16c, 0xfffff4f1, 0x404a, 0x6bab, + 0xffff9021, 0xffffd5f5, 0xffff87b0, 0xfffffb85, 0xffffbc33, 0x3ef, 0x16dd, 0xfffffc0a, + 0x346, 0xf7b, 0xffffb212, 0xffffe5b9, 0x1c45, 0x5a37, 0xffff8f95, 0xffffccda, + 0x11d2, 0xffff74a0, 0x52c1, 0xfffff70b, 0xffff90dd, 0x5ab1, 0x3ecb, 0x70d0, + 0x8ac4, 0xedb, 0x1091, 0xffff874d, 0xffffdce4, 0x4603, 0x157f, 0x4db, + 0xffffb596, 0x5604, 0xffff7a31, 0xffffe7e6, 0x3bc2, 0x1ec0, 0x861, 0xffffbb57, + 0xfffff94b, 0xffff9fb4, 0xffffea52, 0xfffff479, 0xffff9909, 0xffffa95f, 0xffffa074, 0x8889, + 0x198b, 0x56f4, 0x3423, 0x8241, 0xffffe3ff, 0xffff881a, 0x4e97, 0xffffcf1b, + 0xffffa603, 0x3957, 0xfffff6d5, 0xfffff0b2, 0x8464, 0x1f13, 0xffffe04e, 0x3ed2, + 0x1636, 0x19df, 0xffff9d9c, 0xffffb4af, 0xffff764e, 0x787f, 0x42a6, 0xffffda01, + 0x5a29, 0x8d78, 0x5fae, 0xffffe92e, 0xfffff130, 0x7c51, 0xffffbf50, 0xffffb867, + 0x2ddf, 0xffffb349, 0xffffd0e9, 0x6b0b, 0x6d50, 0xffffd468, 0xffffa3b0, 0xffff97d8, + 0x1960, 0xffffdbbb, 0xffffa4af, 0xffffbd37, 0x2ef3, 0x2437, 0xffffd17e, 0x13e5, + 0x54e0, 0xffffc59f, 0x22bb, 0xffff780f, 0x6239, 0xffff7d96, 0xffffda9d, 0x6e34, + 0xfffface6, 0x295a, 0x2719, 0xffffda03, 0xffffabc0, 0x23a3, 0x1cf2, 0xffffaa50, + 0xfffff1aa, 0x6565, 0x75b1, 0xffffc795, 0xffffb3d6, 0xffffac07, 0xffff8ab8, 0xffffe135, + 0x6be2, 0xffff9a21, 0x66be, 0x1ede, 0xffff9b45, 0xffffddb2, 0x19d9, 0xffff9a42, + 0x1470, 0xfffffd5c, 0x1e7e, 0x6407, 0x6ab4, 0x9cd, 0x1ce7, 0x7246, + 0xffffcc0e, 0x334a, 0x8d32, 0xffffdd26, 0xffff876d, 0x5f42, 0xffffce4d, 0x746f, + 0x23a2, 0xffffbddd, 0x1b98, 0xffffc9e3, 0xffff921c, 0xffffb30e, 0x3477, 0xffffa587, + 0x4067, 0x18a0, 0x361e, 0xffd, 0xffff880f, 0xffffef9a, 0xffffce51, 0x3ed, + 0x139b, 0x4957, 0xffffc1b0, 0x5718, 0x4e72, 0x898c, 0x1e76, 0xfffffc63, + 0x5a7e, 0x3388, 0xffff8b15, 0x8c3, 0x42ed, 0xffff9b9a, 0x1fff, 0xfffff544, + 0x66a4, 0xffff7c9f, 0xf3d, 0x8823, 0xffffab00, 0x8d96, 0xffff9a08, 0x16d3, + 0x55a3, 0xffffc3a3, 0x5f6e, 0xffffa6c2, 0xffff982e, 0xffffe233, 0x3b85, 0x4b3b, + 0xfffff53f, 0x31d2, 0x58f0, 0x8345, 0xffffb052, 0x8516, 0x1013, 0x3e91, + 0xffffdf3d, 0xffffb256, 0xffff8937, 0x7307, 0x6544, 0xffff9898, 0x26fc, 0x7aaa, + 0x5d8c, 0x45c4, 0x8168, 0xffffe0d2, 0xffffa15f, 0xffff8c32, 0x23e2, 0x2f6d, + 0x4e73, 0x5b19, 0xfffff7a0, 0x1530, 0x8a57, 0x5994, 0x7668, 0x8658, + 0x7810, 0x5ae5, 0xffffdd59, 0xffffe2e3, 0x6ade, 0xffff84ab, 0x2286, 0x3324, + 0x34d6, 0x6fa3, 0xffff9c8c, 0x1649, 0xffff9152, 0xffffde80, 0x140c, 0xffffe31f, + 0xffffab3a, 0x85b6, 0x870d, 0x21cd, 0x33ee, 0xffff8aa8, 0xffffcb20, 0x584, + 0xffffcdb5, 0x4b6c, 0x4b54, 0x559c, 0xffffc9b9, 0xffffc227, 0xffff93ec, 0xffffaf9c, + 0x2314, 0x4cd1, 0xffff9b8a, 0xffffa7f7, 0xffffe946, 0x6412, 0x8698, 0xfffff049, + 0xffffe24f, 0xffffbc02, 0xfffff5dc, 0x248b, 0xffffa1a1, 0xfffff591, 0x17f8, 0x7c7f, + 0x2a38, 0xffffc4b7, 0x50f4, 0x4567, 0xffffe9b3, 0x1139, 0xffffdc63, 0xffffaf43, + 0xffff921e, 0x38b5, 0x6f7c, 0x7e35, 0x4cb7, 0xffffdbdb, 0xfffffc86, 0x14e0, + 0xffffb500, 0xffff8fd7, 0xffffc44e, 0xffffe8ae, 0x615, 0x73de, 0x513c, 0xffff8c2d, + 0xffffa65e, 0x733b, 0xffffaa1a, 0xffff9823, 0x390f, 0x81e5, 0x6388, 0x2547, + 0x618c, 0xffffc2b5, 0xfe5, 0x61cf, 0xffff8162, 0xffff8c51, 0x8872, 0x5eae, + 0x5a61, 0xffffab35, 0xffff790b, 0xffff894f, 0xffff7e7f, 0x2ef3, 0xffffa954, 0xffff94a3, + 0xffffec89, 0xffffe3e7, 0x886c, 0xffff9f5c, 0x6429, 0x5828, 0xffffb33b, 0x38d4, + 0x3fb6, 0xffffe5df, 0x5e4, 0xffffa316, 0xffffdea1, 0xffffefe5, 0xbb0, 0xf7c, + 0xfffff415, 0x7f2, 0xfffff4ab, 0x8d31, 0xffffb9b1, 0xffffbbdd, 0xffffc868, 0xfffff245, + 0xffff91ae, 0x62db, 0xffffd076, 0xffffc4c5, 0x5575, 0x43af, 0xffffe6f3, 0x7cc1, + 0x6c8b, 0xffffb56c, 0xffffe101, 0xfffffe07, 0xffff8a88, 0xffff9931, 0xfffff933, 0xffffd4bd, + 0x355e, 0xffffd3df, 0x1e2d, 0x5b90, 0x6ce5, 0xffffff81, 0x5d0e, 0x514b, + 0xffffa086, 0x1caf, 0x300d, 0xffffc1e2, 0x357c, 0x2820, 0x4be, 0xffff9c0b, + 0x2e68, 0xffffb03b, 0x8ab1, 0x2aed, 0x3cc8, 0xffffa250, 0xffffca57, 0xffff8fe0, + 0xffffbc0e, 0xffffa87c, 0x3681, 0xffffff03, 0x6f96, 0xfffff6e8, 0x3818, 0xffff91eb, + 0x460a, 0xffffc57c, 0x23bf, 0xffffa010, 0x6ae0, 0x38fa, 0x6c95, 0xffffe509, + 0x2594, 0xffff892e, 0xffffd6fd, 0x4dbf, 0xffff7bca, 0x595b, 0x5265, 0xffff722c, + 0xffff9bbe, 0x6f1b, 0xffffa0d6, 0xffffb61d, 0xfffff32c, 0xac6, 0xffff8448, 0x37b3, + 0xffffb59c, 0x6132, 0xffff820a, 0xffffb87e, 0x7e80, 0xffffddb7, 0xffff84db, 0xffff868b, + 0x1498, 0x5ece, 0x4761, 0xffffbe71, 0xffff7b6f, 0x2492, 0x6b0e, 0xfffffcba, + 0xa45, 0xd5d, 0x361d, 0xf45, 0x82fe, 0xffffd7cf, 0xffffc64e, 0xffff8ad6, + 0xffffb43b, 0xfffff00e, 0xffff7b5b, 0xffff9858, 0x3756, 0xffffe97b, 0x6167, 0x52b9, + 0xfffffc14, 0x4bf6, 0x2c11, 0x5c7b, 0x75fc, 0xfffff1b7, 0x47f4, 0xffffc8ca, + 0x5fbc, 0xc3f, 0xffff9e06, 0xffffb109, 0xffff791e, 0x6661, 0x8942, 0xffff92b4, + 0xd4f, 0x15a8, 0x625d, 0x3878, 0xffff9a70, 0x636b, 0xffffad1a, 0xfffffc36, + 0x1abe, 0xfffff303, 0x4b0a, 0xffffe7cc, 0xffff904c, 0xffffe288, 0x5acd, 0xfffff71e, + 0x3252, 0xce1, 0x2db2, 0xffffc97a, 0xfffff8e7, 0xffffbb28, 0x7a7d, 0x6ed5, + 0xffffae7d, 0x8dbe, 0xffff744e, 0xffff8e03, 0x6cb, 0x86a7, 0xffffdc22, 0xffffd8fb, + 0xffffd18d, 0x4626, 0x8c87, 0xffffc3ae, 0xffffb882, 0x689a, 0x3791, 0xffffc0a0, + 0x7223, 0x3c, 0x8fe, 0xffff9ecf, 0xffffd89a, 0xffff7e2d, 0xffffa145, 0x56e7, + 0xfffffb34, 0x480c, 0xffffb7b6, 0x4d54, 0xffffc5f6, 0xffffde25, 0x4d3e, 0x7302, + 0xffffdb67, 0x4fb7, 0xfffffb02, 0x8765, 0xffffab7b, 0xda7, 0xffffb04f, 0xffffc9e5, + 0x15b6, 0x2718, 0xffffc98c, 0xffffe2eb, 0x8011, 0x8b74, 0x7aa7, 0xa1a, + 0x5d48, 0xffff9ffa, 0x1d7, 0xffffef63, 0xffff9746, 0x7c5b, 0xffff816e, 0x6c68, + 0x156f, 0x85b8, 0x16bc, 0xffffc689, 0xffff8006, 0xffffe2ec, 0xfffff102, 0xffffeb7d, + 0x8956, 0xfffff640, 0x4713, 0x7bad, 0x41bb, 0xffff9f79, 0x3691, 0xffff7b9d, + 0x7ca6, 0x5c98, 0x81e4, 0xffff9084, 0x7825, 0x543a, 0xffff8b4b, 0xffffd2f9, + 0xffff7f0a, 0xffff7655, 0x665e, 0xffffd3df, 0xffff8b05, 0x2da3, 0x2c10, 0x4dcf, + 0x23e0, 0x4e27, 0x5fb6, 0x82f3, 0xffffe5cb, 0x6d98, 0xffff9691, 0xa4a, + 0x3f51, 0x2573, 0x894c, 0xffff8107, 0x5091, 0xffffe034, 0x83db, 0x2029, + 0xffff8d63, 0x6ee6, 0xffff92d2, 0xfffffe7e, 0x5f72, 0x6704, 0xffffd1f6, 0x4d40, + 0xffffb1f6, 0x2766, 0x4b84, 0x7e47, 0x728a, 0x51f7, 0xffff9a48, 0x1149, + 0xffffc964, 0x456f, 0xffffa797, 0x6112, 0xffff7e4c, 0xffffea92, 0x8a8b, 0xffffc9bf, + 0xffffbc0c, 0x6591, 0xffffd69c, 0xffffe54f, 0xffff7adb, 0x581b, 0xffffad1f, 0xffff9607, + 0x3e51, 0xffffe644, 0x80a4, 0x272e, 0xffffd8d5, 0x4c15, 0x639a, 0x7345, + 0xffff7d10, 0x1f97, 0xffffe213, 0xffffcd19, 0xffffb907, 0x7196, 0x348c, 0xffffcd02, + 0xffffc4b0, 0xfffff3d3, 0x56d5, 0xffff7712, 0x2415, 0x19c9, 0xffffaa34, 0x5be0, + 0xffffbe3d, 0x3edb, 0xffff7ba6, 0xffff8704, 0xffff9b22, 0xffff7398, 0x1ad2, 0x2b12, + 0xfffffa9e, 0x82a0, 0x289f, 0x20c1, 0xffffa302, 0xffff8bac, 0x5528, 0x5b36, + 0xffff9f0e, 0x300, 0x76ab, 0xe31, 0x54dc, 0x14c2, 0xfffff3f7, 0xffff9727, + 0xffffb8a1, 0xfffffd6c, 0x668c, 0x12ce, 0x5e2b, 0x837f, 0x79d9, 0xffff9f2c, + 0xffffe8c0, 0x5569, 0xffffa931, 0xffff9828, 0x5447, 0xe70, 0xffffc612, 0xffffbdc8, + 0xffff8100, 0xffff948f, 0xffffd762, 0x165, 0x7caf, 0xffffe5ba, 0xffffd76a, 0x1b3f, + 0xffffbace, 0x75b9, 0x266, 0x3be3, 0xffffb139, 0xffffdf94, 0x2528, 0xffff85e5, + 0x63ec, 0xffffea79, 0x784, 0x12c5, 0xffffcf6d, 0xffff941e, 0xffffd6c0, 0xffffe17c, + 0xffffde73, 0x317d, 0xffff7430, 0x2eea, 0x2d4d, 0xffff7937, 0xfffffb7c, 0xffff802d, + 0xffff902a, 0xfffff7d6, 0xffffbdb7, 0xffffdf44, 0xffffd10a, 0xffffc6a9, 0x36fe, 0xffffc98c, + 0xffff732c, 0xffffe42e, 0xffffd1e4, 0x6c5e, 0xffffa8ab, 0x7624, 0xffffdd12, 0xffffaf68, + 0x4d98, 0x5f15, 0x865d, 0xffff8d23, 0x5266, 0x276c, 0x295e, 0x1d29, + 0x5e0b, 0x772f, 0x2942, 0x459e, 0xffffe4eb, 0xffff73dd, 0xffffd004, 0xffff886f, + 0xffffcaf9, 0x18e0, 0xc66, 0xffffd08d, 0xffff7a9f, 0xffffd290, 0x88d8, 0xffff7c4b, + 0xffff86dd, 0xe4c, 0x15ef, 0xffff99f5, 0xffffde0e, 0x44db, 0x6855, 0x29de, + 0x3458, 0xffffc7a8, 0xffffdc32, 0xffffb3ec, 0x6e1b, 0xffff8dfd, 0x86a6, 0x685d, + 0xffffee8d, 0xffff92e9, 0xffffc182, 0xfffff271, 0x39d5, 0xffff86a2, 0xffff7472, 0xffffecba, + 0xffffd44d, 0xffff7fef, 0xffffd860, 0xffffeb6d, 0x3822, 0xffff91b2, 0xffffe1ea, 0x657f, + 0xffff98be, 0x7c56, 0xffffe379, 0x1286, 0xfffff440, 0xffffefd4, 0xffffc00c, 0xffffef9d, + 0xffffbb0a, 0xffffe423, 0x717a, 0xffff8177, 0xffffc56c, 0xffff87c0, 0x389, 0xffffbd6f, + 0x6a85, 0x6072, 0xffff8991, 0x6768, 0xffffb310, 0x55a0, 0x3566, 0xffffa763, + 0x6ad8, 0xffffecf0, 0x6e47, 0x460f, 0xffff74c3, 0xffffa827, 0xffff8ed2, 0x63a8, + 0x6785, 0xffff9ab6, 0x8721, 0xffffb48d, 0xffff8e1d, 0x1b24, 0x4cad, 0x32a8, + 0xffffa063, 0x3cc6, 0x3f51, 0x27c7, 0x32e2, 0xffff9cf7, 0xffffeca9, 0x6a39, + 0x58fa, 0x305d, 0xffffb237, 0xffff8301, 0x2b29, 0x4d40, 0xbfb, 0xffffea6f, + 0x15a1, 0xffffcc4f, 0xffffc735, 0xffffdaca, 0x26e5, 0xffff9e2f, 0xffffc05a, 0xffff8cf2, + 0x7a37, 0x4531, 0xfffffa02, 0xffffb210, 0x8633, 0x4f0f, 0x754, 0xffffed54, + 0xffff8740, 0x59d2, 0xffff767e, 0xffff855a, 0x3d85, 0x71b9, 0x72cd, 0x4d3b, + 0x78a1, 0xffffa6c1, 0x6c3e, 0xffff9317, 0x2926, 0x119a, 0x44d2, 0xffffb033, + 0xffff935e, 0xffffc224, 0x4ba1, 0xffffdba2, 0xffffb9b7, 0x17e4, 0xffff8b75, 0x2f37, + 0xffff73b2, 0xffffcc5c, 0xffff88bc, 0x213a, 0x47b0, 0x13d5, 0x3ca1, 0x51a7, + 0x2e56, 0xffffc38a, 0x7f7a, 0xffffe80b, 0xffff8832, 0x7270, 0xffff8f10, 0xffff7ca1, + 0x6c56, 0x8390, 0xffffb0bf, 0xffff9200, 0x6bbb, 0x46c8, 0xfffff4db, 0x2ab3, + 0xffffa2c1, 0x7288, 0xfffff4a6, 0x5ec3, 0x7c3, 0xffff81af, 0x3cc2, 0x28f7, + 0x4a58, 0xfffff026, 0x7ff0, 0xfffffc62, 0xffff9148, 0xd8f, 0x185, 0x59f4, + 0x1caa, 0x39dd, 0x3787, 0x4a31, 0xffffed74, 0x4336, 0xffffa9ea, 0x4646, + 0xffffd6f7, 0x175a, 0xffffe833, 0xffff95e8, 0xffff79ef, 0x7509, 0x68b8, 0x5445, + 0xffffe6a9, 0x49e4, 0xee4, 0x5e83, 0xffff9812, 0xffff9b80, 0xffffcd5b, 0xffff905e, + 0x6959, 0x38cf, 0xffffbce0, 0x758b, 0x3d88, 0xffffc47d, 0xffff86ca, 0x1c6a, + 0x10f2, 0x2934, 0xffffeb47, 0xffffa621, 0xfffff453, 0x8822, 0xffffd84d, 0x88a8, + 0xffff7738, 0x2211, 0x278b, 0xffffb4fd, 0x4a25, 0x24a1, 0xffff9982, 0x4316, + 0x1f4, 0xffffec51, 0xffffaf4d, 0xfffff10f, 0x452d, 0xffffed98, 0xffff89e2, 0xffff9770, + 0xffff7393, 0x2e9a, 0xffffa805, 0x870c, 0xffffb79d, 0xffffdcb9, 0x190f, 0xffffaf36, + 0xffffae0b, 0x35a8, 0xffffcb81, 0x49b6, 0x5b81, 0xffffad9f, 0x4b00, 0x59f6, + 0xbcf, 0x2bf6, 0xffff83b9, 0x56a, 0x478b, 0xfffff9a6, 0xffffefb1, 0xd52, + 0xffff977e, 0xfffffde7, 0x2281, 0x486b, 0xffff7a45, 0x38, 0xffffa31e, 0x545b, + 0x5f67, 0x759e, 0x7227, 0x4710, 0xffffda15, 0xffffde83, 0xffffb16f, 0x445a, + 0xffffb2a9, 0xffffe77a, 0x8ff, 0x136f, 0xffffaa07, 0xffff739c, 0x16f8, 0xffffd05a, + 0x1bc1, 0xffffbd49, 0x6534, 0xffff8187, 0x30d6, 0xffff7c5a, 0x8038, 0xffffc927, + 0x81d3, 0x6e7, 0x7d71, 0x5eed, 0x2dbc, 0x7779, 0x49d9, 0xffffa59c, + 0xffff7c2e, 0xffff7a46, 0x1461, 0xffffcbc6, 0x47cd, 0x6df4, 0xffff9c8b, 0xffffba56, + 0xffffc1aa, 0xffffe2c4, 0xffffb8b3, 0x354f, 0xffffba6f, 0x7e32, 0x88d2, 0x1dda, + 0x65c3, 0xffff7a23, 0xffffa941, 0x772d, 0xffffa8e4, 0x6cac, 0x6006, 0xffff8cc0, + 0x2c22, 0xffff8f93, 0xffffd510, 0x4ac1, 0xffffcac2, 0xffffbfc5, 0xffff772e, 0xffffd90e, + 0xffffc04b, 0x1858, 0xffffdb53, 0x4730, 0xffff87ca, 0xfffff776, 0xb2b, 0x5f04, + 0xffff7deb, 0xffffafc4, 0x273c, 0xffffa9ad, 0x2f96, 0x1df3, 0xffff99ab, 0x3ccb, + 0x8cb2, 0x69c, 0xffffb855, 0xffffa904, 0x8a40, 0x1b30, 0xffffbfe7, 0x8a23, + 0x70f8, 0x57da, 0xffff75fe, 0x2214, 0x2be1, 0xffff990b, 0xffff9394, 0xffffe908, + 0xffffb2c4, 0xffffa067, 0xfffff7c6, 0xffff97cd, 0xffff7498, 0x3af8, 0x1241, 0x10e3, + 0xffffa621, 0xfffff296, 0x698e, 0xffffa28b, 0xffff9084, 0x12cf, 0xffffb1f9, 0x4359, + 0x336c, 0xffffcf1e, 0xffffa763, 0x80bf, 0x4019, 0x47d5, 0xffffec7a, 0xffff83f6, + 0xffffd75a, 0xffffb050, 0xffff9104, 0xfffffb14, 0xffffd821, 0xffff8b8d, 0xffffb3fd, 0xffffebb6, + 0x124e, 0xffffd263, 0xffff7eab, 0xb78, 0xffffb115, 0xffffa4e5, 0xffffe296, 0x1f8, + 0xffffdd28, 0x3378, 0xffff9498, 0x3617, 0xffffb7c3, 0xffffe507, 0xffffe6ae, 0x47b2, + 0x18a5, 0xffff77c3, 0xffffa734, 0xffffc105, 0xffff8925, 0x7add, 0xfffffab0, 0xffffe3ec, + 0x39d4, 0x74ba, 0x56ea, 0xffffebec, 0xffff8e36, 0x3b63, 0x931, 0xfffff745, + 0x81c5, 0x368d, 0xffffbca4, 0xffff80b1, 0xffffe01f, 0xfffff52c, 0xffffacf4, 0x486f, + 0xffffc5e0, 0xfffffaae, 0x10d4, 0x5ea8, 0x4832, 0x38b4, 0x6894, 0x6002, + 0xffffdf3b, 0xffffa4a1, 0xffffe890, 0xffffb7b1, 0x3fee, 0x3c88, 0x1b52, 0xffff8883, + 0x1f6c, 0xfffff5ac, 0xffffc0cb, 0xac9, 0xcd4, 0x14f7, 0xffffa823, 0x21e2, + 0xffff8831, 0x5526, 0xffffc6a1, 0x4551, 0xffffa492, 0xffff9837, 0xffffa222, 0xffffde9d, + 0x1efc, 0xffffec4e, 0xffffd75b, 0x3268, 0xffffc8d6, 0xffff7a3f, 0x4c9b, 0xffff86a0, + 0x45e3, 0xffffddfb, 0xffff806b, 0x7aef, 0xffffcfa4, 0x30ef, 0x7f2b, 0xffffa3bf, + 0x46d7, 0xfffff316, 0x3720, 0x6dd9, 0xffffdb02, 0xffffbc61, 0xffffdd72, 0x81b9, + 0x1bf4, 0xffffb670, 0xffffcd6c, 0x37d8, 0xffffbd23, 0x4df6, 0xfffff2eb, 0xfffff687, + 0x8b59, 0xffff909b, 0x34cd, 0xffffc786, 0x143b, 0x8570, 0xffffc38e, 0x965, + 0xffffd3a1, 0xffffac12, 0xffffbb63, 0xffffe93f, 0x12d2, 0xffffe053, 0x3b2b, 0x4bcd, + 0x52f2, 0xfffff538, 0xffffb301, 0xf71, 0xffffb774, 0xffffd5ba, 0xffffbe11, 0x1121, + 0xffffa83d, 0x1a5a, 0x1ce, 0x8a49, 0xffffccb0, 0x82d2, 0xffffb440, 0xffff8a82, + 0xffff91fe, 0xffff8bad, 0x3e1d, 0x5005, 0xffffb167, 0xffff8f02, 0x1a0b, 0xffffc6d1, + 0x6303, 0xffffb2fe, 0xffffae6b, 0x507c, 0xffff907f, 0xffffeecd, 0xffff801b, 0x7b03, + 0xffffe69a, 0xffff8454, 0xffff8110, 0x2195, 0x60df, 0xffffe944, 0xffff7ac8, 0x21d, + 0x798, 0xffffed4d, 0xffff78b9, 0x36fa, 0xffff7616, 0xffffbf0e, 0x32c0, 0xffffcc92, + 0x294d, 0x819b, 0x2413, 0xffffaa63, 0x7ae7, 0xffff72bb, 0x6505, 0xfffff0e8, + 0x7b0f, 0xffff7b00, 0xffff8a4b, 0xffff8f23, 0x2336, 0xffffe49d, 0xffff9a9c, 0x478d, + 0xffffc085, 0x6059, 0xffffd216, 0xffff9e9b, 0x5e49, 0xffff7f3e, 0x6038, 0x6ad9, + 0xffffc10b, 0xffffd364, 0xffff7ecc, 0x6fef, 0xffff7809, 0xffffc298, 0x835f, 0xffffb70d, + 0xffffbc76, 0xffffc2fa, 0x1779, 0x247d, 0xffffdbe8, 0xffffb8de, 0xffffb96f, 0xffff81ff, + 0xffffbea1, 0xffffa830, 0xffff7fcd, 0xfffff310, 0x51fe, 0x65dd, 0xffff9f9f, 0xffffc799, + 0xffff8390, 0xffffd9da, 0xffffbb03, 0xffffb886, 0x6e67, 0x5799, 0x677b, 0x45ad, + 0xffff934b, 0x70b5, 0x44d0, 0x2f7e, 0xffff7568, 0x15b2, 0xffffbb0d, 0x7bf6, + 0x2605, 0x2b90, 0x4916, 0xffff9cd0, 0xffffaef8, 0xffffe9ab, 0x7fbe, 0xffffac1a, + 0x846, 0xffffc2d1, 0xffffbfba, 0x7699, 0xffffbfb5, 0xffffdef6, 0xffffbfed, 0x2d29, + 0xffffee6e, 0xffffb0c7, 0x8879, 0x8584, 0x3415, 0xffffc2e9, 0xffffc15a, 0xffffa8c4, + 0x3d0c, 0x31ab, 0xffffc3e1, 0xffff8bd4, 0x2ce5, 0x409c, 0x4243, 0xfffff9ce, + 0xffffecff, 0x27c6, 0xffffcddf, 0x6137, 0xffff96f2, 0xffff8d64, 0xffff9537, 0x8566, + 0xffffdf03, 0x6ef9, 0x7ada, 0x1413, 0x46e4, 0xfd7, 0x2c50, 0x7295, + 0xffff8827, 0x8938, 0x3392, 0xffffe413, 0x6e09, 0xffff811b, 0xffffba76, 0xffffc622, + 0x4554, 0xffffba5e, 0x6476, 0xffffb6f3, 0x2589, 0xffffcb99, 0x121a, 0x7e6d, + 0xffffd01a, 0x5bb5, 0xfffff271, 0x5031, 0x528d, 0x63f7, 0x7e28, 0xffffec61, + 0x18e, 0x1915, 0xffffaa49, 0xfffffd82, 0x6e94, 0x80c3, 0xfffff9b9, 0xffff9231, + 0x2b46, 0xffffb3c1, 0x8ef, 0x220e, 0xffffa349, 0x3649, 0x8397, 0xffff981d, + 0x6ad9, 0xffffaee7, 0x1fa9, 0xffffab33, 0x1e07, 0x7698, 0x7732, 0xffffe853, + 0xffff7232, 0x4f9f, 0xffffcbbf, 0xffff7feb, 0x68ce, 0xffffbdf9, 0x17d4, 0x2ee8, + 0x12c4, 0x8112, 0xffffb67d, 0x4914, 0xffffd9a2, 0xffff9e22, 0x74c8, 0xffffd9d8, + 0x5ed2, 0xc27, 0x3957, 0x39ca, 0xffffae61, 0x4edd, 0x15d8, 0x50b9, + 0x5077, 0xffff9787, 0x421a, 0xffff7ec0, 0xffffb93c, 0xffff922c, 0x867f, 0x855c, + 0xffff91fc, 0xffff8bc5, 0xffff8a93, 0x3e3f, 0xffff7c92, 0x772f, 0xffffaedc, 0x474e, + 0xffffb582, 0x135b, 0xffffb468, 0xfffff11d, 0x6298, 0x43bd, 0xffff9698, 0x43e1, + 0xffffc5a7, 0xfffffed5, 0xffffd9be, 0x4176, 0x322d, 0x6eef, 0xffffbdda, 0xffffce75, + 0xffff990d, 0x1857, 0xffffe0bc, 0x639e, 0xffffb5de, 0xfffffa1b, 0x70c8, 0x3404, + 0xffffd256, 0xffffd016, 0x7b8b, 0x69ad, 0x843c, 0xffffe02d, 0xffff7409, 0x4bc2, + 0xffffa87d, 0xffff7408, 0xffffd4d3, 0x27a2, 0xffff74a7, 0xffffc225, 0xffffc7a1, 0xffffcaa1, + 0x3a52, 0x2fe3, 0x36c3, 0x4f3c, 0xffffb5b5, 0x1ec0, 0xffffac64, 0x5f2c, + 0x1f24, 0xffff9dbf, 0x482e, 0x384b, 0xffffb6ca, 0x1acf, 0x66d6, 0x2652, + 0xffffd61d, 0xffff88fc, 0xffff7bed, 0x1862, 0xffffcf25, 0xffffb8e2, 0xffff9823, 0x526f, + 0xffff8e92, 0x6309, 0x4888, 0xffffe6f9, 0x631, 0xffffd94a, 0x1cd3, 0xffffa01b, + 0x43d8, 0x2793, 0x6557, 0x794b, 0x1383, 0x269, 0x1240, 0xffffe15c, + 0x69c5, 0xffffe7b1, 0x8d62, 0x2ecc, 0x7ab3, 0xffff7c8a, 0xffff7d9c, 0x7270, + 0x5c06, 0x7667, 0x1006, 0x7c60, 0x53af, 0xffff8990, 0x4bf4, 0x7183, + 0x2675, 0x30f1, 0x2478, 0x6124, 0xffff8265, 0x116e, 0xffffab22, 0xffffda7e, + 0xffff8517, 0x89fc, 0xffff7a6e, 0xffffb9f7, 0xffffd29e, 0xffffa22b, 0x461, 0xffff8708, + 0x1bcb, 0x7e6d, 0xffffc54a, 0x5d4d, 0x88a1, 0xffffdf3b, 0x1d91, 0x12b6, + 0xffffeb16, 0xffffe8ea, 0x30f0, 0xffff7427, 0xffff7d09, 0xfffff64e, 0xffff8896, 0xffffa354, + 0xfffff72e, 0xffff81d9, 0xffff996c, 0xffff74a4, 0xffffc3cf, 0xfffff2d2, 0xffffbf2c, 0xffff741d, + 0xffffd89c, 0xffffc38a, 0xffffde7d, 0x5f1c, 0xffffb1bb, 0xffffa21f, 0xffffb38e, 0x8236, + 0xfffff3ed, 0xffffce5d, 0x585e, 0xffffbe23, 0xffff8372, 0xffffaf4d, 0x3fcf, 0x3927, + 0x5dda, 0xffffa074, 0xf76, 0x6969, 0x4196, 0x875e, 0xffffb681, 0x35bc, + 0xffffbf70, 0x15af, 0xfffff405, 0x8b2a, 0x6d4c, 0x218d, 0x89bc, 0xffff9efe, + 0xffffc56b, 0xffff942b, 0xffff8aa0, 0x4739, 0x6f8f, 0xffff8a85, 0x6c68, 0xffff958c, + 0xffff9507, 0xffff9771, 0x3fb7, 0xffff8354, 0x6186, 0xffff90d7, 0x1520, 0xffffe018, + 0x3b58, 0x411d, 0xffffdc5f, 0x1ecd, 0xc86, 0xffffa92a, 0xffffeaa6, 0x73a, + 0x3def, 0x58de, 0x4933, 0x675d, 0x5e3, 0x25e2, 0x3eb, 0x714d, + 0xa3a, 0xffff8420, 0xffffcb78, 0xffff887a, 0xffff7747, 0xffffff76, 0x280b, 0x2abd, + 0xffffbdcd, 0x7dc1, 0xffffac20, 0xffffc30a, 0xffff7238, 0x27f3, 0xffffce4b, 0x398d, + 0x4244, 0x3750, 0xffffc875, 0xffffc657, 0xffff9c8c, 0x3779, 0x55ce, 0x49d2, + 0xfffff9b4, 0xffffd3a7, 0xffffade9, 0x3b41, 0x681f, 0xffff8812, 0xffff7a5a, 0xffffc989, + 0x49e6, 0x3783, 0xffffb5f4, 0x70ba, 0xffffbf48, 0x8933, 0x3314, 0x2047, + 0x111e, 0xffffd1e0, 0xffffea38, 0xffff779e, 0xffffabe9, 0xffffe109, 0xffff9c1c, 0x3fdd, + 0x157b, 0x2726, 0x480, 0xffff7635, 0xffffb05d, 0xffff82de, 0xcec, 0xfffff7d9, + 0xffffb171, 0x45f9, 0x8a9f, 0x1d04, 0x1b06, 0x80b, 0x39a9, 0xfffff58c, + 0x274c, 0x1abd, 0xffff7ae0, 0xffffc2a1, 0xffffce98, 0xffff9427, 0xffffa278, 0xffff8c58, + 0x31d6, 0x6f95, 0xef0, 0xffffd311, 0xffff95a0, 0x7c0b, 0xffffaf59, 0x934, + 0x73b3, 0xffff98df, 0xffffa574, 0x6069, 0xffffead8, 0x671f, 0x5c9f, 0x4354, + 0x23dc, 0x1c3f, 0xffffbc97, 0x22d2, 0xffffdd4e, 0x1239, 0x3af3, 0xffffefad, + 0x6121, 0xffffd1e6, 0x66da, 0xffffcc0a, 0x63ea, 0xfffffc17, 0xffffc2d6, 0xffffa0f2, + 0xffffc2d3, 0xffffa772, 0x4b13, 0xffffcfba, 0xffffee11, 0x6561, 0x38cc, 0xffffabbe, + 0xffffe3f2, 0x4c6b, 0xfffff7ef, 0x6373, 0xffffeed8, 0x34cf, 0x59d9, 0x2699, + 0xffffd7fa, 0xfffffa92, 0xffffac49, 0x62d7, 0x6daa, 0x4ab3, 0xffffaf00, 0xffffce18, + 0xffff7e6c, 0x118, 0x72fe, 0xffff874a, 0x645, 0x2d6f, 0xffffa91f, 0x7443, + 0xffff82ca, 0x553f, 0xffffb391, 0xffff83c6, 0x581a, 0x4124, 0x4d68, 0x5981, + 0x40c2, 0xffff925c, 0x10e3, 0xffff957f, 0x7b13, 0xffff9008, 0x3563, 0xffffb7d3, + 0xffff8c80, 0x8508, 0x8a7e, 0xffffd76b, 0x5321, 0x39bb, 0xffffe271, 0xffffa6fa, + 0x758e, 0x3092, 0xffffd014, 0x2666, 0xffff745f, 0xffffb06f, 0xffff861c, 0xffffe4c9, + 0x306f, 0xffffc98f, 0xffff950b, 0x2139, 0x7698, 0xffff9796, 0x1df5, 0xfffff0f9, + 0x112c, 0x467a, 0x211b, 0x4469, 0x168f, 0x38b7, 0x2007, 0x2908, + 0x24, 0x280e, 0x5051, 0xffffb28f, 0x4c68, 0x836a, 0xffffea37, 0xffff9080, + 0xffff95e1, 0xffffe897, 0xffffcabd, 0xffff87dc, 0x88c2, 0x4507, 0xffff8a98, 0x405f, + 0x52c8, 0xffffc450, 0x204a, 0xffff8690, 0xffffec68, 0x28a5, 0xffffdb3c, 0xffffa42c, + 0x13e2, 0xffffb958, 0x595d, 0x4eae, 0xffff8001, 0xffff7f70, 0x4a8c, 0x748b, + 0xffffb9ea, 0xffff87ba, 0x4a61, 0xa72, 0xfffffc5b, 0xffff9428, 0xfffff71c, 0xffffa0d7, + 0xffffd5c7, 0xffffcd3f, 0xffff77eb, 0xfffff986, 0xffff92c6, 0x57a0, 0xffffe759, 0x815c, + 0xffff8cb3, 0xffffcdc4, 0x6a3f, 0x1a8, 0xffff7840, 0x60bd, 0xffffb606, 0xffff8946, + 0xffffebc2, 0xffffaae5, 0xffffce9d, 0xffffca7c, 0xffff761c, 0x3ffb, 0xffffc9e6, 0xffff94b5, + 0xffff7888, 0x63fc, 0xffff8da1, 0xffffd969, 0x21b0, 0x47be, 0x39e9, 0xffffee2b, + 0xffffbc45, 0x82a2, 0x243d, 0x75bc, 0xffff88cf, 0x8c54, 0xffffb154, 0xffffa214, + 0xffffb8bb, 0x8a04, 0xffff87de, 0x8cd6, 0xffffd8d3, 0xffffc81e, 0xffffdf1c, 0xffffb674, + 0x5782, 0xffffa361, 0xffffcd7b, 0xffffe9d7, 0xffff9bbf, 0xffffcae9, 0xffffeab3, 0xffffd75e, + 0xfffffab2, 0xd68, 0x8288, 0x5177, 0x5f43, 0xffffeebd, 0xffffc78f, 0xffff72d2, + 0x812, 0x752a, 0xffffc8ce, 0xfffff6d2, 0xdb9, 0x6b64, 0x3527, 0xfffff063, + 0x79be, 0x6579, 0xffffe19c, 0x226f, 0xffff9529, 0x1eb8, 0x8747, 0x41e2, + 0xffffde27, 0x46e7, 0x86bf, 0xffffa714, 0xffff93c7, 0xffffe02a, 0xffffc1e6, 0x36de, + 0xffffc76e, 0x43ed, 0x65a, 0x6cf4, 0x57f3, 0x4916, 0xffffecae, 0x7ca7, + 0x5c09, 0x48f0, 0xffffb23e, 0xffffaecc, 0xffffa88b, 0xffff7d10, 0x87c4, 0x669f, + 0x56c2, 0x43d, 0x8c6b, 0xfffff478, 0x87cb, 0xffffd0f4, 0xffffa7a1, 0x25e7, + 0x5a3d, 0x1df, 0xfffff384, 0x3438, 0x1ce8, 0x800, 0xffff8048, 0xffffad8a, + 0xffff9d72, 0xffff73f5, 0x818d, 0x420a, 0xffffae9d, 0xffffc332, 0xffffbe39, 0xffffce52, + 0x5b09, 0xffff8635, 0x1157, 0xffffb3d7, 0x33d1, 0xffff8149, 0xffffbe1d, 0xffffff1d, + 0xe7c, 0xa66, 0xffff8167, 0x191d, 0x1beb, 0xffff82ec, 0xffffa8a3, 0xffff78af, + 0x52ca, 0xffff7862, 0x7c41, 0x8b97, 0xffffbe29, 0xffffcaac, 0x7279, 0x893c, + 0x3b70, 0x7947, 0xffffed3c, 0xffffe6e8, 0x3dcb, 0x1d01, 0x88cf, 0xffffb5ae, + 0xffffa7ef, 0xffffece8, 0xfffffb0a, 0x1c20, 0x3691, 0x4f, 0x40aa, 0xffffebe0, + 0x5fa0, 0x38, 0x44dd, 0xffff8ab5, 0x2c13, 0xffffd8b8, 0xffff9f3d, 0x8815, + 0x8683, 0x6a60, 0x1a12, 0xffffa788, 0x5215, 0xffffcc46, 0xffff75bd, 0xffff8c9d, + 0x2871, 0xffff889e, 0xffff9608, 0x8d91, 0x8c85, 0xffffc2ee, 0x458b, 0x48e7, + 0x1d47, 0xffffe974, 0xffffa020, 0xffffe1fd, 0x6f80, 0x8264, 0x885, 0x4317, + 0xffffd135, 0x89c9, 0xffffb412, 0xffff7b42, 0x5b21, 0x5a98, 0xffffbc39, 0x16c0, + 0xffff7c6e, 0x286b, 0x1996, 0xffffd5e6, 0x5fb3, 0xffff950f, 0xe62, 0x215d, + 0x2328, 0xffff7dc1, 0xffffacb9, 0x1483, 0x3da9, 0x74e7, 0x410e, 0x8253, + 0x4216, 0x1ff1, 0x4d3a, 0x3771, 0x817a, 0xffff73f2, 0x624e, 0xffffff16, + 0x3dc5, 0x1384, 0x377c, 0xf2, 0x4bf2, 0xffff74f7, 0x3060, 0x728d, + 0x2aee, 0x7273, 0xffff8fbf, 0x1106, 0xffff89df, 0xffffc920, 0x3582, 0x25fd, + 0xffffce73, 0xffffe0f1, 0x6219, 0xffffadc3, 0xfe9, 0xffff837f, 0xffff9048, 0x781f, + 0xffffb93b, 0x189f, 0xfffffb71, 0x16d2, 0xf5e, 0xffffb0bf, 0x62f8, 0x51e2, + 0x2c58, 0x5d59, 0xffffc837, 0x161a, 0xffffa164, 0x39c, 0x10a3, 0xffff79f8, + 0xfffffd31, 0xffffb4e3, 0xffffc92d, 0x6f16, 0xffffab27, 0xfffff0ba, 0x1be7, 0xffffb0a9, + 0xffffe906, 0x3a70, 0xffffaf42, 0x8b55, 0xffffa625, 0xffffca7e, 0xffff7fdb, 0x4078, + 0x5d41, 0x7798, 0xfffff767, 0xffff964e, 0xffffd7df, 0xffffa537, 0x3b4a, 0x35d0, + 0x5ba2, 0xffffd3b1, 0xffffb2e2, 0xffffd0e7, 0x3602, 0x72f1, 0xffff8dcc, 0xffff7ade, + 0xffffb1ee, 0xffffafa9, 0xffffdad2, 0xffffea6a, 0x6667, 0xffff941e, 0xfffff259, 0xfffff365, + 0x15be, 0x1280, 0xfffffcab, 0x8bb6, 0xffffbf10, 0xffffb64d, 0x408f, 0xfffff18a, + 0xffff9956, 0xffffa946, 0x71e3, 0xffffe7e8, 0xffff7ddc, 0xfffff570, 0x1c0f, 0xffffc10d, + 0x6e81, 0x367d, 0x2846, 0x635e, 0xffff74fc, 0x4b36, 0xfffff47b, 0x8b6b, + 0x7d7, 0xffffeb07, 0xfffff577, 0xffffb507, 0x42a5, 0x733c, 0xffffe9a2, 0xffffe885, + 0xfffff77a, 0xd37, 0x5f47, 0xffffc515, 0xfffffd88, 0xffffeb05, 0xffffcb7f, 0xffffa183, + 0x63df, 0x896f, 0x7fd9, 0x5f5, 0xffffc008, 0x29ac, 0x360e, 0x259d, + 0x7d1, 0xfffff226, 0x3d55, 0xffffabfd, 0x54b4, 0x3085, 0x59a1, 0x8a1e, + 0xffff85f4, 0xffffef3e, 0x49e5, 0xffffe51a, 0xfffffe96, 0xffffdea7, 0x328a, 0xffffa638, + 0x4ced, 0xffffb2d8, 0xffffec06, 0x854b, 0x46a, 0xfffff0e7, 0x8922, 0x8266, + 0x280a, 0x68a6, 0x5210, 0x6a2, 0x4142, 0xffffca2d, 0xffff9e3b, 0x5dd5, + 0xffffe648, 0xffffaac4, 0x22d9, 0xfffff89e, 0x4059, 0xffffab1f, 0xffffd230, 0xffff8d23, + 0x6cf, 0x6067, 0xffffed0e, 0xffff74f8, 0x58ee, 0xffff964e, 0xffffe204, 0x5e81, + 0xffff9d1e, 0xffffa77a, 0xffffef8a, 0xffff8f01, 0xffff7694, 0x6c0b, 0x7293, 0x72b2, + 0xffffa48b, 0xffffeb04, 0x1953, 0x1d, 0xffff888f, 0xffff7b0a, 0xffffa134, 0x7fe3, + 0xffffacc2, 0x471, 0x999, 0x4397, 0xfffff6a0, 0x7af2, 0xffffaac9, 0xffffe255, + 0x1170, 0xffffaaec, 0x2b92, 0xffff96a5, 0xffffd8b4, 0x3e4a, 0x44b0, 0xffffefdf, + 0xffffc299, 0xffff7360, 0xffff7ec4, 0x4be8, 0x2e91, 0xffffc8dc, 0xffffb89a, 0xffff8894, + 0xffff9818, 0xffffb4a1, 0x669, 0x892, 0x8c52, 0xffffe05d, 0x6fc3, 0xffff861c, + 0x19f4, 0x876d, 0x2260, 0xffff873f, 0x363e, 0xfffff093, 0x1434, 0x840b, + 0x648b, 0xffff8ebb, 0x1a62, 0x604e, 0x5874, 0x4304, 0x6f7e, 0xffff8c56, + 0x603b, 0xffffbaa1, 0xffffe654, 0xffff7ea9, 0xffff9791, 0xffffc749, 0xffffa7d9, 0x11e6, + 0xffffa58d, 0x6995, 0x4a1c, 0x362e, 0xffff9be4, 0x8266, 0x304, 0xffffbe5c, + 0xffffb4e6, 0xffffa022, 0xffff821f, 0x1170, 0xffff8639, 0xffffcbf0, 0x2364, 0x6c9a, + 0xffff8726, 0xffff9417, 0xffffea48, 0xffffb072, 0x5f33, 0x4896, 0xffff7762, 0x65e9, + 0xfffffd0a, 0x57f, 0x3b2c, 0xffff751d, 0xffff8c1f, 0xffffef92, 0x7117, 0xffffed28, + 0x8b9f, 0x764b, 0xfffff95d, 0xffff8346, 0xffffada7, 0xffffcd90, 0xffffa794, 0x22f6, + 0x5821, 0x2a57, 0xffff7575, 0xffffc0a9, 0xffffc11c, 0xffff954c, 0x921, 0xffffb22e, + 0x6fa4, 0x5f18, 0xffffcc0d, 0xffffd4eb, 0xffff8fd0, 0xffffd740, 0xffffc4d2, 0x5b17, + 0x7391, 0xffffdc3a, 0xffff923d, 0x4572, 0xffffaf19, 0xffffc9fb, 0xd70, 0x4c5d, + 0xffffb57d, 0x7eda, 0x60ce, 0x3db6, 0x6478, 0xffff81ca, 0xffff8e3f, 0xffffae43, + 0x8aad, 0xffff76a0, 0x2d2d, 0xffffc6ed, 0x89c4, 0xfffff0bd, 0xfffff634, 0xffff86cc, + 0x8934, 0x5c28, 0xfffff07a, 0xffffc810, 0xffffc4d5, 0xffff931a, 0x6cc1, 0xffff820d, + 0x4ad9, 0xffffe2ec, 0x5400, 0xffffce27, 0xffffa35b, 0xfffffa9a, 0xffffc984, 0x29db, + 0x198b, 0xb84, 0xffff7987, 0x43fc, 0x475f, 0x432d, 0xffffe7cc, 0xffff9245, + 0xffffef67, 0x60c2, 0xffffa260, 0x3a6a, 0x6739, 0x6685, 0x1b66, 0xa0, + 0xffff76b4, 0x2f5f, 0x8857, 0xffffa00d, 0xffff8549, 0x203e, 0x841f, 0x28a6, + 0x4193, 0xffffa1d6, 0x798f, 0x5d16, 0x279b, 0x9b1, 0xffffd61c, 0xffff9bce, + 0x3ecd, 0xffffc062, 0xffffac02, 0xffffac45, 0x150e, 0x7e22, 0xffffc92e, 0xffffe529, + 0x60da, 0x3950, 0x3d86, 0x1575, 0x182f, 0x7ee7, 0xffff8da9, 0x1a01, + 0x2e85, 0x7cd5, 0xffff8cc0, 0xffff730f, 0xffff8fe1, 0xffffeb15, 0x3bb7, 0x2d60, + 0xfffffaa0, 0xffffbd0f, 0x33b2, 0xffffd0be, 0xffffc2df, 0xffff7f81, 0x6400, 0xffffd43b, + 0xffffc823, 0x418c, 0xd2f, 0xffffa895, 0x8c3c, 0xffffbaeb, 0x7f05, 0xffffa145, + 0x660d, 0xffffa464, 0xfffff7ba, 0x8a12, 0x5b5a, 0xffffc222, 0xffff999e, 0xffffe91a, + 0x1bd9, 0xffffb0f5, 0x8202, 0x7319, 0xffff877a, 0xffff97b7, 0xffffc451, 0xffffa669, + 0x34b1, 0xffffbcda, 0xffffb333, 0x76fa, 0x4fb3, 0x1bfa, 0x8822, 0xffffcd78, + 0xffff7440, 0xfffffb6c, 0xffffb200, 0x4f19, 0x33ed, 0xffffb977, 0x26b, 0xfffff89d, + 0xffffa1de, 0x61ec, 0x1d9c, 0xffff76c0, 0xffffb7c1, 0xfffff027, 0x700c, 0xffff841a, + 0xfffffd62, 0xffff8baf, 0x4562, 0x7eab, 0x2ac8, 0xffffca3d, 0x6a8c, 0xffffc5c5, + 0xffff76cf, 0x454e, 0x44b2, 0x2e49, 0x551c, 0x4b86, 0x734c, 0xffff9db0, + 0x1d8, 0xffff9219, 0xffffe716, 0xffff7e4f, 0xffffcad7, 0x208, 0xffffa001, 0xffffe587, + 0xffffeed7, 0xffffc27b, 0xffffc41d, 0x4531, 0x7ee, 0xffff755f, 0xa10, 0x1d02, + 0xffff75fe, 0xffff9543, 0x237f, 0xffffabf2, 0xd2, 0xae9, 0x2785, 0xffff85c8, + 0xffff9b84, 0xffffc2d6, 0xffffe149, 0x28ae, 0xffff75f9, 0xffff9667, 0x5647, 0x76e9, + 0xfffff7f3, 0xffffa9ae, 0xffffc163, 0xffff8412, 0xfaf, 0x1cde, 0xffff888f, 0xffff7e2f, + 0xffffd400, 0xffff8602, 0x37de, 0xffffb80c, 0xffffd2e9, 0x11ba, 0xffffb448, 0xffff9253, + 0x603a, 0x71c9, 0x4d23, 0x48c7, 0xffffc84d, 0xffffe1fb, 0x47db, 0x1877, + 0x45af, 0xfffff561, 0xffffd599, 0x7c57, 0xffff8cd4, 0xffffbc8b, 0x61db, 0x37a0, + 0x1544, 0xffffca6a, 0x8d85, 0x768f, 0xffff897a, 0xffff923c, 0xffffecde, 0xfffff499, + 0x100c, 0x5097, 0x8dd1, 0x1d2c, 0xffffd766, 0x31a3, 0xffff9f7e, 0x31e8, + 0x2744, 0x8dad, 0xffffd73e, 0x33ab, 0x3fed, 0xfffff38c, 0xffffe07f, 0x7827, + 0xfffffc55, 0x6531, 0x526b, 0x2399, 0x3c8c, 0x4633, 0xffffaafa, 0x11da, + 0xfffffca9, 0xffff7c90, 0x4499, 0x3445, 0x12c4, 0x2210, 0xffffe1e1, 0x431b, + 0x45da, 0xffff72cf, 0xffffdae7, 0x6ee7, 0xffffb843, 0x7930, 0xfffffc7c, 0xffffda3e, + 0xffff89d1, 0x8d06, 0xe73, 0xffff82c9, 0xffffeeb8, 0xffffc7dc, 0x3e13, 0xffff9f2f, + 0xffff7e2a, 0xffff7eaf, 0x6cb0, 0x5077, 0xc26, 0xffff9fcb, 0xffff7e45, 0x1bc3, + 0x6cd7, 0x800e, 0x333f, 0xffffef38, 0x3294, 0x38c5, 0xffff9860, 0x7fe2, + 0x1846, 0xffffc870, 0x8798, 0xffffa794, 0x3433, 0x70a5, 0xffffe031, 0xffffbd5a, + 0x626c, 0xfffff816, 0x7b1, 0x83fc, 0xffff9362, 0x306, 0x7587, 0xffffdb69, + 0xffff89e4, 0x1da2, 0x5532, 0xfffffd49, 0xffffba57, 0xffff8941, 0xc84, 0x6b89, + 0xffffecd4, 0x2578, 0x8a3e, 0xffffbd94, 0xffff8bc6, 0x7a73, 0x5cfc, 0xffffa543, + 0x4605, 0xffffbde5, 0x8cfe, 0x150b, 0xffffd23e, 0xffffa042, 0xffff7b69, 0xfffff168, + 0x1c44, 0xffff72f5, 0xfffff3c2, 0xfffff9ed, 0xffffeca1, 0x2d48, 0xffff9bce, 0x272b, + 0xffffc260, 0xffff929d, 0x3cb9, 0x5c11, 0x5d4, 0xffff8ad7, 0x6aa9, 0xfffffb80, + 0x572b, 0x2cbd, 0x5e8a, 0xffffb586, 0xfffff8e7, 0x6f5b, 0x28ce, 0x11a, + 0x71f5, 0xfffff744, 0x1be2, 0xffff95cd, 0x6cef, 0xffffc7f6, 0x1ac3, 0x8c96, + 0xffff760f, 0xffffa1ba, 0x370, 0x3277, 0xffff817a, 0xffffcee6, 0x195e, 0xffff7ccb, + 0xffffca7b, 0xffff9d90, 0x540e, 0x6725, 0xffff75a3, 0x48a5, 0xffffada6, 0xfffffdad, + 0x32e4, 0x1e1e, 0xffffe0eb, 0xffffed3c, 0xfd, 0xffff9fbf, 0x4878, 0x8dbc, + 0x3ef3, 0xfffffcd0, 0x80e5, 0x77b5, 0x8b4b, 0x7003, 0xffffb759, 0x8938, + 0x4a57, 0xca9, 0x6783, 0x27ee, 0x2c7a, 0xffff8bf7, 0xffffe754, 0x2a23, + 0x60ea, 0xffffc6bc, 0xffffb024, 0x34b2, 0xffffe44f, 0x2f16, 0x3df3, 0x883c, + 0x3eb1, 0xffff81dd, 0x5e00, 0x7ae1, 0x62bc, 0xffffcb8d, 0xffffd0eb, 0x457f, + 0x6bb3, 0x72a2, 0xffffb521, 0xffff7d69, 0xffffd032, 0x4d2, 0xffff9dcb, 0xfffffd7d, + 0x44d, 0x3c01, 0x34ed, 0xfffff07f, 0x74a6, 0x894, 0x524d, 0xdb3, + 0xcb3, 0xffff9661, 0xffff9d9a, 0xffffdae6, 0xffffd8df, 0xffffe241, 0x14a9, 0xffff79ad, + 0x1d71, 0x17e9, 0xffffcee6, 0x58cc, 0xffffa52b, 0x7b08, 0xec7, 0x5a66, + 0xffff7f3c, 0xffffc522, 0x210d, 0x109c, 0x162d, 0x4654, 0xfffffee4, 0x1b68, + 0x7e7b, 0xffffb804, 0xffff9c77, 0xffffa259, 0xfffffcdc, 0xffffb126, 0x6f3e, 0x597e, + 0xffff8c8b, 0xffffb09a, 0x4d39, 0x8bc3, 0x1208, 0x63f, 0x7e6a, 0x3bb1, + 0x8dd9, 0x4cac, 0xffff803c, 0xffff9d29, 0xffffa2d6, 0x1a9a, 0x16fe, 0xffffc6c9, + 0x6ff1, 0xffffb441, 0xffffbdc5, 0xfcd, 0xffffe445, 0xffffa0f3, 0xffffef93, 0xffffdd4e, + 0x3fe8, 0x40a2, 0xffffeac0, 0x6f7d, 0xffff83d1, 0x459e, 0x6eee, 0x7da, + 0xffff9f26, 0xffff9da6, 0xffffb81c, 0x25c8, 0x32a6, 0x2351, 0xffff7450, 0xffff90f0, + 0x16ee, 0xffffa868, 0xffffa2cb, 0xffff79fc, 0xfffffe99, 0x6a31, 0x1a59, 0xffffbca9, + 0xffff8d29, 0xffffc840, 0xffffd7e8, 0xffff9128, 0xfffff92c, 0xffffd49d, 0xffffa0a4, 0x7533, + 0x748, 0x4245, 0x34bc, 0x366c, 0xffffc838, 0x3265, 0x8226, 0x4aca, + 0xffffe761, 0x19e, 0x46bb, 0xffffdafa, 0xffffdd98, 0xffffc1b8, 0x7aa8, 0xffffc744, + 0xffff7766, 0xffffeb0c, 0x675b, 0x573, 0x5b52, 0xffffd638, 0x49a1, 0x5235, + 0xffffcd48, 0xffff8960, 0xffff8468, 0xffffc6b1, 0xfffff7c1, 0x6995, 0x5eb4, 0xffffc196, + 0xffff7779, 0x6104, 0xffff8f5b, 0x2928, 0x6cf0, 0x1b93, 0xffffbdd9, 0x1ca5, + 0x81b, 0x64c3, 0xfffff230, 0xffffc185, 0xffffd191, 0xffff858e, 0x6eb8, 0xffffd904, + 0x89ca, 0xffff8102, 0xffffc709, 0x39e2, 0x5bde, 0x1e9e, 0xffffb9c8, 0x81c2, + 0xffffb753, 0xffff9bba, 0xfe5, 0xffffaabf, 0xffff82e0, 0xffffcc44, 0x22e0, 0x1053, + 0x6b07, 0x2522, 0x6316, 0x5ddf, 0xfffff8fe, 0xffff896b, 0x8a7d, 0xffff9398, + 0xffffa42f, 0x4f57, 0x71a, 0xffffef95, 0xffffb170, 0x12e9, 0xffff8147, 0xffffdc5c, + 0xffff9d76, 0x2a39, 0x2a4a, 0x2d76, 0xffffa31c, 0xffffafcf, 0xffffb76e, 0x617c, + 0xa00, 0xffff878f, 0xffff737a, 0x6f54, 0x7516, 0xffffbc9a, 0x39c8, 0x5bbe, + 0x4d20, 0x32b6, 0xffff8d2f, 0xffffcee7, 0x46ef, 0x3bdb, 0xffffc557, 0xffffe1a6, + 0xffff7a54, 0x6572, 0xffff9a6d, 0x7b59, 0x3be8, 0xffffd635, 0x1acd, 0xffffe77a, + 0xffffa8c9, 0x531c, 0xffff8a3a, 0xfffff65d, 0xb96, 0x49b8, 0x735b, 0x791, + 0x682b, 0xfffff0f6, 0x179e, 0xfffff2ef, 0x3992, 0xffffc2d8, 0xffffb85c, 0xffff9e2d, + 0xffffdc7a, 0x1202, 0xffff761e, 0xffffae43, 0xffffddc9, 0xffff8377, 0xffffd6dc, 0x124, + 0x493d, 0x2f55, 0xfffff8c8, 0x5f25, 0xfffff800, 0xffff738a, 0x3465, 0x1089, + 0x4ea3, 0xffff83ec, 0x4f50, 0xffffaac4, 0x1c54, 0x58c5, 0xffffe6ab, 0xffff8a2e, + 0x74b2, 0x6032, 0xfffff56b, 0x836c, 0xffff8f09, 0x8316, 0xffffeb3e, 0x257c, + 0xffffd7c8, 0x671f, 0x4eab, 0x1220, 0xffff7c40, 0x3c05, 0xffffd400, 0x841, + 0xffff7c1a, 0x5119, 0x371c, 0xffffb126, 0xffffa46d, 0xffff8f00, 0xfffffed8, 0x6db7, + 0x1608, 0xffff7c99, 0x72a6, 0x7cad, 0xffff7831, 0x810d, 0x79d5, 0x1b55, + 0xffffd273, 0x5d84, 0x5983, 0xffffff4a, 0x5005, 0x69bf, 0xffffe75f, 0xffffd029, + 0xffffe1e8, 0xffff9e76, 0xff2, 0xfffff4d4, 0xffffe108, 0xffffb618, 0xffffed8b, 0xd27, + 0x94d, 0x52ff, 0x8634, 0xffffa360, 0xffffffe3, 0xffffb0d8, 0xffffaaee, 0xfffff959, + 0xffffbdaf, 0xffffc563, 0x2506, 0x4a98, 0xfffff9bb, 0x4ad2, 0x25f4, 0xffff9987, + 0x5bf9, 0x8d03, 0x58d7, 0xffff988b, 0xffffe7b6, 0x1aeb, 0xffffdd88, 0xffffd037, + 0xffff9db8, 0xffff77f7, 0x693, 0x8863, 0xffff9329, 0xffffb19f, 0x5447, 0x2606, + 0x77dd, 0xffffbd47, 0xfffffb00, 0x4c00, 0xffff9169, 0x7d2a, 0x8548, 0xffffe574, + 0x44b, 0xffffe68c, 0xffff9738, 0x4689, 0x27f6, 0x5a2c, 0x37a7, 0x529d, + 0xffff7c73, 0x76f2, 0x242f, 0x8134, 0x30a8, 0x3ab2, 0xfffffe83, 0x3bd5, + 0xffffc9ed, 0xffff7be3, 0x6356, 0xffffab4b, 0x6d2d, 0xffffb6dc, 0x1d24, 0x6908, + 0x6aa6, 0x4fe3, 0xffffe221, 0xffff8985, 0x3389, 0x6062, 0x8700, 0x4834, + 0x8cba, 0x842c, 0x15dd, 0x86ac, 0xffffa5c2, 0x375c, 0xffffc3e1, 0x2517, + 0x2a44, 0xffffa391, 0xffffec55, 0xffff7bec, 0xffffb1e1, 0x5156, 0x7b17, 0xd57, + 0x962, 0x4e52, 0x3b2e, 0xffffab67, 0xffffda44, 0x69e8, 0xffff78ec, 0xffffd084, + 0xffff8488, 0x773a, 0x6c60, 0xffffa9c9, 0x6d4a, 0xfffffe96, 0xffffe0e0, 0x1bef, + 0xffffde02, 0xaae, 0xffff9a10, 0x557, 0x4da9, 0x867c, 0x1741, 0x42f8, + 0xffffd09b, 0xffffd2d1, 0xffffe212, 0xfffff266, 0x45ed, 0xffffe717, 0x6837, 0x76c1, + 0xfffffef7, 0x5baf, 0xffffbee3, 0xffff830d, 0xffffb4fa, 0x372b, 0xffffb440, 0xffff8e7e, + 0xffffa00d, 0xffffbb90, 0xffff92d7, 0xffffa723, 0xffffe18b, 0xfffffbe0, 0xffffdf88, 0xffff76d1, + 0xffffd2af, 0x3a01, 0x8c46, 0xfffff48e, 0xffff8ada, 0xffffb3f4, 0x46ba, 0xffffa696, + 0x4a04, 0x8cf1, 0x362f, 0xffffc320, 0x73d2, 0xffffa00f, 0xfffff6ad, 0x7269, + 0x695e, 0x4812, 0x3b16, 0x6442, 0xffffa02b, 0xffffc2c0, 0xffffe410, 0xffffb923, + 0x6012, 0xffffdcd3, 0xffffbdfe, 0xffff97be, 0x6ad6, 0xffffe081, 0xffff97e9, 0xffff8adf, + 0xd9e, 0xffff7e8f, 0xffffc9c6, 0x6a7e, 0x53b9, 0xffff7fb5, 0x8314, 0xffff81f5, + 0x1d86, 0x3e5d, 0xfffffd9d, 0x201e, 0xffffde6d, 0x2055, 0x7317, 0x167c, + 0xffffcfa0, 0xffff9bbc, 0xffffa8e0, 0x2d83, 0x5a8d, 0xffffb0bd, 0x3926, 0x669f, + 0x4b9e, 0x6345, 0x2c7, 0xffff91c9, 0xffff745a, 0x5091, 0x56a3, 0x6e45, + 0x31ac, 0xffff9847, 0xffffbb04, 0x617c, 0x1374, 0x8dd7, 0xffffe142, 0xffffeb42, + 0x9d4, 0xffff8b2d, 0x84fc, 0x3b6, 0x604a, 0xffffd453, 0xffffd691, 0xffff7927, + 0xc47, 0x169d, 0x70bb, 0x10d4, 0x6b25, 0xffff8965, 0xffffc874, 0xffff7571, + 0x2165, 0xffffbb50, 0xffff7623, 0xffffab6f, 0xfffff47a, 0xffffb87b, 0x14d1, 0xffffff82, + 0xffffe1b8, 0xf6b, 0xffff74f4, 0xffffefb6, 0xffff88c0, 0x2eec, 0xffffade2, 0xffffdcd2, + 0xffffb1cc, 0x334f, 0xffffc569, 0xffff8414, 0x8070, 0x7bfa, 0x8992, 0xffffcc6d, + 0xffffa65a, 0x251f, 0x8bbf, 0x2463, 0xffff74d2, 0xfffff0cf, 0xffffde9a, 0x4f4a, + 0xffff8446, 0xffffa4e2, 0x808a, 0xfffffadd, 0x723e, 0xffffd82d, 0x1f14, 0x8c71, + 0xffffdc75, 0x6c3c, 0x4435, 0x472f, 0xffff7252, 0x22e5, 0x19c0, 0x88aa, + 0xffffd423, 0xffff8758, 0x2758, 0xffffd33d, 0xffffe1bb, 0x83b3, 0x8535, 0xaa5, + 0x7864, 0x6b59, 0x2ab7, 0x7e5b, 0x6df6, 0x6f3e, 0xffff908a, 0xffffb6d4, + 0x4eca, 0xffffa83f, 0xffffff3f, 0xffff7a6a, 0xffff74aa, 0x37e9, 0xffff8a5e, 0xfffff391, + 0xffffc4c1, 0x36fb, 0x21e2, 0x623d, 0xffff7306, 0xfffff202, 0x39cb, 0xffffcd47, + 0x13b6, 0x630e, 0xffffa3e6, 0xffffeb86, 0x5eb8, 0xffff73c0, 0xfffffa42, 0x49fb, + 0xffffed95, 0x718f, 0xffff7e6a, 0x1914, 0xffffa5e9, 0x8cf1, 0x2ae3, 0xfffff9e8, + 0xffffec23, 0x697d, 0x5ab9, 0x77f0, 0xfffff222, 0x5ff0, 0xffffa34d, 0x82bc, + 0x5950, 0x13c1, 0x5a9b, 0x570c, 0x4992, 0x405c, 0x3ecd, 0xfffff886, + 0x1362, 0x1704, 0xffff87b3, 0xffffe31c, 0x7e6c, 0x27e7, 0x355a, 0xffff84c4, + 0xffffe078, 0xffffc000, 0xffffd37a, 0x2690, 0x130d, 0xffffd22b, 0xffffa6c1, 0x12dd, + 0x36db, 0x5507, 0xffff8c14, 0xffffb616, 0x71ab, 0xffffd884, 0xffff7ed4, 0x1871, + 0x212a, 0xffff8acf, 0x353, 0x3bca, 0x7cfc, 0xffff7a5d, 0x5990, 0x4bb, + 0xffff7606, 0x6328, 0x386, 0xffffd02b, 0xffffe3b6, 0xfffff0bb, 0x4b6f, 0x8dc, + 0xfffff3ea, 0x169c, 0x3ed8, 0xffffa125, 0x3c69, 0xfffffedb, 0x6c9b, 0x17de, + 0xffffb5f8, 0xef6, 0xfffffbc6, 0xffff82b9, 0xffff7a4e, 0x6193, 0x6994, 0xffffe6b5, + 0xffffdb01, 0x5c14, 0x68a8, 0x26a4, 0xffffb021, 0x7bcc, 0xffff9f05, 0x814, + 0x162c, 0xffffb3e7, 0x2c53, 0xffffc8e1, 0x6920, 0xffff7254, 0x6d49, 0xffffb4c2, + 0xffffcaca, 0xffffe1cd, 0xffffd576, 0xffffbad8, 0xffffc4db, 0xffff7f6b, 0x758b, 0x1f19, + 0x4407, 0x3b61, 0xffffa2ea, 0xfffff403, 0x26b, 0x6789, 0x5ca7, 0x3b3, + 0x458b, 0xffffd823, 0xffff83b7, 0x2dc6, 0xffffbd8d, 0xffff7964, 0x77a3, 0x18bd, + 0x7ada, 0xffffc92e, 0x32e2, 0xffffe36a, 0xffff79db, 0x6ca2, 0xffffafdb, 0xffffba78, + 0x23cb, 0xffffc5ad, 0xffffe3f4, 0x89d5, 0x86ee, 0x13ca, 0xfffff25b, 0x3ebb, + 0x680d, 0x628a, 0xffffce21, 0x44c, 0xffff7532, 0xffff72a6, 0xffff88d5, 0x8599, + 0xffffe7cf, 0xffffbeed, 0xffffbcf5, 0x675c, 0x481d, 0x6ac3, 0xffffc0ae, 0x4ce4, + 0x46ef, 0x2b3f, 0x47fd, 0x35f4, 0xc48, 0x3038, 0x7b9b, 0x302d, + 0xffff85f4, 0x6652, 0xffff7f44, 0xffffec9b, 0xffffedd2, 0x2863, 0x2faa, 0x8cf1, + 0xffffc4e8, 0xcb3, 0xffff925c, 0xffffc9c0, 0xffffad2f, 0x5eb1, 0x5697, 0x66bd, + 0xffff8080, 0xffff98b1, 0x2955, 0xffffcdbd, 0xffffd6d8, 0xffff84a6, 0xffffe29c, 0xffff9edd, + 0x391f, 0x625c, 0xffff8094, 0xffffbad3, 0xffff8b97, 0x7d06, 0xffffadce, 0x1036, + 0xffffcbd0, 0x3027, 0xfffff405, 0x3104, 0xffffd411, 0x614d, 0x426b, 0x410, + 0x3524, 0xffffddf3, 0x3c3b, 0x7663, 0x4d40, 0x7c3e, 0xffffa330, 0xffffbd4a, + 0xffffce53, 0x989, 0xffffddc9, 0xffff92ed, 0x4449, 0xffffa2d2, 0xfffff261, 0x5c84, + 0xfffff447, 0xfffff6c6, 0x4520, 0xffffa40d, 0xffffd253, 0xffffbf75, 0xffffaeea, 0x8c96, + 0xffff7c66, 0xffffc745, 0x572b, 0x5167, 0xffffdc8a, 0x46cc, 0x5b66, 0xffffd61c, + 0x3fc6, 0x7a63, 0xffffc4d8, 0xffffe8b4, 0xffffdc6a, 0x6f63, 0xffffd716, 0xffffbb46, + 0x7426, 0xffff7dde, 0x26f1, 0xffffcd18, 0x1776, 0x4d89, 0x20c5, 0x6457, + 0x371c, 0xffff8c94, 0xffff72e4, 0x7cc, 0x835b, 0xffffb776, 0xffff93e1, 0xffff83cd, + 0x7241, 0xffffcfc4, 0xffffbda6, 0x63f0, 0xffffaa19, 0x7cf5, 0xffff8f8d, 0x1942, + 0xffff87ae, 0x4e6d, 0xffff78d5, 0x6e8c, 0x3539, 0xffffc063, 0x73c, 0x76dc, + 0xfffff8ff, 0xffffb5a1, 0x19bf, 0xffff7694, 0xf15, 0xfffff136, 0xffff82b9, 0xffffcc83, + 0xffff88a4, 0xffffc7e0, 0xffff7256, 0xffffe068, 0x25b4, 0xffffed48, 0xffff8d7d, 0x5f8c, + 0x1892, 0xffffd1e5, 0xffff7417, 0x7ecc, 0xfffffb74, 0x8c0c, 0x4758, 0xffffc7d7, + 0xffffe764, 0xfffffe29, 0xffff88fa, 0xffffe66d, 0xffffdeb4, 0x2f2d, 0x646b, 0xffffce8c, + 0x3769, 0x3912, 0xffffe6fb, 0xffffc166, 0xffffce02, 0x4dc7, 0x80b5, 0xffffc70d, + 0xffffc36a, 0x30ea, 0x7441, 0x5fe4, 0xffff7812, 0xffffe92e, 0xffffcc86, 0xffffe27b, + 0x49e2, 0x71c0, 0xffffab47, 0xffff9c51, 0x7377, 0xfffffc50, 0x7be0, 0x13e0, + 0xffffe5f2, 0x2db1, 0x2610, 0xffff8258, 0xffff978f, 0x282b, 0x395, 0x1031, + 0xffffb66c, 0xffff749b, 0xffffbf6f, 0xffffa7e1, 0x12f1, 0xffffcfa7, 0xfffff7fd, 0x6a21, + 0x8a4d, 0x4ff5, 0x71be, 0x8096, 0x5502, 0x4f40, 0x81c5, 0x5a75, + 0xffff8d39, 0x1bc0, 0xffff7827, 0xa59, 0xffff9929, 0x8db3, 0x5df1, 0xfffff7b2, + 0x420a, 0x6544, 0x6509, 0x7451, 0x1e7f, 0x4f76, 0x315a, 0x3620, + 0x5091, 0x4403, 0xffffd3e4, 0x5c0c, 0x80c2, 0x36c4, 0x5107, 0xffff943d, + 0x6452, 0xffffad40, 0xffff9b98, 0x58ab, 0x27b3, 0xffff8be9, 0xffffa656, 0xffffa5f8, + 0xffffbd22, 0xffff73fd, 0x2758, 0xffffa764, 0x62ed, 0xffff90c5, 0x1e51, 0xffff897b, + 0xffff82b3, 0x2d25, 0x76ad, 0xffff7f02, 0xfffffa89, 0x2d4f, 0x2ab, 0x5685, + 0x8ce1, 0xfffff7de, 0x5522, 0xffffbc64, 0xffff9e79, 0xffffef8b, 0xffff84f0, 0xffff933c, + 0x102e, 0x8bc, 0x5a44, 0xfffffe4f, 0xffffaed9, 0x7aee, 0xffffa2ae, 0x12e0, + 0x7c7b, 0x3a66, 0xffffb1f5, 0xffffa575, 0x3bf3, 0xffffe14f, 0xffffedca, 0xfffffb3d, + 0xffff8279, 0x296b, 0x8bc7, 0xc1b, 0xffffea63, 0x65cd, 0xffffa851, 0x878f, + 0xe37, 0x501a, 0x581c, 0x16c3, 0x6279, 0xffff9e12, 0xfffffc2c, 0x7d4c, + 0x4c95, 0xffffced3, 0xffff8b07, 0xffff87b0, 0xffffa928, 0x6ce2, 0xffff8bc1, 0xffff7fab, + 0x5249, 0xffffbf8f, 0x8074, 0x1ab9, 0xffffe2ed, 0xffffebbb, 0xfffffd25, 0x474f, + 0xffffe439, 0xffffe258, 0xffffb947, 0xfffffa1b, 0xffff90ea, 0x8134, 0x6eed, 0xffffc392, + 0xffff934a, 0xffffb921, 0xd9a, 0x6581, 0x37f2, 0xffffe672, 0xffffafd9, 0x30eb, + 0xffffa08e, 0xffffa39d, 0xffff9657, 0x26d0, 0xffffb97f, 0x5df, 0xffff9257, 0x3a34, + 0xfffffd43, 0xffffc367, 0x8bf0, 0x186, 0x1692, 0x5420, 0x7d2c, 0x83dd, + 0x4ad1, 0xfffffc05, 0x67a4, 0x7b06, 0xffffacd2, 0x7c2, 0x4f9a, 0x586a, + 0xffffdacd, 0xfffff2e4, 0xffffa666, 0xffffa2f2, 0xffffdd98, 0x50ec, 0xffffec94, 0xffffe01d, + 0xffffe6a5, 0x2b32, 0xffff9128, 0xffffba30, 0xffff82ba, 0xffffe9fc, 0xffffe738, 0x20fa, + 0x3c1b, 0xffffce2f, 0x533, 0x8bdf, 0x79be, 0xffff86e9, 0x82cf, 0xffffab3e, + 0x591d, 0xfffffeb2, 0xffff7424, 0x8932, 0xffffe0f9, 0xffff9d92, 0xffff7b20, 0x2495, + 0x879d, 0x85a3, 0x6f1f, 0x1cf2, 0x1220, 0x65c2, 0xffffc751, 0xffffa10f, + 0xffffa5df, 0xffffd1fd, 0xffffac41, 0xffff73d2, 0xffffc38e, 0xffffa17a, 0xffff9f58, 0x6600, + 0xffff95d8, 0x8400, 0x38dc, 0xffff9844, 0xffff9378, 0x5fdc, 0x3ed8, 0xb4b, + 0xffffb1fd, 0xffff72a1, 0x6313, 0x3acb, 0xffffd03c, 0xffffe6bb, 0x59f7, 0x5a17, + 0x20c2, 0xffffddc9, 0x60e0, 0xffffb1ff, 0x7867, 0xffffad34, 0x8cb0, 0xffff89ed, + 0xffff9cf1, 0x57ed, 0x186b, 0x85bb, 0x1ed9, 0xffffd073, 0x755, 0x39d, + 0xffffe507, 0x5144, 0x3bdd, 0xffff748f, 0x5a22, 0x2f8c, 0xffffe210, 0xffff8285, + 0x2ffa, 0x17c1, 0x11b5, 0xffffa5ff, 0x3950, 0x6b7f, 0xffffc962, 0xfffff345, + 0x80c6, 0xffffbb45, 0xffffac73, 0xffff941e, 0xffff9774, 0xffffe733, 0x35cb, 0xffffb0e4, + 0x8a90, 0x296d, 0xffffea99, 0xffffb292, 0x3778, 0xffffff27, 0x3422, 0x2bd4, + 0xffffb0ac, 0xffffda12, 0x3f00, 0x36ed, 0x38ec, 0xffff9a13, 0xffff9d40, 0x5ec5, + 0x5a1b, 0x5a7d, 0xffffccab, 0xfffffcd1, 0xffffa33b, 0xffff9848, 0x31d8, 0x2224, + 0x2eb0, 0xffffa658, 0xffff9e76, 0xffffd97a, 0x65a8, 0xffff8029, 0xf42, 0x2c21 +}; + diff --git a/plugins/wma/libwma/wmadec.h b/plugins/wma/libwma/wmadec.h new file mode 100644 index 00000000..f5a773b0 --- /dev/null +++ b/plugins/wma/libwma/wmadec.h @@ -0,0 +1,197 @@ +/* + * WMA compatible decoder + * Copyright (c) 2002 The FFmpeg Project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _WMADEC_H +#define _WMADEC_H + +#include <libasf/asf.h> +#include "ffmpeg_get_bits.h" +#include "types.h" + +//#define TRACE +/* size of blocks */ +#define BLOCK_MIN_BITS 7 +#define BLOCK_MAX_BITS 11 +#define BLOCK_MAX_SIZE (1 << BLOCK_MAX_BITS) + +#define BLOCK_NB_SIZES (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) + +/* XXX: find exact max size */ +#define HIGH_BAND_MAX_SIZE 16 + +#define NB_LSP_COEFS 10 + +/* XXX: is it a suitable value ? */ +#define MAX_CODED_SUPERFRAME_SIZE 16384 + +#define M_PI 3.14159265358979323846 + +#define M_PI_F 0x3243f // in fixed 32 format +#define TWO_M_PI_F 0x6487f //in fixed 32 + +#define MAX_CHANNELS 2 + +#define NOISE_TAB_SIZE 8192 + +#define LSP_POW_BITS 7 + + +#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250) +/* PP5022/24 and MCF5250 have 128KB of IRAM. 80KB are allocated for codecs */ +#define IBSS_ATTR_WMA_LARGE_IRAM IBSS_ATTR +#define IBSS_ATTR_WMA_XL_IRAM +#define ICONST_ATTR_WMA_XL_IRAM + +#elif defined(CPU_S5L870X) +/* S5L870x has even more IRAM. Use it. */ +#define IBSS_ATTR_WMA_LARGE_IRAM IBSS_ATTR +#define IBSS_ATTR_WMA_XL_IRAM IBSS_ATTR +#define ICONST_ATTR_WMA_XL_IRAM ICONST_ATTR + +#else +/* other PP's and MCF5249 have 96KB of IRAM */ +#define IBSS_ATTR_WMA_LARGE_IRAM +#define IBSS_ATTR_WMA_XL_IRAM +#define ICONST_ATTR_WMA_XL_IRAM + +#endif + + +#define VLCBITS 7 /*7 is the lowest without glitching*/ +#define VLCMAX ((22+VLCBITS-1)/VLCBITS) + +#define EXPVLCBITS 7 +#define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS) + +#define HGAINVLCBITS 9 +#define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS) + + +typedef struct CoefVLCTable +{ + int n; /* total number of codes */ + const uint32_t *huffcodes; /* VLC bit values */ + const uint8_t *huffbits; /* VLC bit size */ + const uint16_t *levels; /* table to build run/level tables */ +} +CoefVLCTable; + +/* Define MEM_ALIGN_ATTR which may be used to align e.g. buffers for faster + * access. */ +#if defined(CPU_ARM) + /* Use ARMs cache alignment. */ + #define MEM_ALIGN_ATTR CACHEALIGN_ATTR + #define MEM_ALIGN_SIZE CACHEALIGN_SIZE +#elif defined(CPU_COLDFIRE) + /* Use fixed alignment of 16 bytes. Speed up only for 'movem' in DRAM. */ + #define MEM_ALIGN_ATTR __attribute__((aligned(16))) + #define MEM_ALIGN_SIZE 16 +#else + /* Align pointer size */ + #define MEM_ALIGN_ATTR __attribute__((aligned(sizeof(intptr_t)))) + #define MEM_ALIGN_SIZE sizeof(intptr_t) +#endif + +typedef struct WMADecodeContext +{ + GetBitContext gb; + + int nb_block_sizes; /* number of block sizes */ + + int sample_rate; + int nb_channels; + int bit_rate; + int version; /* 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2) */ + int block_align; + int use_bit_reservoir; + int use_variable_block_len; + int use_exp_vlc; /* exponent coding: 0 = lsp, 1 = vlc + delta */ + int use_noise_coding; /* true if perceptual noise is added */ + int byte_offset_bits; + VLC exp_vlc; + int exponent_sizes[BLOCK_NB_SIZES]; + uint16_t exponent_bands[BLOCK_NB_SIZES][25]; + int high_band_start[BLOCK_NB_SIZES]; /* index of first coef in high band */ + int coefs_start; /* first coded coef */ + int coefs_end[BLOCK_NB_SIZES]; /* max number of coded coefficients */ + int exponent_high_sizes[BLOCK_NB_SIZES]; + int exponent_high_bands[BLOCK_NB_SIZES][HIGH_BAND_MAX_SIZE]; + VLC hgain_vlc; + + /* coded values in high bands */ + int high_band_coded[MAX_CHANNELS][HIGH_BAND_MAX_SIZE]; + int high_band_values[MAX_CHANNELS][HIGH_BAND_MAX_SIZE]; + + /* there are two possible tables for spectral coefficients */ + VLC coef_vlc[2]; + uint16_t *run_table[2]; + uint16_t *level_table[2]; + /* frame info */ + int frame_len; /* frame length in samples */ + int frame_len_bits; /* frame_len = 1 << frame_len_bits */ + + /* block info */ + int reset_block_lengths; + int block_len_bits; /* log2 of current block length */ + int next_block_len_bits; /* log2 of next block length */ + int prev_block_len_bits; /* log2 of prev block length */ + int block_len; /* block length in samples */ + int block_num; /* block number in current frame */ + int block_pos; /* current position in frame */ + uint8_t ms_stereo; /* true if mid/side stereo mode */ + uint8_t channel_coded[MAX_CHANNELS]; /* true if channel is coded */ + int exponents_bsize[MAX_CHANNELS]; // log2 ratio frame/exp. length + fixed32 exponents[MAX_CHANNELS][BLOCK_MAX_SIZE] MEM_ALIGN_ATTR; + fixed32 max_exponent[MAX_CHANNELS]; + int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE]; + fixed32 coefs[MAX_CHANNELS][BLOCK_MAX_SIZE]; + fixed32 *windows[BLOCK_NB_SIZES]; + /* output buffer for one frame and the last for IMDCT windowing */ + fixed32 frame_out[MAX_CHANNELS][BLOCK_MAX_SIZE*2]; + + /* last frame info */ + uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4] MEM_ALIGN_ATTR; /* padding added */ + int last_bitoffset; + int last_superframe_len; + fixed32 *noise_table; + int noise_index; + fixed32 noise_mult; /* XXX: suppress that and integrate it in the noise array */ + /* lsp_to_curve tables */ + fixed32 lsp_cos_table[BLOCK_MAX_SIZE] MEM_ALIGN_ATTR; + void *lsp_pow_m_table1; + void *lsp_pow_m_table2; + + /* State of current superframe decoding */ + int bit_offset; + int nb_frames; + int current_frame; + +#ifdef TRACE + + int frame_count; +#endif +} +WMADecodeContext; + +int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx); +int wma_decode_superframe_init(WMADecodeContext* s, + const uint8_t *buf, int buf_size); +int wma_decode_superframe_frame(WMADecodeContext* s, + const uint8_t *buf, int buf_size); +#endif diff --git a/plugins/wma/libwma/wmadeci.c b/plugins/wma/libwma/wmadeci.c new file mode 100644 index 00000000..d7a6f9ae --- /dev/null +++ b/plugins/wma/libwma/wmadeci.c @@ -0,0 +1,1480 @@ +/* + * WMA compatible decoder + * Copyright (c) 2002 The FFmpeg Project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file wmadec.c + * WMA compatible decoder. + */ + +#include <libasf/asf.h> +#include "wmadec.h" +#include "wmafixed.h" +#include "wmadata.h" + +#define trace(...) { fprintf (stderr, __VA_ARGS__); } +//#define trace(fmt,...) +#define DEBUGF trace + +static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len); + +/*declarations of statically allocated variables used to remove malloc calls*/ + +# define IBSS_ATTR + +/*MDCT reconstruction windows*/ +static fixed32 stat0[2048] IBSS_ATTR_WMA_XL_IRAM MEM_ALIGN_ATTR; +static fixed32 stat1[1024] IBSS_ATTR_WMA_XL_IRAM MEM_ALIGN_ATTR; +static fixed32 stat2[ 512] IBSS_ATTR_WMA_XL_IRAM MEM_ALIGN_ATTR; +static fixed32 stat3[ 256] IBSS_ATTR_WMA_XL_IRAM MEM_ALIGN_ATTR; +static fixed32 stat4[ 128] IBSS_ATTR_WMA_XL_IRAM MEM_ALIGN_ATTR; + +/*VLC lookup tables*/ +static uint16_t *runtabarray[2]; +static uint16_t *levtabarray[2]; + +static uint16_t runtab_big[1336] MEM_ALIGN_ATTR; +static uint16_t runtab_small[1072] MEM_ALIGN_ATTR; +static uint16_t levtab_big[1336] MEM_ALIGN_ATTR; +static uint16_t levtab_small[1072] MEM_ALIGN_ATTR; + +#define VLCBUF1SIZE 4598 +#define VLCBUF2SIZE 3574 +#define VLCBUF3SIZE 360 +#define VLCBUF4SIZE 540 + +/*putting these in IRAM actually makes PP slower*/ + +static VLC_TYPE vlcbuf1[VLCBUF1SIZE][2] IBSS_ATTR_WMA_XL_IRAM MEM_ALIGN_ATTR; +static VLC_TYPE vlcbuf2[VLCBUF2SIZE][2] MEM_ALIGN_ATTR; +/* This buffer gets reused for lsp tables */ +static VLC_TYPE vlcbuf3[VLCBUF3SIZE][2] MEM_ALIGN_ATTR; +static VLC_TYPE vlcbuf4[VLCBUF4SIZE][2] MEM_ALIGN_ATTR; + + + + +/** + * Apply MDCT window and add into output. + * + * We ensure that when the windows overlap their squared sum + * is always 1 (MDCT reconstruction rule). + * + * The Vorbis I spec has a great diagram explaining this process. + * See section 1.3.2.3 of http://xiph.org/vorbis/doc/Vorbis_I_spec.html + */ + static void wma_window(WMADecodeContext *s, fixed32 *in, fixed32 *out) + { + //float *in = s->output; + int block_len, bsize, n; + + /* left part */ + + /* previous block was larger, so we'll use the size of the current + * block to set the window size*/ + if (s->block_len_bits <= s->prev_block_len_bits) { + block_len = s->block_len; + bsize = s->frame_len_bits - s->block_len_bits; + + vector_fmul_add_add(out, in, s->windows[bsize], block_len); + + } else { + /*previous block was smaller or the same size, so use it's size to set the window length*/ + block_len = 1 << s->prev_block_len_bits; + /*find the middle of the two overlapped blocks, this will be the first overlapped sample*/ + n = (s->block_len - block_len) / 2; + bsize = s->frame_len_bits - s->prev_block_len_bits; + + vector_fmul_add_add(out+n, in+n, s->windows[bsize], block_len); + + memcpy(out+n+block_len, in+n+block_len, n*sizeof(fixed32)); + } + /* Advance to the end of the current block and prepare to window it for the next block. + * Since the window function needs to be reversed, we do it backwards starting with the + * last sample and moving towards the first + */ + out += s->block_len; + in += s->block_len; + + /* right part */ + if (s->block_len_bits <= s->next_block_len_bits) { + block_len = s->block_len; + bsize = s->frame_len_bits - s->block_len_bits; + + vector_fmul_reverse(out, in, s->windows[bsize], block_len); + + } else { + block_len = 1 << s->next_block_len_bits; + n = (s->block_len - block_len) / 2; + bsize = s->frame_len_bits - s->next_block_len_bits; + + memcpy(out, in, n*sizeof(fixed32)); + + vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len); + + memset(out+n+block_len, 0, n*sizeof(fixed32)); + } + } + + + + +/* XXX: use same run/length optimization as mpeg decoders */ +static void init_coef_vlc(VLC *vlc, + uint16_t **prun_table, uint16_t **plevel_table, + const CoefVLCTable *vlc_table, int tab) +{ + int n = vlc_table->n; + const uint8_t *table_bits = vlc_table->huffbits; + const uint32_t *table_codes = vlc_table->huffcodes; + const uint16_t *levels_table = vlc_table->levels; + uint16_t *run_table, *level_table; + const uint16_t *p; + int i, l, j, level; + + + init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, INIT_VLC_USE_NEW_STATIC); + + run_table = runtabarray[tab]; + level_table= levtabarray[tab]; + + p = levels_table; + i = 2; + level = 1; + while (i < n) + { + l = *p++; + for(j=0;j<l;++j) + { + run_table[i] = j; + level_table[i] = level; + ++i; + } + ++level; + } + *prun_table = run_table; + *plevel_table = level_table; +} + +const uint8_t ff_log2_tab[256]={ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + + +#define av_log2 av_log2_c +static inline av_const int av_log2_c(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + + +int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) +{ + + int i, flags2; + fixed32 *window; + uint8_t *extradata; + fixed64 bps1; + fixed32 high_freq; + fixed64 bps; + int sample_rate1; + int coef_vlc_table; + // int filehandle; + #ifdef CPU_COLDFIRE + coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); + #endif + + /*clear stereo setting to avoid glitches when switching stereo->mono*/ + s->channel_coded[0]=0; + s->channel_coded[1]=0; + s->ms_stereo=0; + + s->sample_rate = wfx->rate; + s->nb_channels = wfx->channels; + s->bit_rate = wfx->bitrate; + s->block_align = wfx->blockalign; + + if (wfx->codec_id == ASF_CODEC_ID_WMAV1) { + s->version = 1; + } else if (wfx->codec_id == ASF_CODEC_ID_WMAV2 ) { + s->version = 2; + } else { + /*one of those other wma flavors that don't have GPLed decoders */ + return -1; + } + + /* extract flag infos */ + flags2 = 0; + extradata = wfx->data; + if (s->version == 1 && wfx->datalen >= 4) { + flags2 = extradata[2] | (extradata[3] << 8); + }else if (s->version == 2 && wfx->datalen >= 6){ + flags2 = extradata[4] | (extradata[5] << 8); + } + s->use_exp_vlc = flags2 & 0x0001; + s->use_bit_reservoir = flags2 & 0x0002; + s->use_variable_block_len = flags2 & 0x0004; + + /* compute MDCT block size */ + if (s->sample_rate <= 16000){ + s->frame_len_bits = 9; + }else if (s->sample_rate <= 22050 || + (s->sample_rate <= 32000 && s->version == 1)){ + s->frame_len_bits = 10; + }else{ + s->frame_len_bits = 11; + } + s->frame_len = 1 << s->frame_len_bits; + if (s-> use_variable_block_len) + { + int nb_max, nb; + nb = ((flags2 >> 3) & 3) + 1; + if ((s->bit_rate / s->nb_channels) >= 32000) + { + nb += 2; + } + nb_max = s->frame_len_bits - BLOCK_MIN_BITS; //max is 11-7 + if (nb > nb_max) + nb = nb_max; + s->nb_block_sizes = nb + 1; + } + else + { + s->nb_block_sizes = 1; + } + + /* init rate dependant parameters */ + s->use_noise_coding = 1; + high_freq = itofix64(s->sample_rate) >> 1; + + + /* if version 2, then the rates are normalized */ + sample_rate1 = s->sample_rate; + if (s->version == 2) + { + if (sample_rate1 >= 44100) + sample_rate1 = 44100; + else if (sample_rate1 >= 22050) + sample_rate1 = 22050; + else if (sample_rate1 >= 16000) + sample_rate1 = 16000; + else if (sample_rate1 >= 11025) + sample_rate1 = 11025; + else if (sample_rate1 >= 8000) + sample_rate1 = 8000; + } + + fixed64 tmp = itofix64(s->bit_rate); + fixed64 tmp2 = itofix64(s->nb_channels * s->sample_rate); + bps = fixdiv64(tmp, tmp2); + fixed64 tim = bps * s->frame_len; + fixed64 tmpi = fixdiv64(tim,itofix64(8)); + s->byte_offset_bits = av_log2(fixtoi64(tmpi+0x8000)) + 2; + + /* compute high frequency value and choose if noise coding should + be activated */ + bps1 = bps; + if (s->nb_channels == 2) + bps1 = fixmul32(bps,0x1999a); + if (sample_rate1 == 44100) + { + if (bps1 >= 0x9c29) + s->use_noise_coding = 0; + else + high_freq = fixmul32(high_freq,0x6666); + } + else if (sample_rate1 == 22050) + { + if (bps1 >= 0x128f6) + s->use_noise_coding = 0; + else if (bps1 >= 0xb852) + high_freq = fixmul32(high_freq,0xb333); + else + high_freq = fixmul32(high_freq,0x999a); + } + else if (sample_rate1 == 16000) + { + if (bps > 0x8000) + high_freq = fixmul32(high_freq,0x8000); + else + high_freq = fixmul32(high_freq,0x4ccd); + } + else if (sample_rate1 == 11025) + { + high_freq = fixmul32(high_freq,0xb333); + } + else if (sample_rate1 == 8000) + { + if (bps <= 0xa000) + { + high_freq = fixmul32(high_freq,0x8000); + } + else if (bps > 0xc000) + { + s->use_noise_coding = 0; + } + else + { + high_freq = fixmul32(high_freq,0xa666); + } + } + else + { + if (bps >= 0xcccd) + { + high_freq = fixmul32(high_freq,0xc000); + } + else if (bps >= 0x999a) + { + high_freq = fixmul32(high_freq,0x999a); + } + else + { + high_freq = fixmul32(high_freq,0x8000); + } + } + + /* compute the scale factor band sizes for each MDCT block size */ + { + int a, b, pos, lpos, k, block_len, i, j, n; + const uint8_t *table; + + if (s->version == 1) + { + s->coefs_start = 3; + } + else + { + s->coefs_start = 0; + } + for(k = 0; k < s->nb_block_sizes; ++k) + { + block_len = s->frame_len >> k; + + if (s->version == 1) + { + lpos = 0; + for(i=0;i<25;++i) + { + a = wma_critical_freqs[i]; + b = s->sample_rate; + pos = ((block_len * 2 * a) + (b >> 1)) / b; + if (pos > block_len) + pos = block_len; + s->exponent_bands[0][i] = pos - lpos; + if (pos >= block_len) + { + ++i; + break; + } + lpos = pos; + } + s->exponent_sizes[0] = i; + } + else + { + /* hardcoded tables */ + table = NULL; + a = s->frame_len_bits - BLOCK_MIN_BITS - k; + if (a < 3) + { + if (s->sample_rate >= 44100) + table = exponent_band_44100[a]; + else if (s->sample_rate >= 32000) + table = exponent_band_32000[a]; + else if (s->sample_rate >= 22050) + table = exponent_band_22050[a]; + } + if (table) + { + n = *table++; + for(i=0;i<n;++i) + s->exponent_bands[k][i] = table[i]; + s->exponent_sizes[k] = n; + } + else + { + j = 0; + lpos = 0; + for(i=0;i<25;++i) + { + a = wma_critical_freqs[i]; + b = s->sample_rate; + pos = ((block_len * 2 * a) + (b << 1)) / (4 * b); + pos <<= 2; + if (pos > block_len) + pos = block_len; + if (pos > lpos) + s->exponent_bands[k][j++] = pos - lpos; + if (pos >= block_len) + break; + lpos = pos; + } + s->exponent_sizes[k] = j; + } + } + + /* max number of coefs */ + s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; + /* high freq computation */ + + fixed32 tmp1 = high_freq*2; /* high_freq is a fixed32!*/ + fixed32 tmp2=itofix32(s->sample_rate>>1); + s->high_band_start[k] = fixtoi32( fixdiv32(tmp1, tmp2) * (block_len>>1) +0x8000); + + /* + s->high_band_start[k] = (int)((block_len * 2 * high_freq) / + s->sample_rate + 0.5);*/ + + n = s->exponent_sizes[k]; + j = 0; + pos = 0; + for(i=0;i<n;++i) + { + int start, end; + start = pos; + pos += s->exponent_bands[k][i]; + end = pos; + if (start < s->high_band_start[k]) + start = s->high_band_start[k]; + if (end > s->coefs_end[k]) + end = s->coefs_end[k]; + if (end > start) + s->exponent_high_bands[k][j++] = end - start; + } + s->exponent_high_sizes[k] = j; + } + } + + /* ffmpeg uses malloc to only allocate as many window sizes as needed. + * However, we're really only interested in the worst case memory usage. + * In the worst case you can have 5 window sizes, 128 doubling up 2048 + * Smaller windows are handled differently. + * Since we don't have malloc, just statically allocate this + */ + fixed32 *temp[5]; + temp[0] = stat0; + temp[1] = stat1; + temp[2] = stat2; + temp[3] = stat3; + temp[4] = stat4; + + /* init MDCT windows : simple sinus window */ + for(i = 0; i < s->nb_block_sizes; i++) + { + int n, j; + fixed32 alpha; + n = 1 << (s->frame_len_bits - i); + window = temp[i]; + + /* this calculates 0.5/(2*n) */ + alpha = (1<<15)>>(s->frame_len_bits - i+1); + for(j=0;j<n;++j) + { + fixed32 j2 = itofix32(j) + 0x8000; + /*alpha between 0 and pi/2*/ + window[j] = fsincos(fixmul32(j2,alpha)<<16, 0); + } + s->windows[i] = window; + + } + + s->reset_block_lengths = 1; + + if (s->use_noise_coding) /* init the noise generator */ + { + /* LSP values are simply 2x the EXP values */ + if (s->use_exp_vlc) + { + s->noise_mult = 0x51f; + /*unlikely, but we may have previoiusly used this table for LSP, + so halve the values if needed*/ + if(noisetable_exp[0] == 0x0a) { + for (i=0;i<NOISE_TAB_SIZE;++i) + noisetable_exp[i] >>= 1; + } + s->noise_table = noisetable_exp; + } + else + { + s->noise_mult = 0xa3d; + /*check that we haven't already doubled this table*/ + if(noisetable_exp[0] == 0x5) { + for (i=0;i<NOISE_TAB_SIZE;++i) + noisetable_exp[i] <<= 1; + } + s->noise_table = noisetable_exp; + } +#if 0 +/*TODO: Rockbox has a dither function. Consider using it for noise coding*/ + +/* We use a lookup table computered in advance, so no need to do this*/ + { + unsigned int seed; + fixed32 norm; + seed = 1; + norm = 0; // PJJ: near as makes any diff to 0! + for (i=0;i<NOISE_TAB_SIZE;++i) + { + seed = seed * 314159 + 1; + s->noise_table[i] = itofix32((int)seed) * norm; + } + } +#endif + + s->hgain_vlc.table = vlcbuf4; + s->hgain_vlc.table_allocated = VLCBUF4SIZE; + init_vlc(&s->hgain_vlc, HGAINVLCBITS, sizeof(hgain_huffbits), + hgain_huffbits, 1, 1, + hgain_huffcodes, 2, 2, INIT_VLC_USE_NEW_STATIC); + } + + if (s->use_exp_vlc) + { + + s->exp_vlc.table = vlcbuf3; + s->exp_vlc.table_allocated = VLCBUF3SIZE; + + init_vlc(&s->exp_vlc, EXPVLCBITS, sizeof(scale_huffbits), + scale_huffbits, 1, 1, + scale_huffcodes, 4, 4, INIT_VLC_USE_NEW_STATIC); + } + else + { + wma_lsp_to_curve_init(s, s->frame_len); + } + + /* choose the VLC tables for the coefficients */ + coef_vlc_table = 2; + if (s->sample_rate >= 32000) + { + if (bps1 < 0xb852) + coef_vlc_table = 0; + else if (bps1 < 0x128f6) + coef_vlc_table = 1; + } + + /* since the coef2 table is the biggest and that has index 2 in coef_vlcs + it's safe to always assign like this */ + runtabarray[0] = runtab_big; runtabarray[1] = runtab_small; + levtabarray[0] = levtab_big; levtabarray[1] = levtab_small; + + s->coef_vlc[0].table = vlcbuf1; + s->coef_vlc[0].table_allocated = VLCBUF1SIZE; + s->coef_vlc[1].table = vlcbuf2; + s->coef_vlc[1].table_allocated = VLCBUF2SIZE; + + + init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0], + &coef_vlcs[coef_vlc_table * 2], 0); + init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], + &coef_vlcs[coef_vlc_table * 2 + 1], 1); + + s->last_superframe_len = 0; + s->last_bitoffset = 0; + + return 0; +} + + +/* compute x^-0.25 with an exponent and mantissa table. We use linear + interpolation to reduce the mantissa table size at a small speed + expense (linear interpolation approximately doubles the number of + bits of precision). */ +static inline fixed32 pow_m1_4(WMADecodeContext *s, fixed32 x) +{ + union { + float f; + unsigned int v; + } u, t; + unsigned int e, m; + fixed32 a, b; + + u.f = fixtof64(x); + e = u.v >> 23; + m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1); + /* build interpolation scale: 1 <= t < 2. */ + t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23); + a = ((fixed32*)s->lsp_pow_m_table1)[m]; + b = ((fixed32*)s->lsp_pow_m_table2)[m]; + + /* lsp_pow_e_table contains 32.32 format */ + /* TODO: Since we're unlikely have value that cover the whole + * IEEE754 range, we probably don't need to have all possible exponents */ + + return (lsp_pow_e_table[e] * (a + fixmul32(b, ftofix32(t.f))) >>32); +} + +static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len) +{ + fixed32 wdel, a, b, temp2; + int i; + + wdel = fixdiv32(itofix32(1), itofix32(frame_len)); + for (i=0; i<frame_len; ++i) + { + /* TODO: can probably reuse the trig_init values here */ + fsincos((wdel*i)<<15, &temp2); + /* get 3 bits headroom + 1 bit from not doubleing the values */ + s->lsp_cos_table[i] = temp2>>3; + + } + /* NOTE: these two tables are needed to avoid two operations in + pow_m1_4 */ + b = itofix32(1); + int ix = 0; + + s->lsp_pow_m_table1 = &vlcbuf3[0]; + s->lsp_pow_m_table2 = &vlcbuf3[1<<LSP_POW_BITS]; + + /*double check this later*/ + for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) + { + a = pow_a_table[ix++]<<4; + ((fixed32*)s->lsp_pow_m_table1)[i] = 2 * a - b; + ((fixed32*)s->lsp_pow_m_table2)[i] = b - a; + b = a; + } + +} + +/* NOTE: We use the same code as Vorbis here */ +/* XXX: optimize it further with SSE/3Dnow */ +static void wma_lsp_to_curve(WMADecodeContext *s, + fixed32 *out, + fixed32 *val_max_ptr, + int n, + fixed32 *lsp) +{ + int i, j; + fixed32 p, q, w, v, val_max, temp2; + + val_max = 0; + for(i=0;i<n;++i) + { + /* shift by 2 now to reduce rounding error, + * we can renormalize right before pow_m1_4 + */ + + p = 0x8000<<5; + q = 0x8000<<5; + w = s->lsp_cos_table[i]; + + for (j=1;j<NB_LSP_COEFS;j+=2) + { + /* w is 5.27 format, lsp is in 16.16, temp2 becomes 5.27 format */ + temp2 = ((w - (lsp[j - 1]<<11))); + + /* q is 16.16 format, temp2 is 5.27, q becomes 16.16 */ + q = fixmul32b(q, temp2 )<<4; + p = fixmul32b(p, (w - (lsp[j]<<11)))<<4; + } + + /* 2 in 5.27 format is 0x10000000 */ + p = fixmul32(p, fixmul32b(p, (0x10000000 - w)))<<3; + q = fixmul32(q, fixmul32b(q, (0x10000000 + w)))<<3; + + v = (p + q) >>9; /* p/q end up as 16.16 */ + v = pow_m1_4(s, v); + if (v > val_max) + val_max = v; + out[i] = v; + } + + *val_max_ptr = val_max; +} + +/* decode exponents coded with LSP coefficients (same idea as Vorbis) + * only used for low bitrate (< 16kbps) files + */ +static void decode_exp_lsp(WMADecodeContext *s, int ch) +{ + fixed32 lsp_coefs[NB_LSP_COEFS]; + int val, i; + + for (i = 0; i < NB_LSP_COEFS; ++i) + { + if (i == 0 || i >= 8) + val = get_bits(&s->gb, 3); + else + val = get_bits(&s->gb, 4); + lsp_coefs[i] = lsp_codebook[i][val]; + } + + wma_lsp_to_curve(s, + s->exponents[ch], + &s->max_exponent[ch], + s->block_len, + lsp_coefs); +} + +/* decode exponents coded with VLC codes - used for bitrate >= 32kbps*/ +static int decode_exp_vlc(WMADecodeContext *s, int ch) +{ + int last_exp, n, code; + const uint16_t *ptr, *band_ptr; + fixed32 v, max_scale; + fixed32 *q,*q_end; + + /*accommodate the 60 negative indices */ + const fixed32 *pow_10_to_yover16_ptr = &pow_10_to_yover16[61]; + + band_ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; + ptr = band_ptr; + q = s->exponents[ch]; + q_end = q + s->block_len; + max_scale = 0; + + + if (s->version == 1) //wmav1 only + { + last_exp = get_bits(&s->gb, 5) + 10; + + v = pow_10_to_yover16_ptr[last_exp]; + max_scale = v; + n = *ptr++; + switch (n & 3) do { + case 0: *q++ = v; + case 3: *q++ = v; + case 2: *q++ = v; + case 1: *q++ = v; + } while ((n -= 4) > 0); + } else { + last_exp = 36; + } + + while (q < q_end) + { + code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); + if (code < 0) + { + return -1; + } + /* NOTE: this offset is the same as MPEG4 AAC ! */ + last_exp += code - 60; + + v = pow_10_to_yover16_ptr[last_exp]; + if (v > max_scale) + { + max_scale = v; + } + n = *ptr++; + switch (n & 3) do { + case 0: *q++ = v; + case 3: *q++ = v; + case 2: *q++ = v; + case 1: *q++ = v; + } while ((n -= 4) > 0); + } + + s->max_exponent[ch] = max_scale; + return 0; +} + +/* return 0 if OK. return 1 if last block of frame. return -1 if + unrecorrable error. */ +static int wma_decode_block(WMADecodeContext *s) +{ + int n, v, a, ch, code, bsize; + int coef_nb_bits, total_gain; + int nb_coefs[MAX_CHANNELS]; + fixed32 mdct_norm; + + /*DEBUGF("***decode_block: %d (%d samples of %d in frame)\n", s->block_num, s->block_len, s->frame_len);*/ + + /* compute current block length */ + if (s->use_variable_block_len) + { + n = av_log2(s->nb_block_sizes - 1) + 1; + + if (s->reset_block_lengths) + { + s->reset_block_lengths = 0; + v = get_bits(&s->gb, n); + if (v >= s->nb_block_sizes) + { + return -2; + } + s->prev_block_len_bits = s->frame_len_bits - v; + v = get_bits(&s->gb, n); + if (v >= s->nb_block_sizes) + { + return -3; + } + s->block_len_bits = s->frame_len_bits - v; + } + else + { + /* update block lengths */ + s->prev_block_len_bits = s->block_len_bits; + s->block_len_bits = s->next_block_len_bits; + } + v = get_bits(&s->gb, n); + + if (v >= s->nb_block_sizes) + { + // rb->splash(HZ*4, "v was %d", v); //5, 7 + return -4; //this is it + } + else{ + //rb->splash(HZ, "passed v block (%d)!", v); + } + s->next_block_len_bits = s->frame_len_bits - v; + } + else + { + /* fixed block len */ + s->next_block_len_bits = s->frame_len_bits; + s->prev_block_len_bits = s->frame_len_bits; + s->block_len_bits = s->frame_len_bits; + } + /* now check if the block length is coherent with the frame length */ + s->block_len = 1 << s->block_len_bits; + + if ((s->block_pos + s->block_len) > s->frame_len) + { + return -5; //oddly 32k sample from tracker fails here + } + + if (s->nb_channels == 2) + { + s->ms_stereo = get_bits1(&s->gb); + } + v = 0; + for (ch = 0; ch < s->nb_channels; ++ch) + { + a = get_bits1(&s->gb); + s->channel_coded[ch] = a; + v |= a; + } + /* if no channel coded, no need to go further */ + /* XXX: fix potential framing problems */ + if (!v) + { + goto next; + } + + bsize = s->frame_len_bits - s->block_len_bits; + + /* read total gain and extract corresponding number of bits for + coef escape coding */ + total_gain = 1; + for(;;) + { + a = get_bits(&s->gb, 7); + total_gain += a; + if (a != 127) + { + break; + } + } + + if (total_gain < 15) + coef_nb_bits = 13; + else if (total_gain < 32) + coef_nb_bits = 12; + else if (total_gain < 40) + coef_nb_bits = 11; + else if (total_gain < 45) + coef_nb_bits = 10; + else + coef_nb_bits = 9; + + /* compute number of coefficients */ + n = s->coefs_end[bsize] - s->coefs_start; + + for(ch = 0; ch < s->nb_channels; ++ch) + { + nb_coefs[ch] = n; + } + /* complex coding */ + if (s->use_noise_coding) + { + + for(ch = 0; ch < s->nb_channels; ++ch) + { + if (s->channel_coded[ch]) + { + int i, n, a; + n = s->exponent_high_sizes[bsize]; + for(i=0;i<n;++i) + { + a = get_bits1(&s->gb); + s->high_band_coded[ch][i] = a; + /* if noise coding, the coefficients are not transmitted */ + if (a) + nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; + } + } + } + for(ch = 0; ch < s->nb_channels; ++ch) + { + if (s->channel_coded[ch]) + { + int i, n, val, code; + + n = s->exponent_high_sizes[bsize]; + val = (int)0x80000000; + for(i=0;i<n;++i) + { + if (s->high_band_coded[ch][i]) + { + if (val == (int)0x80000000) + { + val = get_bits(&s->gb, 7) - 19; + } + else + { + //code = get_vlc(&s->gb, &s->hgain_vlc); + code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX); + if (code < 0) + { + return -6; + } + val += code - 18; + } + s->high_band_values[ch][i] = val; + } + } + } + } + } + + /* exponents can be reused in short blocks. */ + if ((s->block_len_bits == s->frame_len_bits) || get_bits1(&s->gb)) + { + for(ch = 0; ch < s->nb_channels; ++ch) + { + if (s->channel_coded[ch]) + { + if (s->use_exp_vlc) + { + if (decode_exp_vlc(s, ch) < 0) + { + return -7; + } + } + else + { + decode_exp_lsp(s, ch); + } + s->exponents_bsize[ch] = bsize; + } + } + } + + /* parse spectral coefficients : just RLE encoding */ + for(ch = 0; ch < s->nb_channels; ++ch) + { + if (s->channel_coded[ch]) + { + VLC *coef_vlc; + int level, run, sign, tindex; + int16_t *ptr, *eptr; + const int16_t *level_table, *run_table; + + /* special VLC tables are used for ms stereo because + there is potentially less energy there */ + tindex = (ch == 1 && s->ms_stereo); + coef_vlc = &s->coef_vlc[tindex]; + run_table = s->run_table[tindex]; + level_table = s->level_table[tindex]; + /* XXX: optimize */ + ptr = &s->coefs1[ch][0]; + eptr = ptr + nb_coefs[ch]; + memset(ptr, 0, s->block_len * sizeof(int16_t)); + + for(;;) + { + code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX); + + if (code < 0) + { + return -8; + } + if (code == 1) + { + /* EOB */ + break; + } + else if (code == 0) + { + /* escape */ + level = get_bits(&s->gb, coef_nb_bits); + /* NOTE: this is rather suboptimal. reading + block_len_bits would be better */ + run = get_bits(&s->gb, s->frame_len_bits); + } + else + { + /* normal code */ + run = run_table[code]; + level = level_table[code]; + } + sign = get_bits1(&s->gb); + if (!sign) + level = -level; + ptr += run; + if (ptr >= eptr) + { + break; + } + *ptr++ = level; + + + /* NOTE: EOB can be omitted */ + if (ptr >= eptr) + break; + } + } + if (s->version == 1 && s->nb_channels >= 2) + { + align_get_bits(&s->gb); + } + } + + { + int n4 = s->block_len >> 1; + + + mdct_norm = 0x10000>>(s->block_len_bits-1); + + if (s->version == 1) + { + mdct_norm *= fixtoi32(fixsqrt32(itofix32(n4))); + } + } + + + /* finally compute the MDCT coefficients */ + for(ch = 0; ch < s->nb_channels; ++ch) + { + if (s->channel_coded[ch]) + { + int16_t *coefs1; + fixed32 *exponents; + fixed32 *coefs, atemp; + fixed64 mult; + fixed64 mult1; + fixed32 noise, temp1, temp2, mult2; + int i, j, n, n1, last_high_band, esize; + fixed32 exp_power[HIGH_BAND_MAX_SIZE]; + + //total_gain, coefs1, mdctnorm are lossless + + coefs1 = s->coefs1[ch]; + exponents = s->exponents[ch]; + esize = s->exponents_bsize[ch]; + coefs = s->coefs[ch]; + n=0; + + /* + * The calculation of coefs has a shift right by 2 built in. This + * prepares samples for the Tremor IMDCT which uses a slightly + * different fixed format then the ffmpeg one. If the old ffmpeg + * imdct is used, each shift storing into coefs should be reduced + * by 1. + * See SVN logs for details. + */ + + + if (s->use_noise_coding) + { + /*This case is only used for low bitrates (typically less then 32kbps)*/ + + /*TODO: mult should be converted to 32 bit to speed up noise coding*/ + + mult = fixdiv64(pow_table[total_gain+20],Fixed32To64(s->max_exponent[ch])); + mult = mult* mdct_norm; + mult1 = mult; + + /* very low freqs : noise */ + for(i = 0;i < s->coefs_start; ++i) + { + *coefs++ = fixmul32( (fixmul32(s->noise_table[s->noise_index], + exponents[i<<bsize>>esize])>>4),Fixed32From64(mult1)) >>2; + s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); + } + + n1 = s->exponent_high_sizes[bsize]; + + /* compute power of high bands */ + exponents = s->exponents[ch] +(s->high_band_start[bsize]<<bsize); + last_high_band = 0; /* avoid warning */ + for (j=0;j<n1;++j) + { + n = s->exponent_high_bands[s->frame_len_bits - + s->block_len_bits][j]; + if (s->high_band_coded[ch][j]) + { + fixed32 e2, v; + e2 = 0; + for(i = 0;i < n; ++i) + { + /*v is normalized later on so its fixed format is irrelevant*/ + v = exponents[i<<bsize>>esize]>>4; + e2 += fixmul32(v, v)>>3; + } + exp_power[j] = e2/n; /*n is an int...*/ + last_high_band = j; + } + exponents += n<<bsize; + } + + /* main freqs and high freqs */ + exponents = s->exponents[ch] + (s->coefs_start<<bsize); + for(j=-1;j<n1;++j) + { + if (j < 0) + { + n = s->high_band_start[bsize] - + s->coefs_start; + } + else + { + n = s->exponent_high_bands[s->frame_len_bits - + s->block_len_bits][j]; + } + if (j >= 0 && s->high_band_coded[ch][j]) + { + /* use noise with specified power */ + fixed32 tmp = fixdiv32(exp_power[j],exp_power[last_high_band]); + + /*mult1 is 48.16, pow_table is 48.16*/ + mult1 = fixmul32(fixsqrt32(tmp), + pow_table[s->high_band_values[ch][j]+20]) >> 16; + + /*this step has a fairly high degree of error for some reason*/ + mult1 = fixdiv64(mult1,fixmul32(s->max_exponent[ch],s->noise_mult)); + mult1 = mult1*mdct_norm>>PRECISION; + for(i = 0;i < n; ++i) + { + noise = s->noise_table[s->noise_index]; + s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); + *coefs++ = fixmul32((fixmul32(exponents[i<<bsize>>esize],noise)>>4), + Fixed32From64(mult1)) >>2; + + } + exponents += n<<bsize; + } + else + { + /* coded values + small noise */ + for(i = 0;i < n; ++i) + { + noise = s->noise_table[s->noise_index]; + s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); + + /*don't forget to renormalize the noise*/ + temp1 = (((int32_t)*coefs1++)<<16) + (noise>>4); + temp2 = fixmul32(exponents[i<<bsize>>esize], mult>>18); + *coefs++ = fixmul32(temp1, temp2); + } + exponents += n<<bsize; + } + } + + /* very high freqs : noise */ + n = s->block_len - s->coefs_end[bsize]; + mult2 = fixmul32(mult>>16,exponents[((-1<<bsize))>>esize]) ; + for (i = 0; i < n; ++i) + { + /*renormalize the noise product and then reduce to 14.18 precison*/ + *coefs++ = fixmul32(s->noise_table[s->noise_index],mult2) >>6; + + s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); + } + } + else + { + /*Noise coding not used, simply convert from exp to fixed representation*/ + + fixed32 mult3 = (fixed32)(fixdiv64(pow_table[total_gain+20], + Fixed32To64(s->max_exponent[ch]))); + mult3 = fixmul32(mult3, mdct_norm); + + /*zero the first 3 coefficients for WMA V1, does nothing otherwise*/ + for(i=0; i<s->coefs_start; i++) + *coefs++=0; + + n = nb_coefs[ch]; + + /* XXX: optimize more, unrolling this loop in asm + might be a good idea */ + + for(i = 0;i < n; ++i) + { + /*ffmpeg imdct needs 15.17, while tremor 14.18*/ + atemp = (coefs1[i] * mult3)>>2; + *coefs++=fixmul32(atemp,exponents[i<<bsize>>esize]); + } + n = s->block_len - s->coefs_end[bsize]; + memset(coefs, 0, n*sizeof(fixed32)); + } + } + } + + + + if (s->ms_stereo && s->channel_coded[1]) + { + fixed32 a, b; + int i; + /* nominal case for ms stereo: we do it before mdct */ + /* no need to optimize this case because it should almost + never happen */ + if (!s->channel_coded[0]) + { + memset(s->coefs[0], 0, sizeof(fixed32) * s->block_len); + s->channel_coded[0] = 1; + } + + for(i = 0; i < s->block_len; ++i) + { + a = s->coefs[0][i]; + b = s->coefs[1][i]; + s->coefs[0][i] = a + b; + s->coefs[1][i] = a - b; + } + } + + for(ch = 0; ch < s->nb_channels; ++ch) + { + /* BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. */ + static uint32_t scratch_buf[BLOCK_MAX_SIZE * MAX_CHANNELS] IBSS_ATTR MEM_ALIGN_ATTR; + if (s->channel_coded[ch]) + { + int n4, index; + + n4 = s->block_len >>1; + + ff_imdct_calc((s->frame_len_bits - bsize + 1), + scratch_buf, + s->coefs[ch]); + + /* add in the frame */ + index = (s->frame_len / 2) + s->block_pos - n4; + wma_window(s, scratch_buf, &(s->frame_out[ch][index])); + + + + /* specific fast case for ms-stereo : add to second + channel if it is not coded */ + if (s->ms_stereo && !s->channel_coded[1]) + { + wma_window(s, scratch_buf, &(s->frame_out[1][index])); + } + } + } +next: + /* update block number */ + ++s->block_num; + s->block_pos += s->block_len; + if (s->block_pos >= s->frame_len) + { + return 1; + } + else + { + return 0; + } +} + +/* decode a frame of frame_len samples */ +static int wma_decode_frame(WMADecodeContext *s) +{ + int ret; + + /* read each block */ + s->block_num = 0; + s->block_pos = 0; + + + for(;;) + { + ret = wma_decode_block(s); + if (ret < 0) + { + + DEBUGF("wma_decode_block failed with code %d\n", ret); + return -1; + } + if (ret) + { + break; + } + } + + return 0; +} + +/* Initialise the superframe decoding */ + +int wma_decode_superframe_init(WMADecodeContext* s, + const uint8_t *buf, /*input*/ + int buf_size) +{ + if (buf_size==0) + { + s->last_superframe_len = 0; + return 0; + } + + s->current_frame = 0; + + init_get_bits(&s->gb, buf, buf_size*8); + + if (s->use_bit_reservoir) + { + /* read super frame header */ + skip_bits(&s->gb, 4); /* super frame index */ + s->nb_frames = get_bits(&s->gb, 4); + + if (s->last_superframe_len == 0) + s->nb_frames --; + else if (s->nb_frames == 0) + s->nb_frames++; + + s->bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); + } else { + s->nb_frames = 1; + } + + return 1; +} + + +/* Decode a single frame in the current superframe - return -1 if + there was a decoding error, or the number of samples decoded. +*/ + +int wma_decode_superframe_frame(WMADecodeContext* s, + const uint8_t *buf, /*input*/ + int buf_size) +{ + int pos, len, ch; + uint8_t *q; + int done = 0; + + for(ch = 0; ch < s->nb_channels; ch++) + memmove(&(s->frame_out[ch][0]), + &(s->frame_out[ch][s->frame_len]), + s->frame_len * sizeof(fixed32)); + + if ((s->use_bit_reservoir) && (s->current_frame == 0)) + { + if (s->last_superframe_len > 0) + { + /* add s->bit_offset bits to last frame */ + if ((s->last_superframe_len + ((s->bit_offset + 7) >> 3)) > + MAX_CODED_SUPERFRAME_SIZE) + { + DEBUGF("superframe size too large error\n"); + goto fail; + } + q = s->last_superframe + s->last_superframe_len; + len = s->bit_offset; + while (len > 7) + { + *q++ = (get_bits)(&s->gb, 8); + len -= 8; + } + if (len > 0) + { + *q++ = (get_bits)(&s->gb, len) << (8 - len); + } + + /* XXX: s->bit_offset bits into last frame */ + init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); + /* skip unused bits */ + if (s->last_bitoffset > 0) + skip_bits(&s->gb, s->last_bitoffset); + + /* this frame is stored in the last superframe and in the + current one */ + if (wma_decode_frame(s) < 0) + { + goto fail; + } + done = 1; + } + + /* read each frame starting from s->bit_offset */ + pos = s->bit_offset + 4 + 4 + s->byte_offset_bits + 3; + init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); + len = pos & 7; + if (len > 0) + skip_bits(&s->gb, len); + + s->reset_block_lengths = 1; + } + + /* If we haven't decoded a frame yet, do it now */ + if (!done) + { + if (wma_decode_frame(s) < 0) + { + goto fail; + } + } + + s->current_frame++; + + if ((s->use_bit_reservoir) && (s->current_frame == s->nb_frames)) + { + /* we copy the end of the frame in the last frame buffer */ + pos = get_bits_count(&s->gb) + ((s->bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); + s->last_bitoffset = pos & 7; + pos >>= 3; + len = buf_size - pos; + if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) + { + DEBUGF("superframe size too large error after decoding\n"); + goto fail; + } + s->last_superframe_len = len; + memcpy(s->last_superframe, buf + pos, len); + } + + return s->frame_len; + +fail: + /* when error, we reset the bit reservoir */ + + s->last_superframe_len = 0; + return -1; +} + diff --git a/plugins/wma/libwma/wmafixed.c b/plugins/wma/libwma/wmafixed.c new file mode 100644 index 00000000..01326150 --- /dev/null +++ b/plugins/wma/libwma/wmafixed.c @@ -0,0 +1,222 @@ +/**************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 Michael Giacomelli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "wmadec.h" +#include "wmafixed.h" + +fixed64 IntTo64(int x){ + fixed64 res = 0; + unsigned char *p = (unsigned char *)&res; + +#ifdef ROCKBOX_BIG_ENDIAN + p[5] = x & 0xff; + p[4] = (x & 0xff00)>>8; + p[3] = (x & 0xff0000)>>16; + p[2] = (x & 0xff000000)>>24; +#else + p[2] = x & 0xff; + p[3] = (x & 0xff00)>>8; + p[4] = (x & 0xff0000)>>16; + p[5] = (x & 0xff000000)>>24; +#endif + return res; +} + +int IntFrom64(fixed64 x) +{ + int res = 0; + unsigned char *p = (unsigned char *)&x; + +#ifdef ROCKBOX_BIG_ENDIAN + res = p[5] | (p[4]<<8) | (p[3]<<16) | (p[2]<<24); +#else + res = p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24); +#endif + return res; +} + +fixed32 Fixed32From64(fixed64 x) +{ + return x & 0xFFFFFFFF; +} + +fixed64 Fixed32To64(fixed32 x) +{ + return (fixed64)x; +} + +/* + Not performance senstitive code here + +*/ + +fixed32 fixdiv32(fixed32 x, fixed32 y) +{ + fixed64 temp; + + if(x == 0) + return 0; + if(y == 0) + return 0x7fffffff; + temp = x; + temp <<= PRECISION; + return (fixed32)(temp / y); +} + +fixed64 fixdiv64(fixed64 x, fixed64 y) +{ + fixed64 temp; + + if(x == 0) + return 0; + if(y == 0) + return 0x07ffffffffffffffLL; + temp = x; + temp <<= PRECISION64; + return (fixed64)(temp / y); +} + + fixed32 fixsqrt32(fixed32 x) +{ + + unsigned long r = 0, s, v = (unsigned long)x; + +#define STEP(k) s = r + (1 << k * 2); r >>= 1; \ + if (s <= v) { v -= s; r |= (1 << k * 2); } + + STEP(15); + STEP(14); + STEP(13); + STEP(12); + STEP(11); + STEP(10); + STEP(9); + STEP(8); + STEP(7); + STEP(6); + STEP(5); + STEP(4); + STEP(3); + STEP(2); + STEP(1); + STEP(0); + + return (fixed32)(r << (PRECISION / 2)); +} + + + static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */ + + /* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */ + static const unsigned long atan_table[] = { + 0x1fffffff, /* +0.785398163 (or pi/4) */ + 0x12e4051d, /* +0.463647609 */ + 0x09fb385b, /* +0.244978663 */ + 0x051111d4, /* +0.124354995 */ + 0x028b0d43, /* +0.062418810 */ + 0x0145d7e1, /* +0.031239833 */ + 0x00a2f61e, /* +0.015623729 */ + 0x00517c55, /* +0.007812341 */ + 0x0028be53, /* +0.003906230 */ + 0x00145f2e, /* +0.001953123 */ + 0x000a2f98, /* +0.000976562 */ + 0x000517cc, /* +0.000488281 */ + 0x00028be6, /* +0.000244141 */ + 0x000145f3, /* +0.000122070 */ + 0x0000a2f9, /* +0.000061035 */ + 0x0000517c, /* +0.000030518 */ + 0x000028be, /* +0.000015259 */ + 0x0000145f, /* +0.000007629 */ + 0x00000a2f, /* +0.000003815 */ + 0x00000517, /* +0.000001907 */ + 0x0000028b, /* +0.000000954 */ + 0x00000145, /* +0.000000477 */ + 0x000000a2, /* +0.000000238 */ + 0x00000051, /* +0.000000119 */ + 0x00000028, /* +0.000000060 */ + 0x00000014, /* +0.000000030 */ + 0x0000000a, /* +0.000000015 */ + 0x00000005, /* +0.000000007 */ + 0x00000002, /* +0.000000004 */ + 0x00000001, /* +0.000000002 */ + 0x00000000, /* +0.000000001 */ + 0x00000000, /* +0.000000000 */ + }; + + /** + * Implements sin and cos using CORDIC rotation. + * + * @param phase has range from 0 to 0xffffffff, representing 0 and + * 2*pi respectively. + * @param cos return address for cos + * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX, + * representing -1 and 1 respectively. + * + * Gives at least 24 bits precision (last 2-8 bits or so are probably off) + */ + + long fsincos(unsigned long phase, fixed32 *cos) + { + int32_t x, x1, y, y1; + unsigned long z, z1; + int i; + + /* Setup initial vector */ + x = cordic_circular_gain; + y = 0; + z = phase; + + /* The phase has to be somewhere between 0..pi for this to work right */ + if (z < 0xffffffff / 4) { + /* z in first quadrant, z += pi/2 to correct */ + x = -x; + z += 0xffffffff / 4; + } else if (z < 3 * (0xffffffff / 4)) { + /* z in third quadrant, z -= pi/2 to correct */ + z -= 0xffffffff / 4; + } else { + /* z in fourth quadrant, z -= 3pi/2 to correct */ + x = -x; + z -= 3 * (0xffffffff / 4); + } + + /* Each iteration adds roughly 1-bit of extra precision */ + for (i = 0; i < 31; i++) { + x1 = x >> i; + y1 = y >> i; + z1 = atan_table[i]; + + /* Decided which direction to rotate vector. Pivot point is pi/2 */ + if (z >= 0xffffffff / 4) { + x -= y1; + y += x1; + z -= z1; + } else { + x += y1; + y -= x1; + z += z1; + } + } + + if (cos) + *cos = x; + + return y; + } diff --git a/plugins/wma/libwma/wmafixed.h b/plugins/wma/libwma/wmafixed.h new file mode 100644 index 00000000..93969801 --- /dev/null +++ b/plugins/wma/libwma/wmafixed.h @@ -0,0 +1,238 @@ +/**************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 Michael Giacomelli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* fixed precision code. We use a combination of Sign 15.16 and Sign.31 + precision here. + + The WMA decoder does not always follow this convention, and occasionally + renormalizes values to other formats in order to maximize precision. + However, only the two precisions above are provided in this file. + +*/ + +#include "types.h" +#include "mdct.h" + +#define PRECISION 16 +#define PRECISION64 16 + + +#define fixtof64(x) (float)((float)(x) / (float)(1 << PRECISION64)) //does not work on int64_t! +#define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5))) +#define itofix64(x) (IntTo64(x)) +#define itofix32(x) ((x) << PRECISION) +#define fixtoi32(x) ((x) >> PRECISION) +#define fixtoi64(x) (IntFrom64(x)) + + +/*fixed functions*/ + +fixed64 IntTo64(int x); +int IntFrom64(fixed64 x); +fixed32 Fixed32From64(fixed64 x); +fixed64 Fixed32To64(fixed32 x); +fixed32 fixdiv32(fixed32 x, fixed32 y); +fixed64 fixdiv64(fixed64 x, fixed64 y); +fixed32 fixsqrt32(fixed32 x); +/* Inverse gain of circular cordic rotation in s0.31 format. */ +long fsincos(unsigned long phase, fixed32 *cos); + + +#ifdef CPU_ARM + +/*Sign-15.16 format */ +#define fixmul32(x, y) \ + ({ int32_t __hi; \ + uint32_t __lo; \ + int32_t __result; \ + asm ("smull %0, %1, %3, %4\n\t" \ + "movs %0, %0, lsr %5\n\t" \ + "adc %2, %0, %1, lsl %6" \ + : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ + : "%r" (x), "r" (y), \ + "M" (PRECISION), "M" (32 - PRECISION) \ + : "cc"); \ + __result; \ + }) + +#elif defined(CPU_COLDFIRE) + +static inline int32_t fixmul32(int32_t x, int32_t y) +{ +#if PRECISION != 16 +#warning Coldfire fixmul32() only works for PRECISION == 16 +#endif + int32_t t1; + asm ( + "mac.l %[x], %[y], %%acc0 \n" // multiply + "mulu.l %[y], %[x] \n" // get lower half, avoid emac stall + "movclr.l %%acc0, %[t1] \n" // get higher half + "lsr.l #1, %[t1] \n" + "move.w %[t1], %[x] \n" + "swap %[x] \n" + : [t1] "=&d" (t1), [x] "+d" (x) + : [y] "d" (y) + ); + return x; +} + +#else + +static inline fixed32 fixmul32(fixed32 x, fixed32 y) +{ + fixed64 temp; + temp = x; + temp *= y; + + temp >>= PRECISION; + + return (fixed32)temp; +} + +#endif + + +/* + * Helper functions for wma_window. + * + * + */ + +#ifdef CPU_ARM +static inline void vector_fmul_add_add(fixed32 *dst, const fixed32 *data, + const fixed32 *window, int n) +{ + /* Block sizes are always power of two */ + asm volatile ( + "0:" + "ldmia %[d]!, {r0, r1};" + "ldmia %[w]!, {r4, r5};" + /* consume the first data and window value so we can use those + * registers again */ + "smull r8, r9, r0, r4;" + "ldmia %[dst], {r0, r4};" + "add r0, r0, r9, lsl #1;" /* *dst=*dst+(r9<<1)*/ + "smull r8, r9, r1, r5;" + "add r1, r4, r9, lsl #1;" + "stmia %[dst]!, {r0, r1};" + "subs %[n], %[n], #2;" + "bne 0b;" + : [d] "+r" (data), [w] "+r" (window), [dst] "+r" (dst), [n] "+r" (n) + : : "r0", "r1", "r4", "r5", "r8", "r9", "memory", "cc"); +} + +static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, + int len) +{ + /* Block sizes are always power of two */ + asm volatile ( + "add %[s1], %[s1], %[n], lsl #2;" + "0:" + "ldmia %[s0]!, {r0, r1};" + "ldmdb %[s1]!, {r4, r5};" + "smull r8, r9, r0, r5;" + "mov r0, r9, lsl #1;" + "smull r8, r9, r1, r4;" + "mov r1, r9, lsl #1;" + "stmia %[dst]!, {r0, r1};" + "subs %[n], %[n], #2;" + "bne 0b;" + : [s0] "+r" (src0), [s1] "+r" (src1), [dst] "+r" (dst), [n] "+r" (len) + : : "r0", "r1", "r4", "r5", "r8", "r9", "memory", "cc"); +} + +#elif defined(CPU_COLDFIRE) + +static inline void vector_fmul_add_add(fixed32 *dst, const fixed32 *data, + const fixed32 *window, int n) +{ + /* Block sizes are always power of two. Smallest block is always way bigger + * than four too.*/ + asm volatile ( + "0:" + "movem.l (%[d]), %%d0-%%d3;" + "movem.l (%[w]), %%d4-%%d5/%%a0-%%a1;" + "mac.l %%d0, %%d4, %%acc0;" + "mac.l %%d1, %%d5, %%acc1;" + "mac.l %%d2, %%a0, %%acc2;" + "mac.l %%d3, %%a1, %%acc3;" + "lea.l (16, %[d]), %[d];" + "lea.l (16, %[w]), %[w];" + "movclr.l %%acc0, %%d0;" + "movclr.l %%acc1, %%d1;" + "movclr.l %%acc2, %%d2;" + "movclr.l %%acc3, %%d3;" + "movem.l (%[dst]), %%d4-%%d5/%%a0-%%a1;" + "add.l %%d4, %%d0;" + "add.l %%d5, %%d1;" + "add.l %%a0, %%d2;" + "add.l %%a1, %%d3;" + "movem.l %%d0-%%d3, (%[dst]);" + "lea.l (16, %[dst]), %[dst];" + "subq.l #4, %[n];" + "jne 0b;" + : [d] "+a" (data), [w] "+a" (window), [dst] "+a" (dst), [n] "+d" (n) + : : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1", "memory", "cc"); +} + +static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, + int len) +{ + /* Block sizes are always power of two. Smallest block is always way bigger + * than four too.*/ + asm volatile ( + "lea.l (-16, %[s1], %[n]*4), %[s1];" + "0:" + "movem.l (%[s0]), %%d0-%%d3;" + "movem.l (%[s1]), %%d4-%%d5/%%a0-%%a1;" + "mac.l %%d0, %%a1, %%acc0;" + "mac.l %%d1, %%a0, %%acc1;" + "mac.l %%d2, %%d5, %%acc2;" + "mac.l %%d3, %%d4, %%acc3;" + "lea.l (16, %[s0]), %[s0];" + "lea.l (-16, %[s1]), %[s1];" + "movclr.l %%acc0, %%d0;" + "movclr.l %%acc1, %%d1;" + "movclr.l %%acc2, %%d2;" + "movclr.l %%acc3, %%d3;" + "movem.l %%d0-%%d3, (%[dst]);" + "lea.l (16, %[dst]), %[dst];" + "subq.l #4, %[n];" + "jne 0b;" + : [s0] "+a" (src0), [s1] "+a" (src1), [dst] "+a" (dst), [n] "+d" (len) + : : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1", "memory", "cc"); +} + +#else + +static inline void vector_fmul_add_add(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, int len){ + int i; + for(i=0; i<len; i++) + dst[i] = fixmul32b(src0[i], src1[i]) + dst[i]; +} + +static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const fixed32 *src1, int len){ + int i; + src1 += len-1; + for(i=0; i<len; i++) + dst[i] = fixmul32b(src0[i], src1[-i]); +} + +#endif diff --git a/plugins/wma/wma_plugin.c b/plugins/wma/wma_plugin.c new file mode 100644 index 00000000..ddfd8eec --- /dev/null +++ b/plugins/wma/wma_plugin.c @@ -0,0 +1,388 @@ +/* + WMA plugin for deadbeef + Copyright (C) 2013 Alexey Yakovenko <waker@users.sourceforge.net> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include "../../deadbeef.h" +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "libasf/asf.h" + +//#define USE_FFMPEG 1 + +#if USE_FFMPEG +#include "libwma-ff/wma.h" +#else +#include "libwma/wmadec.h" +#endif + +#define min(x,y) ((x)<(y)?(x):(y)) +#define max(x,y) ((x)>(y)?(x):(y)) + +#define trace(...) { fprintf(stderr, __VA_ARGS__); } +//#define trace(fmt,...) + +static DB_decoder_t plugin; +DB_functions_t *deadbeef; + +#define MAX_PACKET_SIZE 100000 + +typedef struct { + DB_fileinfo_t info; + asf_waveformatex_t wfx; +#if USE_FFMPEG + WMACodecContext wmadec; +#else + WMADecodeContext wmadec; +#endif + DB_FILE *fp; + int64_t first_frame_offset; + int currentsample; + int startsample; + int endsample; + char buffer[MAX_PACKET_SIZE]; + int remaining; +} wmaplug_info_t; + +// allocate codec control structure +static DB_fileinfo_t * +wmaplug_open (uint32_t hints) { + DB_fileinfo_t *_info = malloc (sizeof (wmaplug_info_t)); + wmaplug_info_t *info = (wmaplug_info_t *)_info; + memset (info, 0, sizeof (wmaplug_info_t)); + return _info; +} + +int get_asf_metadata(DB_FILE *fd, DB_playItem_t *it, asf_waveformatex_t *wfx, int64_t *first_frame_offset); + +static int +wmaplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) { + wmaplug_info_t *info = (wmaplug_info_t *)_info; + + info->fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI")); + if (!info->fp) { + return -1; + } + + + get_asf_metadata (info->fp, NULL, &info->wfx, &info->first_frame_offset); + deadbeef->fseek (info->fp, info->first_frame_offset, SEEK_SET); +#if USE_FFMPEG + info->wmadec.sample_rate = info->wfx.rate; + info->wmadec.nb_channels = info->wfx.channels; + info->wmadec.channels = info->wfx.channels; + info->wmadec.bit_rate = info->wfx.bitrate; + info->wmadec.block_align = info->wfx.blockalign; + info->wmadec.codec_id = info->wfx.codec_id; + printf ("codec id: %x\n", info->wmadec.codec_id); + info->wmadec.extradata = info->wfx.data; + if (wma_decode_init (&info->wmadec)) { + trace ("wma_decode_init fail\n"); + return -1; + } + trace ("wma_decode_init success\n"); +#else + if (wma_decode_init(&info->wmadec,&info->wfx) < 0) { + return -1; + } +#endif + + info->currentsample = 0; + info->startsample = it->startsample; + info->endsample = it->endsample; + _info->plugin = &plugin; + _info->fmt.bps = info->wfx.bitspersample; + _info->fmt.channels = info->wfx.channels; + _info->fmt.samplerate = info->wfx.rate; + for (int i = 0; i < _info->fmt.channels; i++) { + _info->fmt.channelmask |= 1 << i; + } + return 0; +} + +static void +wmaplug_free (DB_fileinfo_t *_info) { + wmaplug_info_t *info = (wmaplug_info_t *)_info; + if (info) { +#if USE_FFMPEG + ff_wma_end (&info->wmadec); +#endif + if (info->fp) { + deadbeef->fclose (info->fp); + } + free (info); + } +} + +static int +wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) { + wmaplug_info_t *info = (wmaplug_info_t *)_info; + int samplesize = _info->fmt.channels * _info->fmt.bps / 8; + if (!info->fp->vfs->is_streaming ()) { + if (info->currentsample + size / samplesize > info->endsample) { + size = (info->endsample - info->currentsample + 1) * samplesize; + if (size <= 0) { + trace ("wmaplug_read: eof (current=%d, total=%d)\n", info->currentsample, info->endsample); + return 0; + } + } + } + int initsize = size; + +#if !USE_FFMPEG + while (size > 0) { + if (info->remaining == 0) { + int errcount = 0; + int res = 0; + uint8_t audiobuf_mem[40000]; + uint8_t* audiobuf = audiobuf_mem; + int audiobufsize = 0; + int packetlength = 0; + new_packet: + { + int pos = deadbeef->ftell (info->fp); + res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp); + int endpos = deadbeef->ftell (info->fp); +// printf ("packet pos: %d, packet size: %d, data size: %d, blockalign: %d\n", pos, endpos-pos, packetlength, info->wfx.blockalign); + } + if (res > 0) { + int nb = audiobufsize / info->wfx.blockalign; + for (int b = 0; b < nb; b++) { + wma_decode_superframe_init(&info->wmadec, audiobuf + b * info->wfx.blockalign, info->wfx.blockalign); + + int n = 0; + for (int i=0; i < info->wmadec.nb_frames; i++) + { + int wmares = wma_decode_superframe_frame(&info->wmadec, + audiobuf + b * info->wfx.blockalign, info->wfx.blockalign); + + if (wmares < 0) { + /* Do the above, but for errors in decode. */ + errcount++; + trace ("WMA decode error %d, errcount %d\n",wmares, errcount); + if (errcount > 5) { + break; + } else { + goto new_packet; + } + } else if (wmares > 0) { + int16_t *p = (int16_t *)&info->buffer[info->remaining]; + for (int s = 0; s < wmares; s++) { + for (int ch = 0; ch < info->wfx.channels; ch++) { + fixed32 *chan = info->wmadec.frame_out[ch]; + p[s*info->wfx.channels+ch] = chan[s] >> 16; + } + } + info->remaining += wmares * info->wfx.channels * info->wfx.bitspersample / 8; + } + } + } + } + } + + int sz = min (size, info->remaining); + if (sz == 0) { + break; + } + memcpy (bytes, info->buffer, sz); + if (info->remaining != sz) { + memmove (info->buffer, info->buffer+sz, info->remaining-sz); + } + info->remaining -= sz; + size -= sz; + } +#else +// {{{ ffmpeg + while (size > 0) { + if (info->remaining == 0) { + int errcount = 0; + int res = 0; + uint8_t audiobuf_mem[40000]; + uint8_t* audiobuf = audiobuf_mem; + int audiobufsize = 0; + int packetlength = 0; + new_packet: + //res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp); + { + int pos = deadbeef->ftell (info->fp); + res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp); + int endpos = deadbeef->ftell (info->fp); + printf ("packet pos: %d, packet size: %d, data size: %d\n", pos, endpos-pos, packetlength); + } + if (res > 0) { + int nblocks = audiobufsize / info->wfx.blockalign; + for (int i = 0 ; i < nblocks; i++) { + int got_frame_ptr = 0; + char *data; + int bufsize = wma_decode_superframe (&info->wmadec, &got_frame_ptr, audiobuf + i * info->wfx.blockalign, info->wfx.blockalign); + printf ("got frame ptr: %d, bufsize: %d\n", got_frame_ptr, info->wmadec.nb_samples * 4); + + int16_t *p = (int16_t *)&info->buffer[info->remaining]; + memcpy (p, info->wmadec.output_buffer, info->wmadec.nb_samples * 4); + info->remaining += info->wmadec.nb_samples * 4; + } + } + } + + int sz = min (size, info->remaining); + if (sz == 0) { + printf ("buffer is empty\n"); + break; + } + memcpy (bytes, info->buffer, sz); + if (info->remaining != sz) { + memmove (info->buffer, info->buffer+sz, info->remaining-sz); + } + info->remaining -= sz; + size -= sz; + } +#endif +// }}} + + return initsize-size; +} + +static int +wmaplug_seek_sample (DB_fileinfo_t *_info, int sample) { + wmaplug_info_t *info = (wmaplug_info_t *)_info; + + sample += info->startsample; + + /*flush the wma decoder state*/ + info->wmadec.last_superframe_len = 0; + info->wmadec.last_bitoffset = 0; + + /*zero the frame out buffer so we don't overlap with a + stale samples*/ + memset(info->wmadec.frame_out, 0, + sizeof(fixed32) * MAX_CHANNELS * BLOCK_MAX_SIZE * 2); + + int elapsedtime = asf_seek(sample * 1000 / _info->fmt.samplerate, &info->wfx, info->fp, info->first_frame_offset); + if (elapsedtime <= 0) { + // restart track + info->currentsample = 0; + printf ("seek failed\n"); + } + else { + // seek successful + info->currentsample = elapsedtime * _info->fmt.samplerate / 1000; + _info->readpos = (float)(info->currentsample - info->startsample)/_info->fmt.samplerate; + printf ("seek success, sample=%d, pos=%f\n", info->currentsample, _info->readpos); + } + + return 0; +} + +static int +wmaplug_seek (DB_fileinfo_t *_info, float t) { + return wmaplug_seek_sample (_info, t * _info->fmt.samplerate); +} + +static int +wmaplug_read_metadata (DB_playItem_t *it) { + return 0; +} + +static DB_playItem_t * +wmaplug_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { + asf_waveformatex_t wfx; + + DB_FILE *fp = deadbeef->fopen (fname); + if (!fp) { + return NULL; + } + + int64_t first_frame_offset; + + DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id); + + get_asf_metadata (fp, it, &wfx, &first_frame_offset); + //printf ("datalen %d, channels %d, bps %d, rate %d\n", wfx.datalen, wfx.channels, wfx.bitspersample, wfx.rate); + + deadbeef->fseek (fp, first_frame_offset, SEEK_SET); + + int64_t i_count = (deadbeef->fgetlength (fp) - first_frame_offset) / wfx.packet_size; + int64_t i_length = wfx.play_duration / 10 * + i_count / wfx.numpackets - wfx.preroll * 1000; + + int64_t totalsamples = i_length / 1000 * wfx.rate / 1000; +// printf ("totalsamples: %lld\n", totalsamples); + + deadbeef->plt_set_item_duration (plt, it, totalsamples / (float)wfx.rate); + deadbeef->pl_append_meta (it, ":FILETYPE", "WMA"); + + it->startsample = 0; + it->endsample = totalsamples-1; + + after = deadbeef->plt_insert_item (plt, after, it); + deadbeef->pl_item_unref (it); + deadbeef->fclose (fp); + return after; +} + +static const char * exts[] = { "wma", NULL }; + +// define plugin interface +static DB_decoder_t plugin = { + .plugin.api_vmajor = 1, + .plugin.api_vminor = 0, + .plugin.version_major = 1, + .plugin.version_minor = 0, + .plugin.type = DB_PLUGIN_DECODER, + .plugin.id = "wma", + .plugin.name = "WMA player", + .plugin.descr = "plays WMA files", + .plugin.copyright = + "WMA plugin for deadbeef\n" + "Based on WMA and ASF code from RockBox (C) RockBox developers\n" + "\n" + "Copyright (C) 2013 Alexey Yakovenko <waker@users.sourceforge.net>\n" + "\n" + "This program is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU General Public License\n" + "as published by the Free Software Foundation; either version 2\n" + "of the License, or (at your option) any later version.\n" + "\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" + , + .plugin.website = "http://deadbeef.sf.net", + .open = wmaplug_open, + .init = wmaplug_init, + .free = wmaplug_free, + .read = wmaplug_read, + .seek = wmaplug_seek, + .seek_sample = wmaplug_seek_sample, + .insert = wmaplug_insert, + .read_metadata = wmaplug_read_metadata, + .exts = exts, +}; + +DB_plugin_t * +wma_load (DB_functions_t *api) { + deadbeef = api; + return DB_PLUGIN (&plugin); +} diff --git a/scripts/quickinstall.sh b/scripts/quickinstall.sh index 41cc412e..d372ecde 100755 --- a/scripts/quickinstall.sh +++ b/scripts/quickinstall.sh @@ -48,3 +48,4 @@ cp ./plugins/vfs_zip/.libs/vfs_zip.so /usr/local/lib/deadbeef/ cp ./plugins/medialib/.libs/medialib.so /usr/local/lib/deadbeef/ cp ./plugins/mono2stereo/.libs/ddb_mono2stereo.so /usr/local/lib/deadbeef/ cp ./plugins/alac/.libs/alac.so /usr/local/lib/deadbeef/ +cp ./plugins/wma/.libs/wma.so /usr/local/lib/deadbeef/ diff --git a/shortlicense.gpl2 b/shortlicense.gpl2 index 8d9c6d9f..e39da2f2 100644 --- a/shortlicense.gpl2 +++ b/shortlicense.gpl2 @@ -1,6 +1,6 @@ /* DeaDBeeF - ultimate music player for GNU/Linux systems with X11 - Copyright (C) 2009-2012 Alexey Yakovenko <waker@users.sourceforge.net> + Copyright (C) 2009-2013 Alexey Yakovenko <waker@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License |