]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
First draft of the wma decoder.
authorAndre Noll <maan@systemlinux.org>
Tue, 6 Oct 2009 21:03:11 +0000 (23:03 +0200)
committerAndre Noll <maan@systemlinux.org>
Wed, 18 Nov 2009 18:34:10 +0000 (19:34 +0100)
Understands only v1, but is easy to crash.

16 files changed:
COPYING.LIB [new file with mode: 0644]
afh_common.c
bitstream.c [new file with mode: 0644]
bitstream.h [new file with mode: 0644]
configure.ac
error.h
mdct.c [new file with mode: 0644]
mdct.h [new file with mode: 0644]
ogg_afh.c
string.c
string.h
wma.h [new file with mode: 0644]
wma_afh.c [new file with mode: 0644]
wma_common.c [new file with mode: 0644]
wmadata.h [new file with mode: 0644]
wmadec_filter.c [new file with mode: 0644]

diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644 (file)
index 0000000..cf9b6b9
--- /dev/null
@@ -0,0 +1,510 @@
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard.  To achieve this, non-free programs must
+be allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+^L
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at least
+    three years, to give the same user the materials specified in
+    Subsection 6a, above, for a charge no more than the cost of
+    performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+^L
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.1 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James
+  Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
index 80fcbe8b663b85f36f4699df197dc303664bc6b1..1005139d8365165903ac01b8dac011017346c5c9 100644 (file)
@@ -27,6 +27,7 @@ void mp3_init(struct audio_format_handler *);
        void aac_afh_init(struct audio_format_handler *);
 #endif
 
+void wma_afh_init(struct audio_format_handler *);
 /**
  * The list of supported audio formats.
  *
@@ -56,6 +57,10 @@ static struct audio_format_handler afl[] = {
                .init = aac_afh_init,
 #endif
        },
+       {
+               .name = "wma",
+               .init = wma_afh_init,
+       },
        {
                .name = NULL,
        }
diff --git a/bitstream.c b/bitstream.c
new file mode 100644 (file)
index 0000000..c4c465e
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Common bit I/O utils.
+ *
+ * Extracted 2009 from mplayer 2009-02-10 libavcodec/bitstream.c.
+ *
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
+ *
+ * Licensed under the GNU Lesser General Public License.
+ * For licencing details see COPYING.LIB.
+ */
+
+/**
+ * \file bitstream.c Bitstream API.
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <regex.h>
+
+#include "para.h"
+#include "error.h"
+#include "string.h"
+#include "wma.h"
+#include "bitstream.h"
+
+#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(struct vlc *vlc, int size)
+{
+       int idx;
+
+       idx = vlc->table_size;
+       vlc->table_size += size;
+       if (vlc->table_size > vlc->table_allocated) {
+               vlc->table_allocated += (1 << vlc->bits);
+               vlc->table = realloc(vlc->table,
+                       sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
+               if (!vlc->table)
+                       return -E_TABLE_ALLOC;
+       }
+       return idx;
+}
+
+static int build_table(struct vlc *vlc, int table_nb_bits,
+               int nb_codes, const void *bits, int bits_wrap, int bits_size,
+               const void *codes, int codes_wrap, int codes_size,
+               uint32_t code_prefix, int n_prefix)
+{
+       int ret, i, j, k, n, table_size, table_index, nb, n1, idx, code_prefix2,
+               symbol;
+       uint32_t code;
+       VLC_TYPE(*table)[2];
+
+       table_size = 1 << table_nb_bits;
+       ret = alloc_table(vlc, table_size);
+       if (ret < 0)
+               return ret;
+       table_index = ret;
+       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++) {
+               GET_DATA(n, bits, i, bits_wrap, bits_size);
+               GET_DATA(code, codes, i, codes_wrap, codes_size);
+               /* we accept tables with holes */
+               if (n <= 0)
+                       continue;
+               symbol = i;
+               /* if code matches the prefix, it is in the table */
+               n -= n_prefix;
+               code_prefix2 = code >> n;
+               if (n > 0 && code_prefix2 == code_prefix) {
+                       if (n <= table_nb_bits) {
+                               /* no need to add another table */
+                               j = (code << (table_nb_bits - n)) & (table_size - 1);
+                               nb = 1 << (table_nb_bits - n);
+                               for (k = 0; k < nb; k++) {
+                                       if (table[j][1] /* bits */ != 0)
+                                               return -E_BAD_CODES;
+                                       table[j][1] = n;        //bits
+                                       table[j][0] = symbol;
+                                       j++;
+                               }
+                       } else {
+                               n -= table_nb_bits;
+                               j = (code >> n) & ((1 << table_nb_bits) - 1);
+                               /* compute table size */
+                               n1 = -table[j][1];      //bits
+                               if (n > n1)
+                                       n1 = n;
+                               table[j][1] = -n1;      //bits
+                       }
+               }
+       }
+
+       /* second pass : fill auxillary tables recursively */
+       for (i = 0; i < table_size; i++) {
+               n = table[i][1];        //bits
+               if (n < 0) {
+                       n = -n;
+                       if (n > table_nb_bits) {
+                               n = table_nb_bits;
+                               table[i][1] = -n;       //bits
+                       }
+                       ret = build_table(vlc, n, nb_codes,
+                               bits, bits_wrap, bits_size,
+                               codes, codes_wrap, codes_size,
+                               (code_prefix << table_nb_bits) | i,
+                               n_prefix + table_nb_bits);
+                       if (ret < 0)
+                               return ret;
+                       idx = ret;
+                       /* note: realloc has been done, so reload tables */
+                       table = &vlc->table[table_index];
+                       table[i][0] = idx;      //code
+               }
+       }
+       return table_index;
+}
+
+/**
+ * Build VLC decoding tables suitable for use with get_vlc().
+ *
+ * \param nb_bits Set the 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.
+ *
+ * \param nb_codes Number of vlcs codes.
+ *
+ * \param bits Table which gives the size (in bits) of each
+ * vlc code.
+ *
+ * \param codes Table which gives the bit pattern of of each
+ * vlc code.
+ *
+ * \param bits_wrap The number of bytes between each entry of the
+ * 'bits' or 'codes' tables.
+ *
+ *
+ * \param bits_size The number of bytes of each entry of the
+ * 'bits' or 'codes' tables.
+ *
+ * \param codes_wrap Same as bits_wrap but uses the 'codes' table.
+ * \param codes_size Same as bits_size but for the 'codes' table.
+ *
+ * The wrap and size parameters allow to use any memory configuration and
+ * types (byte/word/long) to store the bits and codes tables.
+ */
+int init_vlc(struct 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)
+{
+       int ret;
+
+       PARA_INFO_LOG("nb_codes=%d\n", nb_codes);
+       vlc->bits = nb_bits;
+       vlc->table = NULL;
+       vlc->table_allocated = 0;
+       vlc->table_size = 0;
+       ret = build_table(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size,
+               codes, codes_wrap, codes_size, 0, 0);
+       if (ret < 0)
+               freep(&vlc->table);
+       return ret;
+}
+
+void free_vlc(struct vlc *vlc)
+{
+       freep(&vlc->table);
+}
diff --git a/bitstream.h b/bitstream.h
new file mode 100644 (file)
index 0000000..0a701d7
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Extracted 2009 from mplayer 2009-02-10 libavcodec/bitstream.h.
+ *
+ * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * Licensed under the GNU Lesser General Public License.
+ * For licencing details see COPYING.LIB.
+ */
+
+/** \file bitstream.h Bitstream structures and inline functions. */
+
+#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])
+
+# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
+# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
+
+/**
+ * Structure for bistream I/O.
+ *
+ * The buffer, buffer_end and size_in_bits fields must be present and are used
+ * by every reader.
+ */
+struct getbit_context {
+       const uint8_t *buffer, *buffer_end;
+       int index;
+       int size_in_bits;
+};
+
+#define VLC_TYPE int16_t
+
+struct vlc {
+       int bits;
+       VLC_TYPE(*table)[2];    ///< code, bits
+       int table_size, table_allocated;
+};
+
+#define MIN_CACHE_BITS 25
+
+/** Load \a gb into local variables. */
+#define OPEN_READER(name, gb)\
+       int name##_index= (gb)->index;\
+       int name##_cache= 0;\
+
+/** Store local vars in gb. */
+#define CLOSE_READER(name, gb)\
+       (gb)->index= name##_index;\
+
+/**
+ * Refill the internal cache from the bitstream.
+ *
+ * After this call at least MIN_CACHE_BITS will be available.
+ */
+#define UPDATE_CACHE(name, gb)\
+       name##_cache= AV_RB32( ((const uint8_t *)(gb)->buffer) \
+               + (name##_index >> 3) ) << (name##_index & 0x07);\
+
+/**
+ * Remove the next num bits from the cache.
+ *
+ * SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER).
+ */
+#define SKIP_CACHE(name, gb, num)\
+       name##_cache <<= (num);
+
+/**
+ * Increment the internal bit counter.
+ *
+ * \sa SKIP_CACHE, SKIP_BITS.
+ */
+#define SKIP_COUNTER(name, gb, num)\
+       name##_index += (num);\
+
+/**
+ * Skip over the next num bits.
+ *
+ * This is equivalent to SKIP_CACHE; SKIP_COUNTER.
+ */
+#define SKIP_BITS(name, gb, num)\
+       {\
+               SKIP_CACHE(name, gb, num)\
+               SKIP_COUNTER(name, gb, num)\
+       }\
+
+/** This is equivalent to SKIP_LAST_CACHE; SKIP_COUNTER. */
+#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
+
+/** Return the next num bits. */
+#define SHOW_UBITS(name, gb, num)\
+       NEG_USR32(name##_cache, num)
+
+static inline int get_bits_count(struct getbit_context *s)
+{
+       return s->index;
+}
+
+static inline void skip_bits_long(struct getbit_context *s, int n)
+{
+       s->index += n;
+}
+
+/**
+ * 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(struct getbit_context *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;
+}
+
+/**
+ * Show 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(struct getbit_context *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(struct getbit_context *s, int n)
+{
+       /* 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(struct getbit_context *s)
+{
+       int idx = s->index;
+       uint8_t result = s->buffer[idx >> 3];
+
+       result <<= (idx & 0x07);
+       result >>= 8 - 1;
+       idx++;
+       s->index = idx;
+       return result;
+}
+
+/**
+ * reads 0-32 bits.
+ */
+static inline unsigned int get_bits_long(struct getbit_context *s, int n)
+{
+       if (n <= 17)
+               return get_bits(s, n);
+       else {
+               int ret = get_bits(s, 16) << (n - 16);
+               return ret | get_bits(s, n - 16);
+       }
+}
+
+/**
+ * Initialize a getbit_context structure.
+ *
+ * \param buffer The bitstream buffer. It 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.
+ */
+static inline void init_get_bits(struct getbit_context *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;
+       s->index = 0;
+}
+
+int init_vlc(struct 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);
+
+void free_vlc(struct vlc *vlc);
+
+/**
+ *
+ * if the vlc code is invalid and max_depth=1 than no bits will be removed
+ * if the vlc code is invalid and max_depth>1 than the number of bits removed
+ * is undefined
+ */
+#define GET_VLC(code, name, gb, table, bits, max_depth)\
+{\
+    int n, index, nb_bits;\
+\
+    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)\
+}
index 2989189da1f560a7848bb7cecfe623ad94b6aec0..4583b1eb3fb5dfb251496bb15f6c70463009ad23 100644 (file)
@@ -90,7 +90,9 @@ playlist sha1 sched audiod grab_client filter_common wav_filter compress_filter
 http_recv dccp_recv recv_common write_common file_write audiod_command
 client_common recv stdout filter stdin audioc write client exec send_common ggo
 udp_recv udp_send color fec fecdec_filter prebuffer_filter mm
-server_command_list afs_command_list audiod_command_list"
+server_command_list afs_command_list audiod_command_list bitstream mdct wma_afh
+wma_common wmadec_filter
+"
 
 all_executables="server recv filter audioc write client afh"
 
@@ -106,9 +108,9 @@ senders=" http dccp udp"
 filter_cmdline_objs="add_cmdline(filter compress_filter amp_filter prebuffer_filter)"
 filter_errlist_objs="filter_common wav_filter compress_filter filter string
        stdin stdout sched fd amp_filter ggo fecdec_filter fec
-       prebuffer_filter time"
-filter_ldflags=""
-filters=" compress wav amp fecdec prebuffer"
+       prebuffer_filter time bitstream mdct wma_common wmadec_filter"
+filter_ldflags="-lm"
+filters=" compress wav amp fecdec wmadec prebuffer"
 
 audioc_cmdline_objs="add_cmdline(audioc)"
 audioc_errlist_objs="audioc string net fd"
@@ -118,12 +120,13 @@ audiod_cmdline_objs="add_cmdline(audiod compress_filter http_recv dccp_recv file
 audiod_errlist_objs="audiod signal string daemon stat net
        time grab_client filter_common wav_filter compress_filter amp_filter http_recv dccp_recv
        recv_common fd sched write_common file_write audiod_command crypt fecdec_filter
-       client_common ggo udp_recv color fec prebuffer_filter sha1 audiod_command_list"
+       client_common ggo udp_recv color fec prebuffer_filter sha1 audiod_command_list
+       bitstream mdct wma_common wmadec_filter"
 audiod_ldflags=""
 audiod_audio_formats=""
 
 afh_cmdline_objs="add_cmdline(afh)"
-afh_errlist_objs="afh string fd mp3_afh afh_common time"
+afh_errlist_objs="afh string fd mp3_afh afh_common time wma_afh wma_common"
 afh_ldflags=""
 
 server_cmdline_objs="add_cmdline(server)"
@@ -131,7 +134,7 @@ server_errlist_objs="server afh_common mp3_afh vss command net string signal
        time daemon crypt http_send close_on_fork mm
        ipc dccp_send fd user_list chunk_queue afs aft mood score attribute
        blob playlist sha1 sched acl send_common udp_send color fec
-       server_command_list afs_command_list"
+       server_command_list afs_command_list wma_afh wma_common"
 server_ldflags="-losl"
 server_audio_formats=" mp3"
 
diff --git a/error.h b/error.h
index 6881e692415ff5eb7a8641aef27bbb2baf14360e..7553699c534300c907d2989135fe1c8ff5d88cfa 100644 (file)
--- a/error.h
+++ b/error.h
@@ -34,12 +34,32 @@ DEFINE_ERRLIST_OBJECT_ENUM;
 #define SERVER_COMMAND_LIST_ERRORS
 #define AFS_COMMAND_LIST_ERRORS
 #define AUDIOD_COMMAND_LIST_ERRORS
+#define WMA_AFH_ERRORS
+#define WMA_COMMON_ERRORS
 
 extern const char **para_errlist[];
 
+#define WMADEC_FILTER_ERRORS \
+       PARA_ERROR(WMA_BAD_PARAMS, "invalid WMA parameters"), \
+       PARA_ERROR(WMA_OUTPUT_SPACE, "insufficient output space"), \
+       PARA_ERROR(WMA_BAD_SUPERFRAME, "invalid superframe"), \
+       PARA_ERROR(WMA_DECODE, "wma decode error"), \
+       PARA_ERROR(INCOHERENT_BLOCK_LEN, "incoherent block length"), \
+
+
+#define BITSTREAM_ERRORS \
+       PARA_ERROR(TABLE_ALLOC, "failed to allocate table"), \
+       PARA_ERROR(BAD_CODES, "detected incorrect codes")
+
+
+#define MDCT_ERRORS \
+       PARA_ERROR(FFT_BAD_PARAMS, "invalid params for fft"), \
+
+
 #define PREBUFFER_FILTER_ERRORS \
        PARA_ERROR(PREBUFFER_SYNTAX, "syntax error in prebuffer filter config"), \
 
+
 #define OSS_WRITE_ERRORS \
        PARA_ERROR(BAD_SAMPLE_FORMAT, "sample format not supported"), \
        PARA_ERROR(BAD_CHANNEL_COUNT, "channel count not supported"), \
diff --git a/mdct.c b/mdct.c
new file mode 100644 (file)
index 0000000..9964d4b
--- /dev/null
+++ b/mdct.c
@@ -0,0 +1,477 @@
+/*
+ * FFT/IFFT transforms.
+ *
+ * Extracted 2009 from mplayer 2009-02-10 libavcodec/fft.c and libavcodec/mdct.c
+ *
+ * Copyright (c) 2008 Loren Merritt
+ * Copyright (c) 2002 Fabrice Bellard
+ * Partly based on libdjbfft by D. J. Bernstein
+ *
+ * Licensed under the GNU Lesser General Public License.
+ * For licencing details see COPYING.LIB.
+ */
+
+/**
+ * \file fft.c FFT/MDCT transforms.
+ */
+
+#include <inttypes.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "para.h"
+#include "error.h"
+#include "string.h"
+#include "mdct.h"
+#include "wma.h"
+
+typedef float fftsample_t;
+
+#define DECLARE_ALIGNED(n,t,v)      t v __attribute__ ((aligned (n)))
+#define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v)
+#define M_SQRT1_2      0.70710678118654752440  /* 1/sqrt(2) */
+
+struct fft_complex {
+       fftsample_t re, im;
+};
+
+struct fft_context {
+       int nbits;
+       int inverse;
+       uint16_t *revtab;
+       struct fft_complex *exptab;
+       struct fft_complex *exptab1;    /* only used by SSE code */
+       struct fft_complex *tmp_buf;
+};
+
+struct mdct_context {
+       /** Size of MDCT (i.e. number of input data * 2). */
+       int n;
+       /** n = 2^n bits. */
+       int nbits;
+       /** pre/post rotation tables */
+       fftsample_t *tcos;
+       fftsample_t *tsin;
+       struct fft_context fft;
+};
+
+/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_16[8]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_32[16]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_64[32]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_128[64]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_256[128]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_512[256]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_1024[512]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_2048[1024]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_4096[2048]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_8192[4096]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_16384[8192]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_32768[16384]);
+DECLARE_ALIGNED_16(fftsample_t, ff_cos_65536[32768]);
+
+static fftsample_t *ff_cos_tabs[] = {
+       ff_cos_16, ff_cos_32, ff_cos_64, ff_cos_128, ff_cos_256,
+       ff_cos_512, ff_cos_1024, ff_cos_2048, ff_cos_4096, ff_cos_8192,
+       ff_cos_16384, ff_cos_32768, ff_cos_65536,
+};
+
+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;
+}
+
+#define sqrthalf (float)M_SQRT1_2
+
+#define BF(x,y,a,b) {\
+    x = a - b;\
+    y = a + b;\
+}
+
+#define BUTTERFLIES(a0,a1,a2,a3) {\
+    BF(t3, t5, t5, t1);\
+    BF(a2.re, a0.re, a0.re, t5);\
+    BF(a3.im, a1.im, a1.im, t3);\
+    BF(t4, t6, t2, t6);\
+    BF(a3.re, a1.re, a1.re, t4);\
+    BF(a2.im, a0.im, a0.im, t6);\
+}
+
+// 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_t r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
+    BF(t3, t5, t5, t1);\
+    BF(a2.re, a0.re, r0, t5);\
+    BF(a3.im, a1.im, i1, t3);\
+    BF(t4, t6, t2, t6);\
+    BF(a3.re, a1.re, r1, t4);\
+    BF(a2.im, a0.im, i0, t6);\
+}
+
+#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
+    t1 = a2.re * wre + a2.im * wim;\
+    t2 = a2.im * wre - a2.re * wim;\
+    t5 = a3.re * wre - a3.im * wim;\
+    t6 = a3.im * wre + a3.re * wim;\
+    BUTTERFLIES(a0,a1,a2,a3)\
+}
+
+#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
+    t1 = a2.re;\
+    t2 = a2.im;\
+    t5 = a3.re;\
+    t6 = a3.im;\
+    BUTTERFLIES(a0,a1,a2,a3)\
+}
+
+/* z[0...8n-1], w[1...2n-1] */
+#define PASS(name)\
+static void name(struct fft_complex *z, const fftsample_t *wre, unsigned int n)\
+{\
+    fftsample_t t1, t2, t3, t4, t5, t6;\
+    int o1 = 2*n;\
+    int o2 = 4*n;\
+    int o3 = 6*n;\
+    const fftsample_t *wim = wre+o1;\
+    n--;\
+\
+    TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
+    TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
+    do {\
+        z += 2;\
+        wre += 2;\
+        wim -= 2;\
+        TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
+        TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
+    } while(--n);\
+}
+
+PASS(pass)
+#undef BUTTERFLIES
+#define BUTTERFLIES BUTTERFLIES_BIG
+
+#define DECL_FFT(n,n2,n4)\
+static void fft##n(struct fft_complex *z)\
+{\
+    fft##n2(z);\
+    fft##n4(z+n4*2);\
+    fft##n4(z+n4*3);\
+    pass(z,ff_cos_##n,n4/2);\
+}
+static void fft4(struct fft_complex *z)
+{
+       fftsample_t t1, t2, t3, t4, t5, t6, t7, t8;
+
+       BF(t3, t1, z[0].re, z[1].re);
+       BF(t8, t6, z[3].re, z[2].re);
+       BF(z[2].re, z[0].re, t1, t6);
+       BF(t4, t2, z[0].im, z[1].im);
+       BF(t7, t5, z[2].im, z[3].im);
+       BF(z[3].im, z[1].im, t4, t8);
+       BF(z[3].re, z[1].re, t3, t7);
+       BF(z[2].im, z[0].im, t2, t5);
+}
+
+static void fft8(struct fft_complex *z)
+{
+       fftsample_t t1, t2, t3, t4, t5, t6, t7, t8;
+
+       fft4(z);
+
+       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);
+
+       TRANSFORM(z[1], z[3], z[5], z[7], sqrthalf, sqrthalf);
+}
+
+static void fft16(struct fft_complex *z)
+{
+       fftsample_t t1, t2, t3, t4, t5, t6;
+
+       fft8(z);
+       fft4(z + 8);
+       fft4(z + 12);
+
+       TRANSFORM_ZERO(z[0], z[4], z[8], z[12]);
+       TRANSFORM(z[2], z[6], z[10], z[14], sqrthalf, sqrthalf);
+       TRANSFORM(z[1], z[5], z[9], z[13], ff_cos_16[1], ff_cos_16[3]);
+       TRANSFORM(z[3], z[7], z[11], z[15], ff_cos_16[3], ff_cos_16[1]);
+}
+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)
+DECL_FFT(8192, 4096, 2048)
+DECL_FFT(16384, 8192, 4096)
+DECL_FFT(32768, 16384, 8192)
+DECL_FFT(65536, 32768, 16384)
+
+static void (*fft_dispatch[]) (struct fft_complex *) =
+{
+       fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
+       fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
+};
+
+static void fft(struct fft_context *s, struct fft_complex *z)
+{
+       fft_dispatch[s->nbits - 2] (z);
+}
+
+/* complex multiplication: p = a * b */
+#define CMUL(pre, pim, are, aim, bre, bim) \
+{\
+    fftsample_t _are = (are);\
+    fftsample_t _aim = (aim);\
+    fftsample_t _bre = (bre);\
+    fftsample_t _bim = (bim);\
+    (pre) = _are * _bre - _aim * _bim;\
+    (pim) = _are * _bim + _aim * _bre;\
+}
+
+/**
+ * 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.
+ */
+static void imdct_half(struct mdct_context *s, fftsample_t *output,
+               const fftsample_t *input)
+{
+       int k, n8, n4, n2, n, j;
+       const uint16_t *revtab = s->fft.revtab;
+       const fftsample_t *tcos = s->tcos;
+       const fftsample_t *tsin = s->tsin;
+       const fftsample_t *in1, *in2;
+       struct fft_complex *z = (struct fft_complex *)output;
+
+       n = 1 << s->nbits;
+       n2 = n >> 1;
+       n4 = n >> 2;
+       n8 = n >> 3;
+
+       /* pre rotation */
+       in1 = input;
+       in2 = input + n2 - 1;
+       for (k = 0; k < n4; k++) {
+               j = revtab[k];
+               CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
+               in1 += 2;
+               in2 -= 2;
+       }
+       fft(&s->fft, z);
+
+       /* post rotation + reordering */
+       output += n4;
+       for (k = 0; k < n8; k++) {
+               fftsample_t r0, i0, r1, i1;
+               CMUL(r0, i1, z[n8 - k - 1].im, z[n8 - k - 1].re,
+                       tsin[n8 - k - 1], tcos[n8 - k - 1]);
+               CMUL(r1, i0, z[n8 + k].im, z[n8 + k].re, tsin[n8 + k],
+                       tcos[n8 + k]);
+               z[n8 - k - 1].re = r0;
+               z[n8 - k - 1].im = i0;
+               z[n8 + k].re = r1;
+               z[n8 + k].im = i1;
+       }
+}
+
+/**
+ * Compute the inverse MDCT of size N = 2^nbits.
+ *
+ * \param output N samples.
+ * \param input N/2 samples.
+ */
+void imdct(struct mdct_context *s, float *output, const float *input)
+{
+       int k;
+       int n = 1 << s->nbits;
+       int n2 = n >> 1;
+       int n4 = n >> 2;
+
+       imdct_half(s, output + n4, input);
+
+       for (k = 0; k < n4; k++) {
+               output[k] = -output[n2 - k - 1];
+               output[n - k - 1] = output[n2 + k];
+       }
+}
+
+static int fft_init(struct fft_context *s, int nbits, int inverse)
+{
+       int i, j, m, n;
+       float alpha, c1, s1, s2;
+       int split_radix = 1;
+
+       if (nbits < 2 || nbits > 16)
+               return -E_FFT_BAD_PARAMS;
+       s->nbits = nbits;
+       n = 1 << nbits;
+
+       s->tmp_buf = NULL;
+       s->exptab = para_malloc((n / 2) * sizeof(struct fft_complex));
+       s->revtab = para_malloc(n * sizeof(uint16_t));
+       s->inverse = inverse;
+
+       s2 = inverse ? 1.0 : -1.0;
+
+       s->exptab1 = NULL;
+
+       if (split_radix) {
+               for (j = 4; j <= nbits; j++) {
+                       int k = 1 << j;
+                       double freq = 2 * M_PI / k;
+                       fftsample_t *tab = ff_cos_tabs[j - 4];
+                       for (i = 0; i <= k / 4; i++)
+                               tab[i] = cos(i * freq);
+                       for (i = 1; i < k / 4; i++)
+                               tab[k / 2 - i] = tab[i];
+               }
+               for (i = 0; i < n; i++)
+                       s->revtab[-split_radix_permutation(
+                               i, n, s->inverse) & (n - 1)] = i;
+               s->tmp_buf = para_malloc(n * sizeof(struct fft_complex));
+       } else {
+               int np, nblocks, np2, l;
+               struct fft_complex *q;
+
+               for (i = 0; i < (n / 2); i++) {
+                       alpha = 2 * M_PI * (float) i / (float) n;
+                       c1 = cos(alpha);
+                       s1 = sin(alpha) * s2;
+                       s->exptab[i].re = c1;
+                       s->exptab[i].im = s1;
+               }
+
+               np = 1 << nbits;
+               nblocks = np >> 3;
+               np2 = np >> 1;
+               s->exptab1 = para_malloc(np * 2 * sizeof(struct fft_complex));
+               q = s->exptab1;
+               do {
+                       for (l = 0; l < np2; l += 2 * nblocks) {
+                               *q++ = s->exptab[l];
+                               *q++ = s->exptab[l + nblocks];
+
+                               q->re = -s->exptab[l].im;
+                               q->im = s->exptab[l].re;
+                               q++;
+                               q->re = -s->exptab[l + nblocks].im;
+                               q->im = s->exptab[l + nblocks].re;
+                               q++;
+                       }
+                       nblocks = nblocks >> 1;
+               } while (nblocks != 0);
+               freep(&s->exptab);
+
+               /* compute bit reverse table */
+               for (i = 0; i < n; i++) {
+                       m = 0;
+                       for (j = 0; j < nbits; j++) {
+                               m |= ((i >> j) & 1) << (nbits - j - 1);
+                       }
+                       s->revtab[i] = m;
+               }
+       }
+       return 0;
+}
+
+static void fft_end(struct fft_context *ctx)
+{
+       freep(&ctx->revtab);
+       freep(&ctx->exptab);
+       freep(&ctx->exptab1);
+       freep(&ctx->tmp_buf);
+}
+
+DECLARE_ALIGNED(16, float, ff_sine_128[128]);
+DECLARE_ALIGNED(16, float, ff_sine_256[256]);
+DECLARE_ALIGNED(16, float, ff_sine_512[512]);
+DECLARE_ALIGNED(16, float, ff_sine_1024[1024]);
+DECLARE_ALIGNED(16, float, ff_sine_2048[2048]);
+DECLARE_ALIGNED(16, float, ff_sine_4096[4096]);
+
+float *ff_sine_windows[6] = {
+       ff_sine_128, ff_sine_256, ff_sine_512, ff_sine_1024,
+       ff_sine_2048, ff_sine_4096
+};
+
+// Generate a sine window.
+void sine_window_init(float *window, int n)
+{
+       int i;
+
+       for (i = 0; i < n; i++)
+               window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n)));
+}
+
+/**
+ * Init MDCT or IMDCT computation.
+ */
+int mdct_init(int nbits, int inverse, struct mdct_context **result)
+{
+       int ret, n, n4, i;
+       double alpha;
+       struct mdct_context *s;
+
+       s = para_malloc(sizeof(*s));
+       memset(s, 0, sizeof(*s));
+       n = 1 << nbits;
+       s->nbits = nbits;
+       s->n = n;
+       n4 = n >> 2;
+       s->tcos = para_malloc(n4 * sizeof(fftsample_t));
+       s->tsin = para_malloc(n4 * sizeof(fftsample_t));
+
+       for (i = 0; i < n4; i++) {
+               alpha = 2 * M_PI * (i + 1.0 / 8.0) / n;
+               s->tcos[i] = -cos(alpha);
+               s->tsin[i] = -sin(alpha);
+       }
+       ret = fft_init(&s->fft, s->nbits - 2, inverse);
+       if (ret < 0)
+               goto fail;
+       *result = s;
+       return 0;
+fail:
+       freep(&s->tcos);
+       freep(&s->tsin);
+       free(s);
+       return ret;
+}
+
+void mdct_end(struct mdct_context *ctx)
+{
+       freep(&ctx->tcos);
+       freep(&ctx->tsin);
+       fft_end(&ctx->fft);
+       free(ctx);
+}
diff --git a/mdct.h b/mdct.h
new file mode 100644 (file)
index 0000000..ce34688
--- /dev/null
+++ b/mdct.h
@@ -0,0 +1,7 @@
+struct mdct_context;
+
+float *ff_sine_windows[6];
+void sine_window_init(float *window, int n);
+int mdct_init(int nbits, int inverse, struct mdct_context **result);
+void imdct(struct mdct_context *s, float *output, const float *input);
+void mdct_end(struct mdct_context *s);
index 4583caaba794d80b608b5d2cfa48859765d24821..6a17f05655297e0393a590d352b35035f6f4ea64 100644 (file)
--- a/ogg_afh.c
+++ b/ogg_afh.c
@@ -105,7 +105,7 @@ static int read_vorbis_info(ogg_sync_state *oss, struct afh_info *afhi)
 out:
        vorbis_info_clear(&vi);
        vorbis_comment_clear(&vc);
-       ogg_stream_clear(&stream);
+       //ogg_stream_clear(&stream);
        return ret;
 }
 
index bb63120184c79b44270a4ae1ba671e6dd74de5e1..77f2f2a17d27002b0fcf608a4b615f6beaa83b01 100644 (file)
--- a/string.c
+++ b/string.c
@@ -135,6 +135,13 @@ __must_check __printf_1_2 __malloc char *make_message(const char *fmt, ...)
        return msg;
 }
 
+void freep(void *arg)
+{
+       void **ptr = (void **)arg;
+       free(*ptr);
+       *ptr = NULL;
+}
+
 /**
  * Paraslash's version of strcat().
  *
index 922ba696d18ed4dded4d037bdfba3a96b23aabb3..9dbe9420e27dbf5989a6f18d4eb4e0d48d51d581 100644 (file)
--- a/string.h
+++ b/string.h
@@ -82,3 +82,4 @@ int read_size_header(const char *buf);
 int create_argv(const char *buf, const char *delim, char ***result);
 void free_argv(char **argv);
 int para_regcomp(regex_t *preg, const char *regex, int cflags);
+void freep(void *arg);
diff --git a/wma.h b/wma.h
new file mode 100644 (file)
index 0000000..c4703c2
--- /dev/null
+++ b/wma.h
@@ -0,0 +1,24 @@
+/**
+ * Information contained in an asf audio file header.
+ *
+ * Both para_filter and para_afh need to read the header.
+ */
+struct asf_header_info {
+       /** The size of the audio file header. */
+       int header_len;
+       int audio_stream_info_start;
+       uint8_t channels;
+       uint16_t sample_rate;
+       uint16_t block_align;
+       uint32_t bit_rate;
+       uint32_t flags1;
+       uint16_t flags2;
+};
+
+/* wma_common.c */
+int wma_log2(unsigned int v);
+const char *search_pattern(const char *pattern, int pattern_len,
+               const char *buf, int buf_size);
+int read_asf_header(char *buf, int loaded, struct asf_header_info *ahi);
+#define M_PI           3.14159265358979323846  /* pi */
+#define WMA_FRAME_SKIP 31
diff --git a/wma_afh.c b/wma_afh.c
new file mode 100644 (file)
index 0000000..335ab89
--- /dev/null
+++ b/wma_afh.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2009 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file wma_afh.c The audio format handler for WMA files. */
+
+#include <stdlib.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <regex.h>
+
+#include "para.h"
+#include "error.h"
+#include "afh.h"
+#include "portable_io.h"
+#include "string.h"
+#include "wma.h"
+
+#define FOR_EACH_FRAME(_f, _buf, _size, _ba) for (_f = (_buf); \
+       _f + (_ba) + WMA_FRAME_SKIP < (_buf) + (_size); \
+       _f += (_ba) + WMA_FRAME_SKIP)
+
+static int count_frames(const char *buf, int buf_size, int block_align,
+       long unsigned *num_superframes)
+{
+       int count = 0, step = block_align + WMA_FRAME_SKIP;
+       const uint8_t *p = (uint8_t *)buf + WMA_FRAME_SKIP;
+
+
+       if (buf_size <= WMA_FRAME_SKIP) {
+               if (num_superframes)
+                       *num_superframes = 0;
+               return 0;
+       }
+       count = 0;
+       step = block_align + WMA_FRAME_SKIP;
+       p = (uint8_t *)buf + WMA_FRAME_SKIP;
+
+       FOR_EACH_FRAME(p, (uint8_t *)buf, buf_size, block_align)
+               count += p[WMA_FRAME_SKIP] & 0x0f;
+       PARA_DEBUG_LOG("%d frames\n", count);
+       if (num_superframes) {
+               *num_superframes = buf_size / step;
+               PARA_DEBUG_LOG("%lu superframes\n", *num_superframes);
+       }
+       return count;
+}
+
+/*
+ * put_utf8() and get_str16() below are based on macros in libavutil/common.h
+ * of the mplayer source code, copyright (c) 2006 Michael Niedermayer
+ * <michaelni@gmx.at>.
+ */
+
+/*
+ * Convert a 32-bit Unicode character to its UTF-8 encoded form.
+ *
+ * Writes up to 4 bytes for values in the valid UTF-8 range and up to 7 bytes
+ * in the general case, depending on the length of the converted Unicode
+ * character.
+ *
+ * \param result Where the converted UTF-8 bytes are written.
+ */
+static int put_utf8(uint32_t val, char *result)
+{
+       char *out = result;
+       int bytes, shift;
+       uint32_t in = val;
+
+       if (in < 0x80) {
+               *out++ = in;
+               return 1;
+       }
+       bytes = (wma_log2(in) + 4) / 5;
+       shift = (bytes - 1) * 6;
+       *out++ = (256 - (256 >> bytes)) | (in >> shift);
+       while (shift >= 6) {
+               shift -= 6;
+               *out++ = 0x80 | ((in >> shift) & 0x3f);
+       }
+       return out - result;
+}
+
+static void get_str16(const char *in, int len, char *out, int out_size)
+{
+       const char *p = in;
+       char *q = out;
+
+       len /= 2;
+       while (len-- && q + 7 + 1 < out + out_size) {
+               uint32_t x = read_u16(p);
+               p += 2;
+               q += put_utf8(x, q);
+               if (x == 0)
+                       return;
+       }
+       *q = '\0';
+}
+
+static const char comment_header[] = {
+       0x33, 0x26, 0xb2, 0x75, 0x8E, 0x66, 0xCF, 0x11,
+       0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c
+};
+
+static const char extended_content_header[] = {
+       0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11,
+       0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50
+};
+
+static const char year_tag_header[] = { /* WM/Year */
+       0x57, 0x00, 0x4d, 0x00, 0x2f, 0x00, 0x59, 0x00,
+       0x65, 0x00, 0x61, 0x00, 0x72, 0x00
+};
+
+static const char album_tag_header[] = { /* WM/AlbumTitle */
+       0x57, 0x00, 0x4d, 0x00, 0x2f, 0x00, 0x41, 0x00,
+       0x6c, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6d, 0x00,
+       0x54, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6c, 0x00,
+       0x65, 0x00
+};
+
+static void read_asf_tags(const char *buf, int buf_size, struct taginfo *ti)
+{
+       const char *p, *end = buf + buf_size;
+       char tag[255];
+
+       p = search_pattern(comment_header, sizeof(comment_header),
+               buf, buf_size);
+       if (p) {
+               int len1, len2, len3, len4, len5;
+               p += 24;
+               len1 = read_u16(p);
+               p += 2;
+               len2 = read_u16(p);
+               p += 2;
+               len3 = read_u16(p);
+               p += 2;
+               len4 = read_u16(p);
+               p += 2;
+               len5 = read_u16(p);
+               p += 2;
+               /* TODO: Check len values */
+               get_str16(p, len1, tag, sizeof(tag));
+               ti->title = para_strdup(tag);
+               PARA_INFO_LOG("title: %s\n", tag);
+               get_str16(p + len1, len2, tag, sizeof(tag));
+               ti->artist = para_strdup(tag);
+               PARA_INFO_LOG("artist: %s\n", tag);
+               get_str16(p + len1 + len2 + len3 + len4, len5, tag, sizeof(tag));
+               ti->comment = para_strdup(tag);
+               PARA_INFO_LOG("comment: %s\n", tag);
+       } else
+               PARA_NOTICE_LOG("comment header not found\n");
+       p = search_pattern(extended_content_header, sizeof(extended_content_header),
+               buf, buf_size);
+       if (p) {
+               const char *q;
+
+               q = search_pattern(year_tag_header, sizeof(year_tag_header),
+                       p, end - p);
+               if (q) {
+                       const char *r = q + sizeof(year_tag_header) + 6;
+                       get_str16(r, end - r, tag, sizeof(tag));
+                       ti->year = para_strdup(tag);
+                       PARA_INFO_LOG("year: %s\n", tag);
+               }
+               q = search_pattern(album_tag_header, sizeof(album_tag_header),
+                       p, end - p);
+               if (q) {
+                       const char *r = q + sizeof(album_tag_header) + 6;
+                       get_str16(r, end - r, tag, sizeof(tag));
+                       ti->album = para_strdup(tag);
+                       PARA_INFO_LOG("album: %s\n", tag);
+               }
+               return;
+       } else
+               PARA_NOTICE_LOG("extended content header not found\n");
+
+}
+
+static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align,
+               struct afh_info *afhi)
+{
+       const uint8_t *f, *start = (uint8_t *)buf;
+       int i, j, frames_per_chunk, chunk_time;
+       size_t ct_size = 250;
+       afhi->chunk_table = para_malloc(ct_size * sizeof(uint32_t));
+       afhi->chunk_table[0] = 0;
+       afhi->chunk_table[1] = afhi->header_len;
+
+
+       int count = 0, num_frames;
+
+       num_frames = count_frames(buf, buf_size, block_align,
+               &afhi->chunks_total);
+       PARA_ERROR_LOG("%d frames\n", num_frames);
+       afhi->seconds_total = num_frames * 2048 /* FIXME */
+               / afhi->frequency;
+       frames_per_chunk = num_frames / afhi->chunks_total;
+       i = 0;
+       j = 1;
+       FOR_EACH_FRAME(f, start, buf_size, block_align) {
+               count += f[WMA_FRAME_SKIP] & 0x0f;
+               while (count > j * frames_per_chunk) {
+                       j++;
+                       if (j >= ct_size) {
+                               ct_size *= 2;
+                               afhi->chunk_table = para_realloc(
+                                       afhi->chunk_table,
+                                       ct_size * sizeof(uint32_t));
+                       }
+                       PARA_DEBUG_LOG("ct[%d]: %zu\n", j, f - start);
+                       afhi->chunk_table[j] = f - start;
+               }
+       }
+       afhi->chunks_total = j;
+       chunk_time = num_frames * 1000 / afhi->frequency * 2048
+               / afhi->chunks_total;
+       PARA_ERROR_LOG("ct: %d\n", chunk_time);
+       afhi->chunk_tv.tv_sec = chunk_time / 1000;
+       afhi->chunk_tv.tv_usec = (chunk_time % 1000) * 1000;
+       //set_chunk_tv(num_frames, j, afhi->frequency, &afhi->chunk_tv);
+       return 1;
+}
+
+static int wma_get_file_info(char *map, size_t numbytes, __a_unused int fd,
+       struct afh_info *afhi)
+{
+       int ret;
+       struct asf_header_info ahi;
+
+       ret = read_asf_header(map, numbytes, &ahi);
+       if (ret < 0)
+               return ret;
+       afhi->bitrate = ahi.bit_rate / 1000;
+       afhi->frequency = ahi.sample_rate;
+       afhi->channels = ahi.channels;
+       afhi->header_len = ahi.header_len;
+       afhi->header_offset = 0;
+       read_asf_tags(map, ahi.header_len, &afhi->tags);
+       wma_make_chunk_table(map + ahi.header_len, numbytes - ahi.header_len,
+               ahi.block_align, afhi);
+       return 0;
+}
+
+static const char* wma_suffixes[] = {"wma", NULL};
+
+/**
+ * The init function of the wma audio format handler.
+ *
+ * \param afh Pointer to the struct to initialize.
+ */
+void wma_afh_init(struct audio_format_handler *afh)
+{
+       afh->get_file_info = wma_get_file_info;
+       afh->suffixes = wma_suffixes;
+}
diff --git a/wma_common.c b/wma_common.c
new file mode 100644 (file)
index 0000000..9a7a22a
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2009 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file wma_common.c Functions used by both the WMA afh and decoder. */
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "para.h"
+#include "error.h"
+#include "afh.h"
+#include "portable_io.h"
+#include "mdct.h"
+#include "wma.h"
+
+const char *search_pattern(const char *pattern, int pattern_len, const char *buf, int buf_size)
+{
+       const char *p, *end = buf + buf_size;
+
+       if (pattern_len > buf_size)
+               return NULL;
+       for (p = buf; p + pattern_len < end; p++) {
+               if (memcmp(p, pattern, pattern_len))
+                       continue;
+               PARA_DEBUG_LOG("found %d byte pattern@%d\n",
+                       pattern_len, p - buf);
+               return p;
+       }
+       PARA_NOTICE_LOG("%d byte pattern not found\n", pattern_len);
+       return NULL;
+}
+
+/*
+   40 9e 69 f8 4d 5b cf 11  a8 fd 00 80 5f 5c 44 2b
+ */
+static int find_audio_stream_info(const char *buf, int len)
+{
+       const char pattern[] = {0x40, 0x9e, 0x69, 0xf8};
+       const char *p = search_pattern(pattern, sizeof(pattern), buf, len);
+
+       if (!p) {
+               PARA_NOTICE_LOG("audio stream guid not found");
+               return -1;
+       }
+       PARA_DEBUG_LOG("found audio stream guid@%0zx\n", p - buf);
+       return p - buf;
+}
+
+static int read_header_len(char *buf, int len)
+{
+       uint16_t header_len;
+
+       if (len < 18)
+               return -1;
+       header_len = read_u16(buf + 16) + 46;
+       if (header_len > len)
+               return -2;
+       PARA_DEBUG_LOG("header_len: %d\n", header_len);
+       return header_len;
+}
+
+int read_asf_header(char *buf, int loaded, struct asf_header_info *ahi)
+{
+       int ret;
+       char *start;
+
+       ret = read_header_len(buf, loaded);
+       if (ret < 0)
+               return ret;
+       ahi->header_len = ret;
+
+       ret = find_audio_stream_info(buf, ahi->header_len);
+       if (ret < 0)
+               return ret;
+       ahi->audio_stream_info_start = ret + 16;
+       start = buf + ahi->audio_stream_info_start;
+
+       ahi->channels = ((uint8_t *)start)[40];
+       ahi->sample_rate = read_u16(start + 42);
+       PARA_NOTICE_LOG("%d channels, sample rate: %d\n", ahi->channels,
+               ahi->sample_rate);
+
+       ahi->bit_rate = 8 * read_u16(start + 46);
+       PARA_INFO_LOG("bit rate: %d\n", ahi->bit_rate);
+
+       ahi->block_align = read_u16(start + 50);
+       PARA_INFO_LOG("block_align: %d\n", ahi->block_align);
+
+       ahi->flags1 = read_u32(start + 56);
+       ahi->flags2 = read_u16(start + 60);
+       PARA_INFO_LOG("read_asf_header: flags1: %d, flag2: %d\n",
+               ahi->flags1, ahi->flags2);
+       return 42;
+}
+
+const uint8_t 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
+};
+
+int wma_log2(unsigned int v)
+{
+       int n = 0;
+       if (v & 0xffff0000) {
+               v >>= 16;
+               n += 16;
+       }
+       if (v & 0xff00) {
+               v >>= 8;
+               n += 8;
+       }
+       n += log2_tab[v];
+
+       return n;
+}
diff --git a/wmadata.h b/wmadata.h
new file mode 100644 (file)
index 0000000..1dfa45d
--- /dev/null
+++ b/wmadata.h
@@ -0,0 +1,1457 @@
+/*
+ * 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.
+ */
+
+struct coef_vlc_table {
+       /** Total number of codes. */
+       int n;
+       /** Number of levels. */
+       int max_level;
+       /** VLC bit values. */
+       const uint32_t *huffcodes;
+       /** VLC bit size. */
+       const uint8_t *huffbits;
+       /* Table to build run/level tables. */
+       const uint16_t *levels;
+};
+
+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,},
+};
+
+const uint16_t ff_wma_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,
+};
+
+const uint8_t ff_wma_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,
+};
+
+#define NB_LSP_COEFS 10
+
+const float ff_wma_lsp_codebook[NB_LSP_COEFS][16] = {
+       {1.98732877, 1.97944528, 1.97179088, 1.96260549, 1.95038374, 1.93336114,
+        1.90719232, 1.86191415,},
+       {1.97260000, 1.96083160, 1.94982586, 1.93806164, 1.92516608, 1.91010199,
+        1.89232331, 1.87149812,
+        1.84564818, 1.81358067, 1.77620070, 1.73265264, 1.67907855, 1.60959081,
+        1.50829650, 1.33120330,},
+       {1.90109110, 1.86482426, 1.83419671, 1.80168452, 1.76650116, 1.72816320,
+        1.68502700, 1.63738256,
+        1.58501580, 1.51795181, 1.43679906, 1.33950585, 1.24176208, 1.12260729,
+        0.96749668, 0.74048265,},
+       {1.76943864, 1.67822463, 1.59946365, 1.53560582, 1.47470796, 1.41210167,
+        1.34509536, 1.27339507,
+        1.19303814, 1.09765169, 0.98818722, 0.87239446, 0.74369172, 0.59768184,
+        0.43168630, 0.17977021,},
+       {1.43428349, 1.32038354, 1.21074086, 1.10577988, 1.00561746, 0.90335924,
+        0.80437489, 0.70709671,
+        0.60427395, 0.49814048, 0.38509539, 0.27106800, 0.14407416, 0.00219910,
+        -0.16725141, -0.36936085,},
+       {0.99895687, 0.84188166, 0.70753739, 0.57906595, 0.47055563, 0.36966965,
+        0.26826648, 0.17163380,
+        0.07208392, -0.03062936, -1.40037388, -0.25128968, -0.37213937,
+        -0.51075646, -0.64887512, -0.80308031,},
+       {0.26515280, 0.06313551, -0.08872080, -0.21103548, -0.31069678,
+        -0.39680323, -0.47223474, -0.54167135,
+        -0.61444740, -0.68943343, -0.76580211, -0.85170082, -0.95289061,
+        -1.06514703, -1.20510707, -1.37617746,},
+       {-0.53940301, -0.73770929, -0.88424876, -1.01117930, -1.13389091,
+        -1.26830073, -1.42041987, -1.62033919,
+        -1.10158808, -1.16512566, -1.23337128, -1.30414401, -1.37663312,
+        -1.46853845, -1.57625798, -1.66893638,},
+       {-0.38601997, -0.56009350, -0.66978483, -0.76028471, -0.83846064,
+        -0.90868087, -0.97408881, -1.03694962,},
+       {-1.56144989, -1.65944032, -1.72689685, -1.77857740, -1.82203011,
+        -1.86220079, -1.90283983, -1.94820479,},
+};
+
+const uint32_t ff_wma_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,
+};
+
+const uint8_t ff_wma_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,
+};
+
+#define DEF_COEF_TABLE(_x) { \
+               .n = sizeof(coef ## _x ## _huffbits), \
+               .max_level = sizeof(levels ## _x) / 2, \
+               .huffcodes = coef ## _x ## _huffcodes, \
+               .huffbits = coef ## _x ##_huffbits, \
+               .levels = levels ## _x}
+
+static const struct coef_vlc_table coef_vlcs[6] = {
+       DEF_COEF_TABLE(0), DEF_COEF_TABLE(1), DEF_COEF_TABLE(2),
+       DEF_COEF_TABLE(3), DEF_COEF_TABLE(4), DEF_COEF_TABLE(5)
+};
diff --git a/wmadec_filter.c b/wmadec_filter.c
new file mode 100644 (file)
index 0000000..8298296
--- /dev/null
@@ -0,0 +1,1333 @@
+/*
+ * WMA compatible decoder
+ *
+ * Extracted 2009 from the mplayer source code 2009-02-10.
+ *
+ * Copyright (c) 2002 The FFmpeg Project
+ *
+ * Licensed under the GNU Lesser General Public License.
+ * For licencing details see COPYING.LIB.
+ */
+
+/** * \file wmadec_filter.c paraslash's WMA decoder.  */
+
+/*
+ * This decoder handles Microsoft Windows Media Audio data version 2.
+ */
+
+#define _XOPEN_SOURCE 600
+
+#include <sys/time.h>
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <regex.h>
+
+#include "para.h"
+#include "error.h"
+#include "list.h"
+#include "ggo.h"
+#include "string.h"
+#include "sched.h"
+#include "filter.h"
+#include "bitstream.h"
+#include "mdct.h"
+#include "wma.h"
+#include "wmadata.h"
+
+
+/* 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
+
+/* XXX: is it a suitable value ? */
+#define MAX_CODED_SUPERFRAME_SIZE 16384
+
+#define MAX_CHANNELS 2
+
+#define NOISE_TAB_SIZE 8192
+
+#define LSP_POW_BITS 7
+
+struct private_wmadec_data {
+       struct asf_header_info ahi;
+       struct getbit_context gb;
+       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;
+       struct 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];
+       struct 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 */
+       struct vlc coef_vlc[2];
+       uint16_t *run_table[2];
+       uint16_t *level_table[2];
+       uint16_t *int_table[2];
+       const struct coef_vlc_table *coef_vlcs[2];
+       /* frame info */
+       int frame_len;          ///< frame length in samples
+       int frame_len_bits;     ///< frame_len = 1 << frame_len_bits
+       int nb_block_sizes;     ///< number of block sizes
+       /* 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
+       float exponents[MAX_CHANNELS][BLOCK_MAX_SIZE];
+       float max_exponent[MAX_CHANNELS];
+       int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE];
+       float coefs[MAX_CHANNELS][BLOCK_MAX_SIZE];
+       float output[BLOCK_MAX_SIZE * 2];
+       struct mdct_context *mdct_ctx[BLOCK_NB_SIZES];
+       float *windows[BLOCK_NB_SIZES];
+       /* output buffer for one frame and the last for IMDCT windowing */
+       float frame_out[MAX_CHANNELS][BLOCK_MAX_SIZE * 2];
+       /* last frame info */
+       uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */
+       int last_bitoffset;
+       int last_superframe_len;
+       float noise_table[NOISE_TAB_SIZE];
+       int noise_index;
+       float noise_mult;       /* XXX: suppress that and integrate it in the noise array */
+       /* lsp_to_curve tables */
+       float lsp_cos_table[BLOCK_MAX_SIZE];
+       float lsp_pow_e_table[256];
+       float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
+       float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
+};
+
+#define EXPVLCBITS 8
+#define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS)
+
+#define HGAINVLCBITS 9
+#define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS)
+
+#define VLCBITS 9
+#define VLCMAX ((22+VLCBITS-1)/VLCBITS)
+
+static int wmadec_cleanup(struct private_wmadec_data *s)
+{
+       int i;
+
+       for (i = 0; i < s->nb_block_sizes; i++)
+               mdct_end(s->mdct_ctx[i]);
+
+       if (s->use_exp_vlc)
+               free_vlc(&s->exp_vlc);
+       if (s->use_noise_coding)
+               free_vlc(&s->hgain_vlc);
+       for (i = 0; i < 2; i++) {
+               free_vlc(&s->coef_vlc[i]);
+               free(s->run_table[i]);
+               free(s->level_table[i]);
+               free(s->int_table[i]);
+       }
+       return 0;
+}
+
+/* XXX: use same run/length optimization as mpeg decoders */
+//FIXME maybe split decode / encode or pass flag
+static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table,
+               uint16_t **plevel_table, uint16_t **pint_table,
+               const struct coef_vlc_table *vlc_table)
+{
+       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, *int_table;
+       int i, l, j, k, level;
+
+       init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4);
+
+       run_table = para_malloc(n * sizeof (uint16_t));
+       level_table = para_malloc(n * sizeof (uint16_t));
+       int_table = para_malloc(n * sizeof (uint16_t));
+       i = 2;
+       level = 1;
+       k = 0;
+       while (i < n) {
+               int_table[k] = i;
+               l = levels_table[k++];
+               for (j = 0; j < l; j++) {
+                       run_table[i] = j;
+                       level_table[i] = level;
+                       i++;
+               }
+               level++;
+       }
+       *prun_table = run_table;
+       *plevel_table = level_table;
+       *pint_table = int_table;
+}
+
+/* compute the scale factor band sizes for each MDCT block size */
+static void compute_scale_factor_band_sizes(struct private_wmadec_data *s,
+       float high_freq)
+{
+       struct asf_header_info *ahi = &s->ahi;
+       int a, b, pos, lpos, k, block_len, i, j, n;
+       const uint8_t *table;
+
+       s->coefs_start = 0;
+       for (k = 0; k < s->nb_block_sizes; k++) {
+               block_len = s->frame_len >> k;
+
+               table = NULL;
+               a = s->frame_len_bits - BLOCK_MIN_BITS - k;
+               if (a < 3) {
+                       if (ahi->sample_rate >= 44100)
+                               table = exponent_band_44100[a];
+                       else if (ahi->sample_rate >= 32000)
+                               table = exponent_band_32000[a];
+                       else if (ahi->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 = ahi->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 */
+               s->high_band_start[k] = (int) ((block_len * 2 * high_freq)
+                       / ahi->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;
+       }
+}
+
+static int wma_init(struct private_wmadec_data *s, int flags2, struct asf_header_info *ahi)
+{
+       int i;
+       float bps1, high_freq;
+       volatile float bps;
+       int sample_rate1;
+       int coef_vlc_table;
+
+       if (ahi->sample_rate <= 0 || ahi->sample_rate > 50000
+               || ahi->channels <= 0 || ahi->channels > 8
+               || ahi->bit_rate <= 0)
+               return -E_WMA_BAD_PARAMS;
+
+       /* compute MDCT block size */
+       if (ahi->sample_rate <= 16000) {
+               s->frame_len_bits = 9;
+       } else if (ahi->sample_rate <= 22050) {
+               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 ((ahi->bit_rate / ahi->channels) >= 32000)
+                       nb += 2;
+               nb_max = s->frame_len_bits - BLOCK_MIN_BITS;
+               if (nb > nb_max)
+                       nb = nb_max;
+               s->nb_block_sizes = nb + 1;
+       } else {
+               s->nb_block_sizes = 1;
+       }
+
+       /* init rate dependent parameters */
+       s->use_noise_coding = 1;
+       high_freq = ahi->sample_rate * 0.5;
+
+       /* wma2 rates are normalized */
+       sample_rate1 = ahi->sample_rate;
+       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;
+
+       bps = (float) ahi->bit_rate / (float) (ahi->channels * ahi->sample_rate);
+       s->byte_offset_bits = wma_log2((int) (bps * s->frame_len / 8.0 + 0.5)) + 2;
+       /*
+        * Compute high frequency value and choose if noise coding should be
+        * activated.
+        */
+       bps1 = bps;
+       if (ahi->channels == 2)
+               bps1 = bps * 1.6;
+       if (sample_rate1 == 44100) {
+               if (bps1 >= 0.61)
+                       s->use_noise_coding = 0;
+               else
+                       high_freq = high_freq * 0.4;
+       } else if (sample_rate1 == 22050) {
+               if (bps1 >= 1.16)
+                       s->use_noise_coding = 0;
+               else if (bps1 >= 0.72)
+                       high_freq = high_freq * 0.7;
+               else
+                       high_freq = high_freq * 0.6;
+       } else if (sample_rate1 == 16000) {
+               if (bps > 0.5)
+                       high_freq = high_freq * 0.5;
+               else
+                       high_freq = high_freq * 0.3;
+       } else if (sample_rate1 == 11025) {
+               high_freq = high_freq * 0.7;
+       } else if (sample_rate1 == 8000) {
+               if (bps <= 0.625) {
+                       high_freq = high_freq * 0.5;
+               } else if (bps > 0.75) {
+                       s->use_noise_coding = 0;
+               } else {
+                       high_freq = high_freq * 0.65;
+               }
+       } else {
+               if (bps >= 0.8) {
+                       high_freq = high_freq * 0.75;
+               } else if (bps >= 0.6) {
+                       high_freq = high_freq * 0.6;
+               } else {
+                       high_freq = high_freq * 0.5;
+               }
+       }
+       PARA_INFO_LOG("channels=%d sample_rate=%d "
+               "bitrate=%d block_align=%d\n",
+               ahi->channels, ahi->sample_rate,
+               ahi->bit_rate, ahi->block_align);
+       PARA_INFO_LOG("frame_len=%d, bps=%f bps1=%f "
+               "high_freq=%f bitoffset=%d\n",
+               s->frame_len, bps, bps1,
+               high_freq, s->byte_offset_bits);
+       PARA_INFO_LOG("use_noise_coding=%d use_exp_vlc=%d nb_block_sizes=%d\n",
+               s->use_noise_coding, s->use_exp_vlc, s->nb_block_sizes);
+
+       compute_scale_factor_band_sizes(s, high_freq);
+       /* init MDCT windows : simple sinus window */
+       for (i = 0; i < s->nb_block_sizes; i++) {
+               int n;
+               n = 1 << (s->frame_len_bits - i);
+               sine_window_init(ff_sine_windows[s->frame_len_bits - i - 7], n);
+               s->windows[i] = ff_sine_windows[s->frame_len_bits - i - 7];
+       }
+
+       s->reset_block_lengths = 1;
+
+       if (s->use_noise_coding) {
+               /* init the noise generator */
+               if (s->use_exp_vlc)
+                       s->noise_mult = 0.02;
+               else
+                       s->noise_mult = 0.04;
+
+               {
+                       unsigned int seed;
+                       float norm;
+                       seed = 1;
+                       norm = (1.0 / (float) (1LL << 31)) * sqrt(3) * s->noise_mult;
+                       for (i = 0; i < NOISE_TAB_SIZE; i++) {
+                               seed = seed * 314159 + 1;
+                               s->noise_table[i] = (float) ((int) seed) * norm;
+                       }
+               }
+       }
+
+       /* choose the VLC tables for the coefficients */
+       coef_vlc_table = 2;
+       if (ahi->sample_rate >= 32000) {
+               if (bps1 < 0.72)
+                       coef_vlc_table = 0;
+               else if (bps1 < 1.16)
+                       coef_vlc_table = 1;
+       }
+       s->coef_vlcs[0] = &coef_vlcs[coef_vlc_table * 2];
+       s->coef_vlcs[1] = &coef_vlcs[coef_vlc_table * 2 + 1];
+       init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0],
+               &s->int_table[0], s->coef_vlcs[0]);
+       init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1],
+               &s->int_table[1], s->coef_vlcs[1]);
+       return 0;
+}
+
+static void wma_lsp_to_curve_init(struct private_wmadec_data *s, int frame_len)
+{
+       float wdel, a, b;
+       int i, e, m;
+
+       wdel = M_PI / frame_len;
+       for (i = 0; i < frame_len; i++)
+               s->lsp_cos_table[i] = 2.0f * cos(wdel * i);
+
+       /* tables for x^-0.25 computation */
+       for (i = 0; i < 256; i++) {
+               e = i - 126;
+               s->lsp_pow_e_table[i] = pow(2.0, e * -0.25);
+       }
+
+       /* These two tables are needed to avoid two operations in pow_m1_4. */
+       b = 1.0;
+       for (i = (1 << LSP_POW_BITS) - 1; i >= 0; i--) {
+               m = (1 << LSP_POW_BITS) + i;
+               a = (float) m *(0.5 / (1 << LSP_POW_BITS));
+               a = pow(a, -0.25);
+               s->lsp_pow_m_table1[i] = 2 * a - b;
+               s->lsp_pow_m_table2[i] = b - a;
+               b = a;
+       }
+}
+
+static int wma_decode_init(char *initial_buf, int len, struct private_wmadec_data **result)
+{
+       struct private_wmadec_data *s;
+       int ret, i;
+
+       if (len < 18)
+               return 0;
+
+       PARA_NOTICE_LOG("initial buf: %d bytes\n", len);
+       s = para_calloc(sizeof(*s));
+       ret = read_asf_header(initial_buf, len, &s->ahi);
+       if (ret < 0)
+               return ret;
+
+       s->use_exp_vlc = s->ahi.flags2 & 0x0001;
+       s->use_bit_reservoir = s->ahi.flags2 & 0x0002;
+       s->use_variable_block_len = s->ahi.flags2 & 0x0004;
+
+       ret = wma_init(s, s->ahi.flags2, &s->ahi);
+       if (ret < 0)
+               return ret;
+       /* init MDCT */
+       for (i = 0; i < s->nb_block_sizes; i++) {
+               ret = mdct_init(s->frame_len_bits - i + 1, 1, &s->mdct_ctx[i]);
+               if (ret < 0)
+                       return ret;
+       }
+       if (s->use_noise_coding) {
+               PARA_INFO_LOG("using noise coding\n");
+               init_vlc(&s->hgain_vlc, HGAINVLCBITS,
+                       sizeof (ff_wma_hgain_huffbits), ff_wma_hgain_huffbits,
+                       1, 1, ff_wma_hgain_huffcodes, 2, 2);
+       }
+
+       if (s->use_exp_vlc) {
+               PARA_INFO_LOG("using exp_vlc\n");
+               init_vlc(&s->exp_vlc, EXPVLCBITS,
+               sizeof (ff_wma_scale_huffbits), ff_wma_scale_huffbits,
+               1, 1, ff_wma_scale_huffcodes, 4, 4);
+       } else {
+               PARA_INFO_LOG("using curve\n");
+               wma_lsp_to_curve_init(s, s->frame_len);
+       }
+       *result = s;
+       return s->ahi.header_len;
+}
+
+/**
+ * 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 float pow_m1_4(struct private_wmadec_data *s, float x)
+{
+       union {
+               float f;
+               unsigned int v;
+       } u, t;
+       unsigned int e, m;
+       float a, b;
+
+       u.f = 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 = s->lsp_pow_m_table1[m];
+       b = s->lsp_pow_m_table2[m];
+       return s->lsp_pow_e_table[e] * (a + b * t.f);
+}
+
+static void wma_lsp_to_curve(struct private_wmadec_data *s,
+               float *out, float *val_max_ptr, int n, float *lsp)
+{
+       int i, j;
+       float p, q, w, v, val_max;
+
+       val_max = 0;
+       for (i = 0; i < n; i++) {
+               p = 0.5f;
+               q = 0.5f;
+               w = s->lsp_cos_table[i];
+               for (j = 1; j < NB_LSP_COEFS; j += 2) {
+                       q *= w - lsp[j - 1];
+                       p *= w - lsp[j];
+               }
+               p *= p * (2.0f - w);
+               q *= q * (2.0f + w);
+               v = p + q;
+               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). */
+static void decode_exp_lsp(struct private_wmadec_data *s, int ch)
+{
+       float 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] = ff_wma_lsp_codebook[i][val];
+       }
+
+       wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch],
+                        s->block_len, lsp_coefs);
+}
+
+/*
+ * Parse a vlc code, faster then get_vlc().
+ *
+ * \param bits The number of bits which will be read at once, must be
+ * identical to nb_bits in init_vlc()
+ *
+ * \param max_depth The number of times bits bits must be read to completely
+ * read the longest vlc code = (max_vlc_length + bits - 1) / bits.
+ */
+static int get_vlc2(struct getbit_context *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;
+}
+
+/* Decode exponents coded with VLC codes. */
+static int decode_exp_vlc(struct private_wmadec_data *s, int ch)
+{
+       int last_exp, n, code;
+       const uint16_t *ptr, *band_ptr;
+       float v, *q, max_scale, *q_end;
+
+       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;
+       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;
+               /* XXX: use a table */
+               v = pow(10, last_exp * (1.0 / 16.0));
+               if (v > max_scale)
+                       max_scale = v;
+               n = *ptr++;
+               do {
+                       *q++ = v;
+               } while (--n);
+       }
+       s->max_exponent[ch] = max_scale;
+       return 0;
+}
+
+static void vector_fmul_add(float *dst, const float *src0, const float *src1,
+               const float *src2, int src3, int len, int step)
+{
+       int i;
+       for (i = 0; i < len; i++)
+               dst[i * step] = src0[i] * src1[i] + src2[i] + src3;
+}
+
+static void vector_fmul_reverse_c(float *dst, const float *src0,
+               const float *src1, int len)
+{
+       int i;
+       src1 += len - 1;
+       for (i = 0; i < len; i++)
+               dst[i] = src0[i] * src1[-i];
+}
+
+/**
+ * Apply MDCT window and add into output.
+ *
+ * We ensure that when the windows overlap their squared sum
+ * is always 1 (MDCT reconstruction rule).
+ */
+static void wma_window(struct private_wmadec_data *s, float *out)
+{
+       float *in = s->output;
+       int block_len, bsize, n;
+
+       /* left part */
+       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(out, in, s->windows[bsize],
+                                        out, 0, block_len, 1);
+
+       } else {
+               block_len = 1 << s->prev_block_len_bits;
+               n = (s->block_len - block_len) / 2;
+               bsize = s->frame_len_bits - s->prev_block_len_bits;
+
+               vector_fmul_add(out + n, in + n, s->windows[bsize],
+                                        out + n, 0, block_len, 1);
+
+               memcpy(out + n + block_len, in + n + block_len,
+                      n * sizeof (float));
+       }
+
+       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_c(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 (float));
+
+               vector_fmul_reverse_c(out + n, in + n, s->windows[bsize],
+                                     block_len);
+
+               memset(out + n + block_len, 0, n * sizeof (float));
+       }
+}
+
+static int wma_total_gain_to_bits(int total_gain)
+{
+       if (total_gain < 15)
+               return 13;
+       else if (total_gain < 32)
+               return 12;
+       else if (total_gain < 40)
+               return 11;
+       else if (total_gain < 45)
+               return 10;
+       else
+               return 9;
+}
+
+/**
+ * @return 0 if OK. 1 if last block of frame. return -1 if
+ * unrecorrable error.
+ */
+static int wma_decode_block(struct private_wmadec_data *s)
+{
+       int n, v, ch, code, bsize;
+       int coef_nb_bits, total_gain;
+       int nb_coefs[MAX_CHANNELS];
+       float mdct_norm;
+
+       /* compute current block length */
+       if (s->use_variable_block_len) {
+               n = wma_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 -1;
+                       s->prev_block_len_bits = s->frame_len_bits - v;
+                       v = get_bits(&s->gb, n);
+                       if (v >= s->nb_block_sizes)
+                               return -1;
+                       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)
+                       return -1;
+               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 -E_INCOHERENT_BLOCK_LEN;
+
+       if (s->ahi.channels == 2) {
+               s->ms_stereo = get_bits1(&s->gb);
+       }
+       v = 0;
+       for (ch = 0; ch < s->ahi.channels; ch++) {
+               int a = get_bits1(&s->gb);
+               s->channel_coded[ch] = a;
+               v |= a;
+       }
+
+       bsize = s->frame_len_bits - s->block_len_bits;
+
+       /* if no channel coded, no need to go further */
+       /* XXX: fix potential framing problems */
+       if (!v)
+               goto next;
+
+       /* read total gain and extract corresponding number of bits for
+          coef escape coding */
+       total_gain = 1;
+       for (;;) {
+               int a = get_bits(&s->gb, 7);
+               total_gain += a;
+               if (a != 127)
+                       break;
+       }
+
+       coef_nb_bits = wma_total_gain_to_bits(total_gain);
+
+       /* compute number of coefficients */
+       n = s->coefs_end[bsize] - s->coefs_start;
+       for (ch = 0; ch < s->ahi.channels; ch++)
+               nb_coefs[ch] = n;
+
+       /* complex coding */
+       if (s->use_noise_coding) {
+
+               for (ch = 0; ch < s->ahi.channels; ch++) {
+                       if (s->channel_coded[ch]) {
+                               int i, m, a;
+                               m = s->exponent_high_sizes[bsize];
+                               for (i = 0; i < m; 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->ahi.channels; ch++) {
+                       if (s->channel_coded[ch]) {
+                               int i, val;
+
+                               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_vlc2(&s->gb,
+                                                                    s->
+                                                                    hgain_vlc.
+                                                                    table,
+                                                                    HGAINVLCBITS,
+                                                                    HGAINMAX);
+                                                       if (code < 0)
+                                                               return -1;
+                                                       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->ahi.channels; ch++) {
+                       if (s->channel_coded[ch]) {
+                               if (s->use_exp_vlc) {
+                                       if (decode_exp_vlc(s, ch) < 0)
+                                               return -1;
+                               } else {
+                                       decode_exp_lsp(s, ch);
+                               }
+                               s->exponents_bsize[ch] = bsize;
+                       }
+               }
+       }
+
+       /* parse spectral coefficients : just RLE encoding */
+       for (ch = 0; ch < s->ahi.channels; ch++) {
+               if (s->channel_coded[ch]) {
+                       struct vlc *coef_vlc;
+                       int level, run, sign, tindex;
+                       int16_t *ptr, *eptr;
+                       const uint16_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 -1;
+                               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) {
+                                       PARA_ERROR_LOG("overflow in spectral RLE, ignoring\n");
+                                       break;
+                               }
+                               *ptr++ = level;
+                               /* NOTE: EOB can be omitted */
+                               if (ptr >= eptr)
+                                       break;
+                       }
+               }
+       }
+
+       /* normalize */
+       {
+               int n4 = s->block_len / 2;
+               mdct_norm = 1.0 / (float) n4;
+       }
+
+       /* finally compute the MDCT coefficients */
+       for (ch = 0; ch < s->ahi.channels; ch++) {
+               if (s->channel_coded[ch]) {
+                       int16_t *coefs1;
+                       float *coefs, *exponents, mult, mult1, noise;
+                       int i, j, n1, last_high_band, esize;
+                       float exp_power[HIGH_BAND_MAX_SIZE];
+
+                       coefs1 = s->coefs1[ch];
+                       exponents = s->exponents[ch];
+                       esize = s->exponents_bsize[ch];
+                       mult = pow(10, total_gain * 0.05) / s->max_exponent[ch];
+                       mult *= mdct_norm;
+                       coefs = s->coefs[ch];
+                       if (s->use_noise_coding) {
+                               mult1 = mult;
+                               /* very low freqs : noise */
+                               for (i = 0; i < s->coefs_start; i++) {
+                                       *coefs++ =
+                                           s->noise_table[s->noise_index] *
+                                           exponents[i << bsize >> esize] *
+                                           mult1;
+                                       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]) {
+                                               float e2, val;
+                                               e2 = 0;
+                                               for (i = 0; i < n; i++) {
+                                                       val = exponents[i << bsize
+                                                                     >> esize];
+                                                       e2 += val * val;
+                                               }
+                                               exp_power[j] = e2 / n;
+                                               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 */
+                                               mult1 =
+                                                   sqrt(exp_power[j] /
+                                                        exp_power
+                                                        [last_high_band]);
+                                               /* XXX: use a table */
+                                               mult1 =
+                                                   mult1 * pow(10,
+                                                               s->
+                                                               high_band_values
+                                                               [ch][j] * 0.05);
+                                               mult1 =
+                                                   mult1 /
+                                                   (s->max_exponent[ch] *
+                                                    s->noise_mult);
+                                               mult1 *= mdct_norm;
+                                               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++ =
+                                                           noise *
+                                                           exponents[i << bsize
+                                                                     >> esize]
+                                                           * mult1;
+                                               }
+                                               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);
+                                                       *coefs++ =
+                                                           ((*coefs1++) +
+                                                            noise) *
+                                                           exponents[i << bsize
+                                                                     >> esize]
+                                                           * mult;
+                                               }
+                                               exponents += n << bsize;
+                                       }
+                               }
+
+                               /* very high freqs : noise */
+                               n = s->block_len - s->coefs_end[bsize];
+                               mult1 =
+                                   mult * exponents[((-1 << bsize)) >> esize];
+                               for (i = 0; i < n; i++) {
+                                       *coefs++ =
+                                           s->noise_table[s->noise_index] *
+                                           mult1;
+                                       s->noise_index =
+                                           (s->noise_index +
+                                            1) & (NOISE_TAB_SIZE - 1);
+                               }
+                       } else {
+                               /* XXX: optimize more */
+                               for (i = 0; i < s->coefs_start; i++)
+                                       *coefs++ = 0.0;
+                               n = nb_coefs[ch];
+                               for (i = 0; i < n; i++) {
+                                       *coefs++ =
+                                           coefs1[i] *
+                                           exponents[i << bsize >> esize] *
+                                           mult;
+                               }
+                               n = s->block_len - s->coefs_end[bsize];
+                               for (i = 0; i < n; i++)
+                                       *coefs++ = 0.0;
+                       }
+               }
+       }
+
+       if (s->ms_stereo && s->channel_coded[1]) {
+               float 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]) {
+                       PARA_NOTICE_LOG("rare ms-stereo\n");
+                       memset(s->coefs[0], 0, sizeof(float) * 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;
+               }
+       }
+
+next:
+       for (ch = 0; ch < s->ahi.channels; ch++) {
+               int n4, index;
+
+               n = s->block_len;
+               n4 = s->block_len / 2;
+               if (s->channel_coded[ch])
+                       imdct(s->mdct_ctx[bsize], s->output, s->coefs[ch]);
+               else if (!(s->ms_stereo && ch == 1))
+                       memset(s->output, 0, sizeof (s->output));
+
+               /* multiply by the window and add in the frame */
+               index = (s->frame_len / 2) + s->block_pos - n4;
+               wma_window(s, &s->frame_out[ch][index]);
+       }
+
+       /* update block number */
+       s->block_num++;
+       s->block_pos += s->block_len;
+       if (s->block_pos >= s->frame_len)
+               return 1;
+       else
+               return 0;
+}
+
+/*
+ * Clip a signed integer value into the -32768,32767 range.
+ *
+ * \param a The value to clip.
+ *
+ * \return The clipped value.
+ */
+static inline int16_t av_clip_int16(int a)
+{
+       if ((a + 32768) & ~65535)
+               return (a >> 31) ^ 32767;
+       else
+               return a;
+}
+
+/* Decode a frame of frame_len samples. */
+static int wma_decode_frame(struct private_wmadec_data *s, int16_t * samples)
+{
+       int ret, i, n, ch, incr;
+       int16_t *ptr;
+       float *iptr;
+
+       /* read each block */
+       s->block_num = 0;
+       s->block_pos = 0;
+       for (;;) {
+               ret = wma_decode_block(s);
+               if (ret < 0)
+                       return -1;
+               if (ret)
+                       break;
+       }
+
+       /* convert frame to integer */
+       n = s->frame_len;
+       incr = s->ahi.channels;
+       for (ch = 0; ch < s->ahi.channels; ch++) {
+               ptr = samples + ch;
+               iptr = s->frame_out[ch];
+
+               for (i = 0; i < n; i++) {
+                       *ptr = av_clip_int16(lrintf(*iptr++));
+                       ptr += incr;
+               }
+               /* prepare for next block */
+               memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len],
+                       s->frame_len * sizeof (float));
+       }
+       return 0;
+}
+
+static int wma_decode_superframe(struct private_wmadec_data *s, void *data,
+               int *data_size, const uint8_t *buf, int buf_size)
+{
+       int ret, nb_frames, bit_offset, i, pos, len;
+       uint8_t *q;
+       int16_t *samples;
+       static int frame_count;
+
+       if (buf_size == 0) {
+               s->last_superframe_len = 0;
+               return 0;
+       }
+       if (buf_size < s->ahi.block_align)
+               return 0;
+       buf_size = s->ahi.block_align;
+       samples = data;
+       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 */
+               nb_frames = get_bits(&s->gb, 4) - 1;
+               // PARA_DEBUG_LOG("have %d frames\n", nb_frames);
+               ret = -E_WMA_OUTPUT_SPACE;
+               if ((nb_frames + 1) * s->ahi.channels * s->frame_len
+                               * sizeof(int16_t) > *data_size)
+                       goto fail;
+
+               bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
+
+               if (s->last_superframe_len > 0) {
+                       /* add bit_offset bits to last frame */
+                       ret = -E_WMA_BAD_SUPERFRAME;
+                       if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) >
+                                       MAX_CODED_SUPERFRAME_SIZE)
+                               goto fail;
+                       q = s->last_superframe + s->last_superframe_len;
+                       len = 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: 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.
+                        */
+                       ret = -E_WMA_DECODE;
+                       if (wma_decode_frame(s, samples) < 0)
+                               goto fail;
+                       frame_count++;
+                       samples += s->ahi.channels * s->frame_len;
+               }
+
+               /* read each frame starting from bit_offset */
+               pos = 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;
+               for (i = 0; i < nb_frames; i++) {
+                       ret = -E_WMA_DECODE;
+                       if (wma_decode_frame(s, samples) < 0)
+                               goto fail;
+                       frame_count++;
+                       samples += s->ahi.channels * s->frame_len;
+               }
+
+               /* we copy the end of the frame in the last frame buffer */
+               pos = get_bits_count(&s->gb) +
+                       ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7);
+               s->last_bitoffset = pos & 7;
+               pos >>= 3;
+               len = buf_size - pos;
+               ret = -E_WMA_BAD_SUPERFRAME;
+               if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) {
+                       goto fail;
+               }
+               s->last_superframe_len = len;
+               memcpy(s->last_superframe, buf + pos, len);
+       } else {
+               PARA_DEBUG_LOG("not using bit reservoir\n");
+               ret = -E_WMA_OUTPUT_SPACE;
+               if (s->ahi.channels * s->frame_len * sizeof(int16_t) > *data_size)
+                       goto fail;
+               /* single frame decode */
+               ret = -E_WMA_DECODE;
+               if (wma_decode_frame(s, samples) < 0)
+                       goto fail;
+               frame_count++;
+               samples += s->ahi.channels * s->frame_len;
+       }
+       PARA_DEBUG_LOG("frame_count: %d frame_len: %d, block_len: %d, "
+               "outbytes: %d, eaten: %d\n",
+               frame_count, s->frame_len, s->block_len,
+               (int8_t *) samples - (int8_t *) data, s->ahi.block_align);
+       *data_size = (int8_t *)samples - (int8_t *)data;
+       return s->ahi.block_align;
+fail:
+       /* reset the bit reservoir on errors */
+       s->last_superframe_len = 0;
+       return ret;
+}
+
+static ssize_t wmadec_convert(char *inbuffer, size_t len,
+               struct filter_node *fn)
+{
+       int ret, out_size = fn->bufsize - fn->loaded;
+       struct private_wmadec_data *pwd = fn->private_data;
+
+       if (out_size < 128 * 1024)
+               return 0;
+       if (!pwd) {
+               ret = wma_decode_init(inbuffer, len, &pwd);
+               if (ret <= 0)
+                       return ret;
+               fn->private_data = pwd;
+               return pwd->ahi.header_len;
+       }
+       /* skip 31 bytes */
+       if (len <= WMA_FRAME_SKIP + pwd->ahi.block_align)
+               return 0;
+       ret = wma_decode_superframe(pwd, fn->buf + fn->loaded,
+               &out_size, (uint8_t *)inbuffer + WMA_FRAME_SKIP,
+               len - WMA_FRAME_SKIP);
+       if (ret < 0)
+               return ret;
+       fn->loaded += out_size;
+       return ret + WMA_FRAME_SKIP;
+}
+
+static void wmadec_close(struct filter_node *fn)
+{
+       struct private_wmadec_data *pwd = fn->private_data;
+       if (!pwd)
+               return;
+       wmadec_cleanup(pwd);
+       free(fn->buf);
+       fn->buf = NULL;
+       free(fn->private_data);
+       fn->private_data = NULL;
+}
+
+static void wmadec_open(struct filter_node *fn)
+{
+       fn->bufsize = 1024 * 1024;
+       fn->buf = para_malloc(fn->bufsize);
+       fn->private_data = NULL;
+       fn->loaded = 0;
+}
+
+/**
+ * The init function of the wma decoder.
+ *
+ * \param f Its fields are filled in by the function.
+ */
+void wmadec_filter_init(struct filter *f)
+{
+       f->open = wmadec_open;
+       f->close = wmadec_close;
+       f->convert = wmadec_convert;
+}