Bug 422538. Import libtheora
authorMonty <monty@xiph.org> and the rest of the Xiph.Org Foundation, plus Chris Double <chris.double@double.co.nz>
Tue, 29 Jul 2008 23:38:23 -0700
changeset 16296 beb6a98d95cb28d441c5e5f804f3742f70f4db0c
parent 16295 512b6f96960cc5ab36746bd627c502deefc2ee44
child 16297 c23d0114b53734b45f948956fc7418a99b2b11ab
push idunknown
push userunknown
push dateunknown
bugs422538
milestone1.9.1a2pre
Bug 422538. Import libtheora
modules/libtheora/AUTHORS
modules/libtheora/CHANGES
modules/libtheora/COPYING
modules/libtheora/LICENSE
modules/libtheora/Makefile.in
modules/libtheora/README
modules/libtheora/README_MOZILLA
modules/libtheora/include/Makefile.in
modules/libtheora/include/theora/Makefile.in
modules/libtheora/include/theora/codec.h
modules/libtheora/include/theora/config.h
modules/libtheora/include/theora/theora.h
modules/libtheora/include/theora/theoradec.h
modules/libtheora/lib/Makefile.in
modules/libtheora/lib/config.h
modules/libtheora/lib/cpu.c
modules/libtheora/lib/cpu.h
modules/libtheora/lib/dec/apiwrapper.c
modules/libtheora/lib/dec/apiwrapper.h
modules/libtheora/lib/dec/bitwise.c
modules/libtheora/lib/dec/bitwise.h
modules/libtheora/lib/dec/dct.h
modules/libtheora/lib/dec/decapiwrapper.c
modules/libtheora/lib/dec/decinfo.c
modules/libtheora/lib/dec/decint.h
modules/libtheora/lib/dec/decode.c
modules/libtheora/lib/dec/dequant.c
modules/libtheora/lib/dec/dequant.h
modules/libtheora/lib/dec/enquant.h
modules/libtheora/lib/dec/fragment.c
modules/libtheora/lib/dec/huffdec.c
modules/libtheora/lib/dec/huffdec.h
modules/libtheora/lib/dec/huffman.h
modules/libtheora/lib/dec/idct.c
modules/libtheora/lib/dec/idct.h
modules/libtheora/lib/dec/info.c
modules/libtheora/lib/dec/internal.c
modules/libtheora/lib/dec/ocintrin.h
modules/libtheora/lib/dec/quant.c
modules/libtheora/lib/dec/quant.h
modules/libtheora/lib/dec/state.c
modules/libtheora/lib/dec/x86/mmxfrag.c
modules/libtheora/lib/dec/x86/mmxidct.c
modules/libtheora/lib/dec/x86/mmxstate.c
modules/libtheora/lib/dec/x86/x86int.h
modules/libtheora/lib/dec/x86/x86state.c
modules/libtheora/lib/internal.h
modules/libtheora/update.sh
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/AUTHORS
@@ -0,0 +1,42 @@
+Monty <monty@xiph.org>
+	- Original VP3 port
+
+Ralph Giles
+Timothy B. Terriberry 
+	- Ongoing development
+	
+Dan B. Miller
+	- Pre alpha3 development
+	
+Wim Tayman
+Dan Lenski
+	- MMX optimized functions
+	
+Aaron Colwell
+Thomas Vander Stichele
+Jan Gerber
+Conrad Parker
+	- Bug fixes, enhancements, build systems.
+	
+Mauricio Piacentini
+	- Original win32 projects and example ports
+	- VP3->Theora transcoder
+
+Silvia Pfeiffer
+	- Figures for the spec
+
+Michael Smith
+Andre Pang
+calc
+ccheney
+brendan
+Edward Hervey
+Adam Moss
+Colin Ward
+Jeremy C. Reed
+Arc Riley
+Rodolphe Ortalo
+	- Bug fixes
+
+
+and other Xiph.org contributors
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/CHANGES
@@ -0,0 +1,140 @@
+libtheora 1.0beta3 (2008 April 16)
+
+ - Build new libtheoradec and libtheoraenc libraries
+   supporting the new API from theora-exp. This API should
+   not be considered stable yet.
+ - Change granule_frame() to return an index as documented.
+   This is a change of behaviour from 1.0beta1.
+ - Document that granule_time() returns the end of the 
+   presentation interval. 
+ - Use a custom copy of the libogg bitpacker in the decoder
+   to avoid function call overhead.
+ - MMX code improved and ported to MSVC.
+ - Fix a problem with the MMX code on SELinux 
+ - Fix a problem with decoder quantizer initialization.
+ - Fix a page queue problem with png2theora.
+ - Improved robustness.
+ - Updated VS2005 project files.
+ - Dropped build support for Microsoft VS2003.
+ - Dropped build support for the unreleased libogg2.
+ - Added the specification to the autotools build.
+ - Specification corrections.
+
+libtheora 1.0beta2 (2007 October 12)
+
+ - Fix a crash bug on char-is-unsigned architectures (PowerPC)
+ - Fix a buffer sizing issue that caused rare encoder crashes
+ - Fix a buffer alignment issue
+ - Build fixes for MingW32, MSVC
+ - Improved format documentation.
+
+libtheora 1.0beta1 (2007 September 22)
+
+ - Granulepos scheme modified to match other codecs. This bumps
+   the bitstream revision to 3.2.1. Bitstreams marked 3.2.0 are
+   handled correctly by this decoder. Older decoders will show
+   a one frame sync error in the less noticable direction.
+
+libtheora 1.0alpha8 (2007 September 18)
+
+ - Switch to new spec compliant decoder from theora-exp branch.
+   Written by Dr. Timothy Terriberry.
+ - Add support to the encoder for using quantization settings
+   provided by the application.
+ - more assembly optimizations
+
+libtheora 1.0alpha7 (2006 June 20)
+
+ - Enable mmx assembly by default
+ - Avoid some relocations that caused problems on SELinux
+ - Other build fixes
+ - time testing mode (-f) for the dump_video example
+
+libtheora 1.0alpha6 (2006 May 30)
+
+ * Merge theora-mmx simd acceleration (x86_32 and x86_64)
+ * Major RTP payload specification update
+ * Minor format specification updates
+ * Fix some spurious calls to free() instead of _ogg_free()
+ * Fix invalid array indexing in PixelLineSearch()
+ * Improve robustness against invalid input
+ * General warning cleanup
+ * The offset_y member now means what every application thought it meant
+   (offset from the top). This will mean some old files (those with a 
+   non-centered image created with a buggy encoder) will display differently.
+
+libtheora 1.0alpha5 (2005 August 20)
+
+ * Fixed bitrate management bugs that caused popping and encode
+   errors
+ * Fixed a crash problem with the theora_state internals not
+   being intialized properly.
+ * new utility function:
+   - theora_granule_shift()
+ * dump_video example now makes YUV4MPEG files by default, so
+   the results can be fed back to encoder_example and similar
+   tools. The old behavior is restored through the '-r' switch.
+ * ./configure now prints a summary
+ * simple unit test of the comment api under 'make check'
+ * misc code cleanup, warning and leak fixes
+
+libtheora 1.0alpha4 (2004 December 15)
+
+ * first draft of the Theora I Format Specification
+ * API documentation generated from theora.h with Doxygen
+ * fix a double-update bug in the motion analysis
+ * apply the loop filter before filling motion vector border 
+   in the reference frame
+ * new utility functions:
+   - theora_packet_isheader(),
+   - theora_packet_iskeyframe()
+   - theora_granule_frame()
+ * optional support for building without floating point
+ * optional support for building without encode support 
+ * various build and packaging fixes
+ * pkg-config support
+ * SymbianOS build support
+
+libtheora 1.0alpha3 (2004 March 20)
+
+ UPDATE: on 2004 July 1 the Theora I bitstream format was frozen. Files
+ produced by the libtheora 1.0alpha3 reference encoder will always be
+ decodable by the Theora I spec.
+
+ * Bitstream info header FORMAT CHANGES:
+   - move the granulepos shift field to maintain byte alignment longer.
+   - reserve 5 additional bits for subsampling and interlace flags.
+ * Bitstream setup header FORMAT CHANGES:
+   - support for a range of interpolated quant matricies.
+   - include the in-loop block filter coeff.
+ * Bitsteam data packet FORMAT CHANGES:
+   - Reserve a bit for per-block Q index selection.
+   - Flip the coded image orientation for compatibility with VP3.
+     This allows lossless transcoding of VP3 content, but files
+     encoded with earlier theora releases would play upside down.
+ * example VP3 lossless transcoder
+ * optional support for libogg2
+ * timing improvements in the example player
+ * packaging and build system updates and fixes
+
+libtheora 1.0alpha2 (2003 June 9)
+
+ * bitstream FORMAT CHANGES:
+   - store the quant tables in a third setup header for
+     future encoder flexibility
+   - store the huffman tables in the third setup header
+   - add a field for marking the colorspace to the info header
+   - add crop parameters for non-multiple-of-16 frame sizes
+   - add a second vorbiscomment-style metadata header
+ * API changes to handle multiple headers with a single 
+   theora_decode_header() call, like libvorbis
+ * code cleanup and minor fixes
+ * new dump_video code example/utility
+ * experimental win32 code examples
+
+libtheora 1.0alpha1 (2002 September 25)
+
+ * First release of the theora reference implementation
+ * Port of the newly opened VP3 code to the Ogg container
+ * Rewrite of the code for portability and to use the libogg bitpacker
+
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/COPYING
@@ -0,0 +1,28 @@
+Copyright (C) 2002-2007 Xiph.org Foundation
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+- Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+- Neither the name of the Xiph.org Foundation nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/LICENSE
@@ -0,0 +1,18 @@
+Please see the file COPYING for the copyright license for this software.
+
+In addition to and irrespective of the copyright license associated
+with this software, On2 Technologies, Inc. makes the following statement
+regarding technology used in this software:
+
+  On2 represents and warrants that it shall not assert any rights 
+  relating to infringement of On2's registered patents, nor initiate
+  any litigation asserting such rights, against any person who, or
+  entity which utilizes the On2 VP3 Codec Software, including any 
+  use, distribution, and sale of said Software; which make changes, 
+  modifications, and improvements in said Software; and to use,
+  distribute, and sell said changes as well as applications for other 
+  fields of use.
+
+This reference implementation is originally derived from the On2 VP3
+Codec Software, and the Theora video format is essentially compatible
+with the VP3 video format, consisting of a backward-compatible superset.
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/Makefile.in
@@ -0,0 +1,51 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= theora
+
+DIRS		= \
+		include \
+		lib \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/README
@@ -0,0 +1,143 @@
+-------------------------------------------------------------------------
+          The Xiph.org Foundation's libtheora 1.0beta1 release
+-------------------------------------------------------------------------
+
+*** What is Theora?
+
+Theora is Xiph.Org's first publicly released video codec, intended
+for use within the Foundation's Ogg multimedia streaming system.
+Theora is derived directly from On2's VP3 codec; Currently the 
+encoders are nearly identical, but Theora will make use of new
+features supported by the decoder to improve over what is 
+is possible with VP3.
+
+*** Where is Theora?
+
+Theora's main site is www.theora.org.  Theora and related libraries
+can be gotten from www.theora.org or the main Xiph.Org site at
+www.xiph.org.  Development source is kept in an open subversion 
+repository, see http://theora.org/svn/ for instructions.
+
+*** What is the goal of this release?
+
+This is the first beta release of the 1.0 reference implementation.
+It is intended to completely support the decoder specification, and
+gather feedback on the implementation before declaring it stable.
+
+-------------------------------------------------------------------------
+Getting started with the code
+-------------------------------------------------------------------------
+
+*** What do I need to build the source?
+
+Requirements summary:
+
+  For libtheora:  
+         
+      libogg 1.1 or newer.
+
+  For example encoder:
+
+      as above
+
+      libvorbis and libvorbisenc 1.0.1 or newer.
+
+  For the player only:
+
+      as above, 
+
+      SDL (Simple Direct media Layer) libraries and headers
+ 
+      OSS audio driver and development headers
+
+The provided build system is the GNU automake/autoconf system, and
+the main library, libtheora, should already build smoothly on any
+system.  Failure of libtheora to build on a GNU-enabled system is
+considered a bug; please report problems to theora-dev@xiph.org.
+
+Some windows build support is included in the win32 directory.
+
+There is also an experimental scons build.
+
+*** How do I use the sample encoder?
+
+The sample encoder takes raw video in YUV4MPEG2 format, as used by
+lavtools, mjpeg-tools and other packages. The encoder expects audio,
+if any, in a separate wave WAV file. Try 'encoder_example -h' for a 
+complete list of options.
+
+An easy way to get raw video and audio files is to use MPlayer as an
+export utility.  The options " -ao pcm -vo yuv4mpeg " will export a
+wav file named audiodump.wav and a YUV video file in the correct
+format for encoder_example as stream.yuv.  Be careful when exporting
+video alone; MPlayer may drop frames to 'keep up' with the audio
+timer.  The example encoder can't properly synchronize input audio and
+video file that aren't in sync to begin with.  
+
+The encoder will also take video or audio on stdin if '-' is specified
+as the input file name.
+
+There is also a 'png2theora' example which accepts a set of image
+files in that format.
+
+*** How do I use the sample player?
+
+The sample player takes an Ogg file on standard in; the file may be
+audio alone, video alone or video with audio.  
+
+*** What other tools are available?
+
+The programs in the examples directory are intended as tutorial source 
+for developers using the library. As such they sacrifice features and 
+robustness in the interests of comprehension and should not be 
+considered serious applications.
+
+If you're wanting to just use theora, consider the programs linked
+from http://www.theora.org/. There is playback support in a number
+of common free players, and plugins for major media frameworks.
+Jan Gerber's ffmpeg2theora is an excellent encoding front end.
+
+-------------------------------------------------------------------------
+Troubleshooting the build process
+-------------------------------------------------------------------------
+
+*** Compile error, such as:
+
+encoder_internal.h:664: parse error before `ogg_uint16_t'
+
+This means you have version of libogg prior to 1.1. A *complete* new Ogg 
+install, libs and headers is needed.
+
+Also be sure that there aren't multiple copies of Ogg installed in
+/usr and /usr/local; an older one might be first on the search path
+for libs and headers.
+
+*** Link error, such as:
+
+undefined reference to `oggpackB_stream'
+
+See above; you need libogg 1.1 or later.
+
+*** Link error, such as:
+
+undefined reference to `vorbis_granule_time'
+
+You need libvorbis and libvorbisenc from the 1.0.1 release or later.
+
+*** Link error, such as:
+
+/usr/lib/libSDL.a(SDL_esdaudio.lo): In function `ESD_OpenAudio':
+SDL_esdaudio.lo(.text+0x25d): undefined reference to `esd_play_stream'
+
+Be sure to use an SDL that's built to work with OSS.  If you use an
+SDL that is also built with ESD and/or ALSA support, it will try to
+suck in all those extra libraries at link time too.  That will only
+work if the extra libraries are also installed.
+
+*** Link warning, such as:
+
+libtool: link: warning: library `/usr/lib/libogg.la' was moved.
+libtool: link: warning: library `/usr/lib/libogg.la' was moved.
+
+Re-run theora/autogen.sh after an Ogg or Vorbis rebuild/reinstall
+
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/README_MOZILLA
@@ -0,0 +1,4 @@
+The source from this directory was copied from the libtheora-1.0beta3
+source distribution using the update.sh script. The only changes made
+were those applied by update.sh and the addition/upate of Makefile.in
+files for the Mozilla build system.
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/include/Makefile.in
@@ -0,0 +1,47 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= theora
+DIRS		= theora
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/include/theora/Makefile.in
@@ -0,0 +1,52 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= theora
+
+EXPORTS		= \
+		theora.h \
+		theoradec.h \
+		codec.h \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/include/theora/codec.h
@@ -0,0 +1,589 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
+
+ ********************************************************************/
+
+/**\mainpage
+ * 
+ * \section intro Introduction
+ *
+ * This is the documentation for <tt>libtheora</tt> C API.
+ * The current reference
+ * implementation for <a href="http://www.theora.org/">Theora</a>, a free,
+ * patent-unencumbered video codec.
+ * Theora is derived from On2's VP3 codec with additional features and
+ *  integration for Ogg multimedia formats by
+ *  <a href="http://www.xiph.org/">the Xiph.Org Foundation</a>.
+ * Complete documentation of the format itself is available in
+ * <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ *  specification</a>.
+ *
+ * \subsection Organization
+ *
+ * The functions documented here are actually subdivided into three 
+ * separate libraries:
+ * - <tt>libtheoraenc</tt> contains the encoder interface,
+ *   described in \ref encfuncs.
+ * - <tt>libtheoradec</tt> contains the decoder interface and
+ *   routines shared with the encoder.
+ *   You must also link to this if you link to <tt>libtheoraenc</tt>.
+ *   The routines in this library are described in \ref decfuncs and 
+ *   \ref basefuncs.
+ * - <tt>libtheora</tt> contains the \ref oldfuncs.
+ *
+ * New code should link to <tt>libtheoradec</tt> and, if using encoder
+ * features, <tt>libtheoraenc</tt>. Together these two export both
+ * the standard and the legacy API, so this is all that is needed by
+ * any code. The older <tt>libtheora</tt> library is provided just for
+ * compatibility with older build configurations.
+ *
+ * In general the recommended 1.x API symbols can be distinguished
+ * by their <tt>th_</tt> or <tt>TH_</tt> namespace prefix.
+ * The older, legacy API uses <tt>theora_</tt> or <tt>OC_</tt>
+ * prefixes instead.
+ */
+
+/**\file
+ * The shared <tt>libtheoradec</tt> and <tt>libtheoraenc</tt> C API.
+ * You don't need to include this directly.*/
+
+#if !defined(_O_THEORA_CODEC_H_)
+# define _O_THEORA_CODEC_H_ (1)
+# include <ogg/ogg.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/**\name Return codes*/
+/*@{*/
+/**An invalid pointer was provided.*/
+#define TH_EFAULT     (-1)
+/**An invalid argument was provided.*/
+#define TH_EINVAL     (-10)
+/**The contents of the header were incomplete, invalid, or unexpected.*/
+#define TH_EBADHEADER (-20)
+/**The header does not belong to a Theora stream.*/
+#define TH_ENOTFORMAT (-21)
+/**The bitstream version is too high.*/
+#define TH_EVERSION   (-22)
+/**The specified function is not implemented.*/
+#define TH_EIMPL      (-23)
+/**There were errors in the video data packet.*/
+#define TH_EBADPACKET (-24)
+/**The decoded packet represented a dropped frame.
+   The player can continue to display the current frame, as the contents of the
+    decoded frame buffer have not changed.*/
+#define TH_DUPFRAME   (1)
+/*@}*/
+
+/**The currently defined color space tags.
+ * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ *  specification</a>, Chapter 4, for exact details on the meaning of each of
+ *  these color spaces.*/
+typedef enum{
+  /**The color space was not specified at the encoder.
+      It may be conveyed by an external means.*/
+  TH_CS_UNSPECIFIED,
+  /**A color space designed for NTSC content.*/
+  TH_CS_ITU_REC_470M,
+  /**A color space designed for PAL/SECAM content.*/
+  TH_CS_ITU_REC_470BG,
+  /**The total number of currently defined color spaces.*/
+  TH_CS_NSPACES
+}th_colorspace;
+
+/**The currently defined pixel format tags.
+ * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ *  specification</a>, Section 4.4, for details on the precise sample
+ *  locations.*/
+typedef enum{
+  /**Chroma decimation by 2 in both the X and Y directions (4:2:0).*/
+  TH_PF_420,
+  /**Currently reserved.*/
+  TH_PF_RSVD,
+  /**Chroma decimation by 2 in the X direction (4:2:2).*/
+  TH_PF_422,
+  /**No chroma decimation (4:4:4).*/
+  TH_PF_444,
+  /**The total number of currently defined pixel formats.*/
+  TH_PF_NFORMATS
+}th_pixel_fmt;
+
+
+
+/**A buffer for a single color plane in an uncompressed image.
+ * This contains the image data in a left-to-right, top-down format.
+ * Each row of pixels is stored contiguously in memory, but successive rows
+ *  need not be.
+ * Use \a stride to compute the offset of the next row.
+ * The encoder accepts both positive \a stride values (top-down in memory) and
+ *  negative (bottom-up in memory).
+ * The decoder currently always generates images with positive strides.*/
+typedef struct{
+  /**The width of this plane.*/
+  int            width;
+  /**The height of this plane.*/
+  int            height;
+  /**The offset in bytes between successive rows.*/
+  int            stride;
+  /**A pointer to the beginning of the first row.*/
+  unsigned char *data;
+}th_img_plane;
+
+/**A complete image buffer for an uncompressed frame.
+ * The chroma planes may be decimated by a factor of two in either direction,
+ *  as indicated by th_info#pixel_fmt.
+ * The width and height of the Y' plane must be multiples of 16.
+ * They may need to be cropped for display, using the rectangle specified by
+ *  th_info#pic_x, th_info#pic_y, th_info#pic_width, and
+ *  th_info#pic_height.
+ * All samples are 8 bits.
+ * \note The term YUV often used to describe a colorspace is ambiguous.
+ * The exact parameters of the RGB to YUV conversion process aside, in many
+ *  contexts the U and V channels actually have opposite meanings.
+ * To avoid this confusion, we are explicit: the name of the color channels are
+ *  Y'CbCr, and they appear in that order, always.
+ * The prime symbol denotes that the Y channel is non-linear.
+ * Cb and Cr stand for "Chroma blue" and "Chroma red", respectively.*/
+typedef th_img_plane th_ycbcr_buffer[3];
+
+/**Theora bitstream information.
+ * This contains the basic playback parameters for a stream, and corresponds to 
+ *  the initial 'info' header packet.
+ * To initialize an encoder, the application fills in this structure and
+ *  passes it to th_encode_alloc().
+ * A default encoding mode is chosen based on the values of the #quality and
+ *  #target_bitrate fields.
+ * On decode, it is filled in by th_decode_headerin(), and then passed to
+ *  th_decode_alloc().
+ *
+ * Encoded Theora frames must be a multiple of 16 in size;
+ *  this is what the #frame_width and #frame_height members represent.
+ * To handle arbitrary picture sizes, a crop rectangle is specified in the
+ *  #pic_x, #pic_y, #pic_width and #pic_height members.
+ *
+ * All frame buffers contain pointers to the full, padded frame.
+ * However, the current encoder <em>will not</em> reference pixels outside of
+ *  the cropped picture region, and the application does not need to fill them
+ *  in.
+ * The decoder <em>will</em> allocate storage for a full frame, but the
+ *  application <em>should not</em> rely on the padding containing sensible
+ *  data.
+ *
+ * It is also generally recommended that the offsets and sizes should still be
+ *  multiples of 2 to avoid chroma sampling shifts when chroma is sub-sampled.
+ * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ *  specification</a>, Section 4.4, for more details.
+ *
+ * Frame rate, in frames per second, is stored as a rational fraction, as is
+ *  the pixel aspect ratio.
+ * Note that this refers to the aspect ratio of the individual pixels, not of
+ *  the overall frame itself.
+ * The frame aspect ratio can be computed from pixel aspect ratio using the
+ *  image dimensions.*/
+typedef struct{
+  /**\name Theora version
+   * Bitstream version information.*/
+  /*@{*/
+  unsigned char version_major;
+  unsigned char version_minor;
+  unsigned char version_subminor;
+  /*@}*/
+  /**The encoded frame width.
+   * This must be a multiple of 16, and less than 1048576.*/
+  ogg_uint32_t  frame_width;
+  /**The encoded frame height.
+   * This must be a multiple of 16, and less than 1048576.*/
+  ogg_uint32_t  frame_height;
+  /**The displayed picture width.
+   * This must be no larger than width.*/
+  ogg_uint32_t  pic_width;
+  /**The displayed picture height.
+   * This must be no larger than height.*/
+  ogg_uint32_t  pic_height;
+  /**The X offset of the displayed picture.
+   * This must be no larger than #frame_width-#pic_width or 255, whichever is
+   *  smaller.*/
+  ogg_uint32_t  pic_x;
+  /**The Y offset of the displayed picture.
+   * This must be no larger than #frame_height-#pic_height, and
+   *  #frame_height-#pic_height-#pic_y must be no larger than 255.
+   * This slightly funny restriction is due to the fact that the offset is
+   *  specified from the top of the image for consistency with the standard
+   *  graphics left-handed coordinate system used throughout this API, while it
+   *  is stored in the encoded stream as an offset from the bottom.*/
+  ogg_uint32_t  pic_y;
+  /**\name Frame rate
+   * The frame rate, as a fraction.
+   * If either is 0, the frame rate is undefined.*/
+  /*@{*/
+  ogg_uint32_t  fps_numerator;
+  ogg_uint32_t  fps_denominator;
+  /*@}*/
+  /**\name Aspect ratio
+   * The aspect ratio of the pixels.
+   * If either value is zero, the aspect ratio is undefined.
+   * If not specified by any external means, 1:1 should be assumed.
+   * The aspect ratio of the full picture can be computed as
+   * \code
+   *  aspect_numerator*pic_width/(aspect_denominator*pic_height).
+   * \endcode */
+  /*@{*/
+  ogg_uint32_t  aspect_numerator;
+  ogg_uint32_t  aspect_denominator;
+  /*@}*/
+  /**The color space.*/
+  th_colorspace colorspace;
+  /**The pixel format.*/
+  th_pixel_fmt  pixel_fmt;
+  /**The target bit-rate in bits per second.
+     If initializing an encoder with this struct, set this field to a non-zero
+      value to activate CBR encoding by default.*/
+  /*TODO: Current encoder does not support CBR mode, or anything like it.
+    We also don't really know what nominal rate each quality level
+     corresponds to yet.*/
+  int           target_bitrate;
+  /**The target quality level.
+     Valid values range from 0 to 63, inclusive, with higher values giving
+      higher quality.
+     If initializing an encoder with this struct, and #target_bitrate is set
+      to zero, VBR encoding at this quality will be activated by default.*/
+  /*Currently this is set so that a qi of 0 corresponds to distortions of 24
+     times the JND, and each increase by 16 halves that value.
+    This gives us fine discrimination at low qualities, yet effective rate
+     control at high qualities.
+    The qi value 63 is special, however.
+    For this, the highest quality, we use one half of a JND for our threshold.
+    Due to the lower bounds placed on allowable quantizers in Theora, we will
+     not actually be able to achieve quality this good, but this should
+     provide as close to visually lossless quality as Theora is capable of.
+    We could lift the quantizer restrictions without breaking VP3.1
+     compatibility, but this would result in quantized coefficients that are
+     too large for the current bitstream to be able to store.
+    We'd have to redesign the token syntax to store these large coefficients,
+     which would make transcoding complex.*/
+  int           quality;
+  /**The amount to shift to extract the last keyframe number from the granule
+   *  position.
+   * This can be at most 31.
+   * th_info_init() will set this to a default value (currently <tt>6</tt>,
+   *  which is good for streaming applications), but you can set it to 0 to
+   *  make every frame a keyframe.
+   * The maximum distance between key frames is
+   *  <tt>1<<#keyframe_granule_shift</tt>.
+   * The keyframe frequency can be more finely controlled with
+   *  #TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, which can also be adjusted
+   *  during encoding (for example, to force the next frame to be a keyframe),
+   *  but it cannot be set larger than the amount permitted by this field after
+   *  the headers have been output.*/
+  int           keyframe_granule_shift;
+}th_info;
+
+/**The comment information.
+ *
+ * This structure holds the in-stream metadata corresponding to
+ *  the 'comment' header packet.
+ * The comment header is meant to be used much like someone jotting a quick
+ *  note on the label of a video.
+ * It should be a short, to the point text note that can be more than a couple
+ *  words, but not more than a short paragraph.
+ *
+ * The metadata is stored as a series of (tag, value) pairs, in
+ *  length-encoded string vectors.
+ * The first occurrence of the '=' character delimits the tag and value.
+ * A particular tag may occur more than once, and order is significant.
+ * The character set encoding for the strings is always UTF-8, but the tag
+ *  names are limited to ASCII, and treated as case-insensitive.
+ * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ *  specification</a>, Section 6.3.3 for details.
+ *
+ * In filling in this structure, th_decode_headerin() will null-terminate
+ *  the user_comment strings for safety.
+ * However, the bitstream format itself treats them as 8-bit clean vectors,
+ *  possibly containing null characters, and so the length array should be
+ *  treated as their authoritative length.
+ */
+typedef struct th_comment{
+  /**The array of comment string vectors.*/
+  char **user_comments;
+  /**An array of the corresponding length of each vector, in bytes.*/
+  int   *comment_lengths;
+  /**The total number of comment strings.*/
+  int    comments;
+  /**The null-terminated vendor string.
+     This identifies the software used to encode the stream.*/
+  char  *vendor;
+}th_comment;
+
+
+
+/**A single base matrix.*/
+typedef unsigned char th_quant_base[64];
+
+/**A set of \a qi ranges.*/
+typedef struct{
+  /**The number of ranges in the set.*/
+  int                  nranges;
+  /**The size of each of the #nranges ranges.
+     These must sum to 63.*/
+  const int           *sizes;
+  /**#nranges <tt>+1</tt> base matrices.
+     Matrices \a i and <tt>i+1</tt> form the endpoints of range \a i.*/
+  const th_quant_base *base_matrices;
+}th_quant_ranges;
+
+/**A complete set of quantization parameters.
+   The quantizer for each coefficient is calculated as:
+   \code
+    Q=MAX(MIN(qmin[qti][ci!=0],scale[ci!=0][qi]*base[qti][pli][qi][ci]/100),
+     1024).
+   \endcode
+
+   \a qti is the quantization type index: 0 for intra, 1 for inter.
+   <tt>ci!=0</tt> is 0 for the DC coefficient and 1 for AC coefficients.
+   \a qi is the quality index, ranging between 0 (low quality) and 63 (high
+    quality).
+   \a pli is the color plane index: 0 for Y', 1 for Cb, 2 for Cr.
+   \a ci is the DCT coefficient index.
+   Coefficient indices correspond to the normal 2D DCT block
+    ordering--row-major with low frequencies first--\em not zig-zag order.
+
+   Minimum quantizers are constant, and are given by:
+   \code
+   qmin[2][2]={{4,2},{8,4}}.
+   \endcode
+
+   Parameters that can be stored in the bitstream are as follows:
+    - The two scale matrices ac_scale and dc_scale.
+      \code
+      scale[2][64]={dc_scale,ac_scale}.
+      \endcode
+    - The base matrices for each \a qi, \a qti and \a pli (up to 384 in all).
+      In order to avoid storing a full 384 base matrices, only a sparse set of
+       matrices are stored, and the rest are linearly interpolated.
+      This is done as follows.
+      For each \a qti and \a pli, a series of \a n \a qi ranges is defined.
+      The size of each \a qi range can vary arbitrarily, but they must sum to
+       63.
+      Then, <tt>n+1</tt> matrices are specified, one for each endpoint of the
+       ranges.
+      For interpolation purposes, each range's endpoints are the first \a qi
+       value it contains and one past the last \a qi value it contains.
+      Fractional values are rounded to the nearest integer, with ties rounded
+       away from zero.
+
+      Base matrices are stored by reference, so if the same matrices are used
+       multiple times, they will only appear once in the bitstream.
+      The bitstream is also capable of omitting an entire set of ranges and
+       its associated matrices if they are the same as either the previous
+       set (indexed in row-major order) or if the inter set is the same as the
+       intra set.
+
+    - Loop filter limit values.
+      The same limits are used for the loop filter in all color planes, despite
+       potentially differing levels of quantization in each.
+
+   For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater
+    than <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must
+    be no greater than <tt>base[qti][pli][qi-1][ci]</tt>.
+   These two conditions ensure that the actual quantizer for a given \a qti,
+    \a pli, and \a ci does not increase as \a qi increases.
+   This is not required by the decoder.*/
+typedef struct{
+  /**The DC scaling factors.*/
+  ogg_uint16_t    dc_scale[64];
+  /**The AC scaling factors.*/
+  ogg_uint16_t    ac_scale[64];
+  /**The loop filter limit values.*/
+  unsigned char   loop_filter_limits[64];
+  /**The \a qi ranges for each \a ci and \a pli.*/
+  th_quant_ranges qi_ranges[2][3];
+}th_quant_info;
+
+
+
+/**The number of Huffman tables used by Theora.*/
+#define TH_NHUFFMAN_TABLES (80)
+/**The number of DCT token values in each table.*/
+#define TH_NDCT_TOKENS     (32)
+
+/**A Huffman code for a Theora DCT token.
+ * Each set of Huffman codes in a given table must form a complete, prefix-free
+ *  code.
+ * There is no requirement that all the tokens in a table have a valid code,
+ *  but the current encoder is not optimized to take advantage of this.
+ * If each of the five grouops of 16 tables does not contain at least one table
+ *  with a code for every token, then the encoder may fail to encode certain
+ *  frames.
+ * The complete table in the first group of 16 does not have to be in the same
+ *  place as the complete table in the other groups, but the complete tables in
+ *  the remaining four groups must all be in the same place.*/
+typedef struct{
+  /**The bit pattern for the code, with the LSbit of the pattern aligned in
+   *   the LSbit of the word.*/
+  ogg_uint32_t pattern;
+  /**The number of bits in the code.
+   * This must be between 0 and 32, inclusive.*/
+  int          nbits;
+}th_huff_code;
+
+
+
+/**\defgroup basefuncs Functions Shared by Encode and Decode*/
+/*@{*/
+/**\name Basic shared functions*/
+/*@{*/
+/**Retrieves a human-readable string to identify the library vendor and
+ *  version.
+ * \return the version string.*/
+extern const char *th_version_string(void);
+/**Retrieves the library version number.
+ * This is the highest bitstream version that the encoder library will produce,
+ *  or that the decoder library can decode.
+ * This number is composed of a 16-bit major version, 8-bit minor version
+ * and 8 bit sub-version, composed as follows:
+ * \code
+ * (VERSION_MAJOR<<16)+(VERSION_MINOR<<8)+(VERSION_SUBMINOR)
+ * \endcode
+ * \return the version number.*/
+extern ogg_uint32_t th_version_number(void);
+/**Converts a granule position to an absolute frame index, starting at
+ *  <tt>0</tt>.
+ * The granule position is interpreted in the context of a given
+ *  #th_enc_ctx or #th_dec_ctx handle (either will suffice).
+ * \param _encdec  A previously allocated #th_enc_ctx or #th_dec_ctx
+ *                  handle.
+ * \param _granpos The granule position to convert.
+ * \returns The absolute frame index corresponding to \a _granpos.
+ * \retval -1 The given granule position was invalid (i.e. negative).*/
+extern ogg_int64_t th_granule_frame(void *_encdec,ogg_int64_t _granpos);
+/**Converts a granule position to an absolute time in seconds.
+ * The granule position is interpreted in the context of a given
+ *  #th_enc_ctx or #th_dec_ctx handle (either will suffice).
+ * \param _encdec  A previously allocated #th_enc_ctx or #th_dec_ctx
+ *                  handle.
+ * \param _granpos The granule position to convert.
+ * \return The absolute time in seconds corresponding to \a _granpos.
+ *         This is the "end time" for the frame, or the latest time it should
+ *          be displayed.
+ *         It is not the presentation time.
+ * \retval -1 The given granule position was invalid (i.e. negative).*/
+extern double th_granule_time(void *_encdec,ogg_int64_t _granpos);
+/**Determines whether a Theora packet is a header or not.
+ * This function does no verification beyond checking the packet type bit, so
+ *  it should not be used for bitstream identification; use
+ *  th_decode_headerin() for that.
+ * As per the Theora specification, an empty (0-byte) packet is treated as a
+ *  data packet (a delta frame with no coded blocks).
+ * \param _op An <tt>ogg_packet</tt> containing encoded Theora data.
+ * \retval 1 The packet is a header packet
+ * \retval 0 The packet is a video data packet.*/
+extern int th_packet_isheader(ogg_packet *_op);
+/**Determines whether a theora packet is a key frame or not.
+ * This function does no verification beyond checking the packet type and
+ *  key frame bits, so it should not be used for bitstream identification; use
+ *  th_decode_headerin() for that.
+ * As per the Theora specification, an empty (0-byte) packet is treated as a
+ *  delta frame (with no coded blocks).
+ * \param _op An <tt>ogg_packet</tt> containing encoded Theora data.
+ * \retval 1  The packet contains a key frame.
+ * \retval 0  The packet contains a delta frame.
+ * \retval -1 The packet is not a video data packet.*/
+extern int th_packet_iskeyframe(ogg_packet *_op);
+/*@}*/
+
+
+/**\name Functions for manipulating header data*/
+/*@{*/
+/**Initializes a th_info structure.
+ * This should be called on a freshly allocated #th_info structure before
+ *  attempting to use it.
+ * \param _info The #th_info struct to initialize.*/
+extern void th_info_init(th_info *_info);
+/**Clears a #th_info structure.
+ * This should be called on a #th_info structure after it is no longer
+ *  needed.
+ * \param _info The #th_info struct to clear.*/
+extern void th_info_clear(th_info *_info);
+
+/**Initialize a #th_comment structure.
+ * This should be called on a freshly allocated #th_comment structure
+ *  before attempting to use it.
+ * \param _tc The #th_comment struct to initialize.*/
+extern void th_comment_init(th_comment *_tc);
+/**Add a comment to an initialized #th_comment structure.
+ * \note Neither th_comment_add() nor th_comment_add_tag() support
+ *  comments containing null values, although the bitstream format does
+ *  support them.
+ * To add such comments you will need to manipulate the #th_comment
+ *  structure directly.
+ * \param _tc      The #th_comment struct to add the comment to.
+ * \param _comment Must be a null-terminated UTF-8 string containing the
+ *                  comment in "TAG=the value" form.*/
+extern void th_comment_add(th_comment *_tc, char *_comment);
+/**Add a comment to an initialized #th_comment structure.
+ * \note Neither th_comment_add() nor th_comment_add_tag() support
+ *  comments containing null values, although the bitstream format does
+ *  support them.
+ * To add such comments you will need to manipulate the #th_comment
+ *  structure directly.
+ * \param _tc  The #th_comment struct to add the comment to.
+ * \param _tag A null-terminated string containing the tag  associated with
+ *              the comment.
+ * \param _val The corresponding value as a null-terminated string.*/
+extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val);
+/**Look up a comment value by its tag.
+ * \param _tc    An initialized #th_comment structure.
+ * \param _tag   The tag to look up.
+ * \param _count The instance of the tag.
+ *               The same tag can appear multiple times, each with a distinct
+ *                value, so an index is required to retrieve them all.
+ *               The order in which these values appear is significant and
+ *                should be preserved.
+ *               Use th_comment_query_count() to get the legal range for
+ *                the \a _count parameter.
+ * \return A pointer to the queried tag's value.
+ *         This points directly to data in the #th_comment structure.
+ *         It should not be modified or freed by the application, and
+ *          modifications to the structure may invalidate the pointer.
+ * \retval NULL If no matching tag is found.*/
+extern char *th_comment_query(th_comment *_tc,char *_tag,int _count);
+/**Look up the number of instances of a tag.
+ * Call this first when querying for a specific tag and then iterate over the
+ *  number of instances with separate calls to th_comment_query() to
+ *  retrieve all the values for that tag in order.
+ * \param _tc    An initialized #th_comment structure.
+ * \param _tag   The tag to look up.
+ * \return The number on instances of this particular tag.*/
+extern int th_comment_query_count(th_comment *_tc,char *_tag);
+/**Clears a #th_comment structure.
+ * This should be called on a #th_comment structure after it is no longer
+ *  needed.
+ * It will free all memory used by the structure members.
+ * \param _tc The #th_comment struct to clear.*/
+extern void th_comment_clear(th_comment *_tc);
+/*@}*/
+/*@}*/
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/include/theora/config.h
@@ -0,0 +1,80 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <soundcard.h> header file. */
+/* #undef HAVE_SOUNDCARD_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+#define HAVE_SYS_SOUNDCARD_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* enable x86 assambler optimization */
+ 
+
+/* Name of package */
+#define PACKAGE "libtheora"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libtheora"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libtheora 1.0beta3"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libtheora"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.0beta3"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to exclude encode support from the build */
+ 
+
+/* Define to exclude floating point code from the build */
+/* #undef THEORA_DISABLE_FLOAT */
+
+/* make use of asm optimization */
+ 
+
+/* Version number of package */
+#define VERSION "1.0beta3"
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/include/theora/theora.h
@@ -0,0 +1,842 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: theora.h,v 1.17 2003/12/06 18:06:19 arc Exp $
+
+ ********************************************************************/
+
+#ifndef _O_THEORA_H_
+#define _O_THEORA_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <stddef.h>	/* for size_t */
+
+#include <ogg/ogg.h>
+
+/** \defgroup oldfuncs Legacy pre-1.0 C API */
+/*  @{ */
+
+/** \mainpage
+ * 
+ * \section intro Introduction
+ *
+ * This is the documentation for the libtheora legacy C API, declared in 
+ * the theora.h header, which describes the old interface used before
+ * the 1.0 release. This API was widely deployed for several years and
+ * remains supported, but for new code we recommend the cleaner API 
+ * declared in theoradec.h and theoraenc.h.
+ *
+ * libtheora is the reference implementation for
+ * <a href="http://www.theora.org/">Theora</a>, a free video codec.
+ * Theora is derived from On2's VP3 codec with improved integration for
+ * Ogg multimedia formats by <a href="http://www.xiph.org/">Xiph.Org</a>.
+ * 
+ * \section overview Overview
+ *
+ * This library will both decode and encode theora packets to/from raw YUV 
+ * frames.  In either case, the packets will most likely either come from or
+ * need to be embedded in an Ogg stream.  Use 
+ * <a href="http://xiph.org/ogg/">libogg</a> or 
+ * <a href="http://www.annodex.net/software/liboggz/index.html">liboggz</a>
+ * to extract/package these packets.
+ *
+ * \section decoding Decoding Process
+ *
+ * Decoding can be separated into the following steps:
+ * -# initialise theora_info and theora_comment structures using 
+ *    theora_info_init() and theora_comment_init():
+ \verbatim
+ theora_info     info;
+ theora_comment  comment;
+   
+ theora_info_init(&info);
+ theora_comment_init(&comment);
+ \endverbatim
+ * -# retrieve header packets from Ogg stream (there should be 3) and decode 
+ *    into theora_info and theora_comment structures using 
+ *    theora_decode_header().  See \ref identification for more information on 
+ *    identifying which packets are theora packets.
+ \verbatim
+ int i;
+ for (i = 0; i < 3; i++)
+ {
+   (get a theora packet "op" from the Ogg stream)
+   theora_decode_header(&info, &comment, op);
+ }
+ \endverbatim
+ * -# initialise the decoder based on the information retrieved into the
+ *    theora_info struct by theora_decode_header().  You will need a 
+ *    theora_state struct.
+ \verbatim
+ theora_state state;
+ 
+ theora_decode_init(&state, &info);
+ \endverbatim
+ * -# pass in packets and retrieve decoded frames!  See the yuv_buffer 
+ *    documentation for information on how to retrieve raw YUV data.
+ \verbatim
+ yuf_buffer buffer;
+ while (last packet was not e_o_s) {
+   (get a theora packet "op" from the Ogg stream)
+   theora_decode_packetin(&state, op);
+   theora_decode_YUVout(&state, &buffer);
+ }
+ \endverbatim
+ *  
+ *
+ * \subsection identification Identifying Theora Packets
+ *
+ * All streams inside an Ogg file have a unique serial_no attached to the 
+ * stream.  Typically, you will want to 
+ *  - retrieve the serial_no for each b_o_s (beginning of stream) page 
+ *    encountered within the Ogg file; 
+ *  - test the first (only) packet on that page to determine if it is a theora 
+ *    packet;
+ *  - once you have found a theora b_o_s page then use the retrieved serial_no 
+ *    to identify future packets belonging to the same theora stream.
+ * 
+ * Note that you \e cannot use theora_packet_isheader() to determine if a 
+ * packet is a theora packet or not, as this function does not perform any
+ * checking beyond whether a header bit is present.  Instead, use the
+ * theora_decode_header() function and check the return value; or examine the
+ * header bytes at the beginning of the Ogg page.
+ *
+ * \subsection example Example Decoder 
+ *
+ * See <a href="http://svn.xiph.org/trunk/theora/examples/dump_video.c">
+ * examples/dump_video.c</a> for a simple decoder implementation.
+ *
+ * \section encoding Encoding Process
+ *
+ * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c">
+ * examples/encoder_example.c</a> for a simple encoder implementation.
+ */
+
+/** \file
+ * The libtheora pre-1.0 legacy C API.
+ */
+
+/**
+ * A YUV buffer for passing uncompressed frames to and from the codec.
+ * This holds a Y'CbCr frame in planar format. The CbCr planes can be
+ * subsampled and have their own separate dimensions and row stride
+ * offsets. Note that the strides may be negative in some 
+ * configurations. For theora the width and height of the largest plane
+ * must be a multiple of 16. The actual meaningful picture size and 
+ * offset are stored in the theora_info structure; frames returned by
+ * the decoder may need to be cropped for display.
+ *
+ * All samples are 8 bits. Within each plane samples are ordered by
+ * row from the top of the frame to the bottom. Within each row samples
+ * are ordered from left to right.
+ *
+ * During decode, the yuv_buffer struct is allocated by the user, but all
+ * fields (including luma and chroma pointers) are filled by the library.  
+ * These pointers address library-internal memory and their contents should 
+ * not be modified.
+ *
+ * Conversely, during encode the user allocates the struct and fills out all
+ * fields.  The user also manages the data addressed by the luma and chroma
+ * pointers.  See the encoder_example.c and dump_video.c example files in
+ * theora/examples/ for more information.
+ */
+typedef struct {
+    int   y_width;      /**< Width of the Y' luminance plane */
+    int   y_height;     /**< Height of the luminance plane */
+    int   y_stride;     /**< Offset in bytes between successive rows */
+
+    int   uv_width;     /**< Width of the Cb and Cr chroma planes */
+    int   uv_height;    /**< Height of the chroma planes */
+    int   uv_stride;    /**< Offset between successive chroma rows */
+    unsigned char *y;   /**< Pointer to start of luminance data */
+    unsigned char *u;   /**< Pointer to start of Cb data */
+    unsigned char *v;   /**< Pointer to start of Cr data */
+
+} yuv_buffer;
+
+/**
+ * A Colorspace.
+ */
+typedef enum {
+  OC_CS_UNSPECIFIED,    /**< The colorspace is unknown or unspecified */
+  OC_CS_ITU_REC_470M,   /**< This is the best option for 'NTSC' content */
+  OC_CS_ITU_REC_470BG,  /**< This is the best option for 'PAL' content */
+  OC_CS_NSPACES         /**< This marks the end of the defined colorspaces */
+} theora_colorspace;
+
+/**
+ * A Chroma subsampling
+ *
+ * These enumerate the available chroma subsampling options supported
+ * by the theora format. See Section 4.4 of the specification for
+ * exact definitions.
+ */
+typedef enum {
+  OC_PF_420,    /**< Chroma subsampling by 2 in each direction (4:2:0) */
+  OC_PF_RSVD,   /**< Reserved value */
+  OC_PF_422,    /**< Horizonatal chroma subsampling by 2 (4:2:2) */
+  OC_PF_444,    /**< No chroma subsampling at all (4:4:4) */
+} theora_pixelformat;
+
+/**
+ * Theora bitstream info.
+ * Contains the basic playback parameters for a stream,
+ * corresponding to the initial 'info' header packet.
+ * 
+ * Encoded theora frames must be a multiple of 16 in width and height.
+ * To handle other frame sizes, a crop rectangle is specified in
+ * frame_height and frame_width, offset_x and * offset_y. The offset
+ * and size should still be a multiple of 2 to avoid chroma sampling
+ * shifts. Offset values in this structure are measured from the
+ * upper left of the image.
+ *
+ * Frame rate, in frames per second, is stored as a rational
+ * fraction. Aspect ratio is also stored as a rational fraction, and
+ * refers to the aspect ratio of the frame pixels, not of the
+ * overall frame itself.
+ * 
+ * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c">
+ * examples/encoder_example.c</a> for usage examples of the
+ * other paramters and good default settings for the encoder parameters.
+ */
+typedef struct {
+  ogg_uint32_t  width;		/**< encoded frame width  */
+  ogg_uint32_t  height;		/**< encoded frame height */
+  ogg_uint32_t  frame_width;	/**< display frame width  */
+  ogg_uint32_t  frame_height;	/**< display frame height */
+  ogg_uint32_t  offset_x;	/**< horizontal offset of the displayed frame */
+  ogg_uint32_t  offset_y;	/**< vertical offset of the displayed frame */
+  ogg_uint32_t  fps_numerator;	    /**< frame rate numerator **/
+  ogg_uint32_t  fps_denominator;    /**< frame rate denominator **/
+  ogg_uint32_t  aspect_numerator;   /**< pixel aspect ratio numerator */
+  ogg_uint32_t  aspect_denominator; /**< pixel aspect ratio denominator */
+  theora_colorspace colorspace;	    /**< colorspace */
+  int           target_bitrate;	    /**< nominal bitrate in bits per second */
+  int           quality;  /**< Nominal quality setting, 0-63 */
+  int           quick_p;  /**< Quick encode/decode */
+
+  /* decode only */
+  unsigned char version_major;
+  unsigned char version_minor;
+  unsigned char version_subminor;
+
+  void *codec_setup;
+
+  /* encode only */
+  int           dropframes_p;
+  int           keyframe_auto_p;
+  ogg_uint32_t  keyframe_frequency;
+  ogg_uint32_t  keyframe_frequency_force;  /* also used for decode init to
+                                              get granpos shift correct */
+  ogg_uint32_t  keyframe_data_target_bitrate;
+  ogg_int32_t   keyframe_auto_threshold;
+  ogg_uint32_t  keyframe_mindistance;
+  ogg_int32_t   noise_sensitivity;
+  ogg_int32_t   sharpness;
+
+  theora_pixelformat pixelformat;	/**< chroma subsampling mode to expect */
+
+} theora_info;
+
+/** Codec internal state and context.
+ */
+typedef struct{
+  theora_info *i;
+  ogg_int64_t granulepos;
+
+  void *internal_encode;
+  void *internal_decode;
+
+} theora_state;
+
+/** 
+ * Comment header metadata.
+ *
+ * This structure holds the in-stream metadata corresponding to
+ * the 'comment' header packet.
+ *
+ * Meta data is stored as a series of (tag, value) pairs, in
+ * length-encoded string vectors. The first occurence of the 
+ * '=' character delimits the tag and value. A particular tag
+ * may occur more than once. The character set encoding for
+ * the strings is always UTF-8, but the tag names are limited
+ * to case-insensitive ASCII. See the spec for details.
+ *
+ * In filling in this structure, theora_decode_header() will
+ * null-terminate the user_comment strings for safety. However,
+ * the bitstream format itself treats them as 8-bit clean,
+ * and so the length array should be treated as authoritative
+ * for their length.
+ */
+typedef struct theora_comment{
+  char **user_comments;         /**< An array of comment string vectors */
+  int   *comment_lengths;       /**< An array of corresponding string vector lengths in bytes */
+  int    comments;              /**< The total number of comment string vectors */
+  char  *vendor;                /**< The vendor string identifying the encoder, null terminated */
+
+} theora_comment;
+
+
+/**\name theora_control() codes */
+
+/**\anchor decctlcodes
+ * These are the available request codes for theora_control()
+ * when called with a decoder instance.
+ * By convention, these are odd, to distinguish them from the
+ *  \ref encctlcodes "encoder control codes".
+ * Keep any experimental or vendor-specific values above \c 0x8000.*/
+
+/**Get the maximum post-processing level.
+ * The decoder supports a post-processing filter that can improve
+ * the appearance of the decoded images. This returns the highest
+ * level setting for this post-processor, corresponding to maximum
+ * improvement and computational expense.
+ */
+#define TH_DECCTL_GET_PPLEVEL_MAX (1)
+
+/**Set the post-processing level.
+ * Sets the level of post-processing to use when decoding the 
+ * compressed stream. This must be a value between zero (off)
+ * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX.
+ */
+#define TH_DECCTL_SET_PPLEVEL (3)
+
+/**Set the granule position.
+ * Call this after a seek, to update the internal granulepos
+ * in the decoder, to insure that subsequent frames are marked
+ * properly. If you track timestamps yourself and do not use
+ * the granule postion returned by the decoder, then you do
+ * not need to use this control.
+ */
+#define TH_DECCTL_SET_GRANPOS (5)
+
+
+/**\anchor encctlcodes
+ * These are the available request codes for theora_control()
+ * when called with an encoder instance.
+ * By convention, these are even, to distinguish them from the
+ *  \ref decctlcodes "decoder control codes".
+ * Keep any experimental or vendor-specific values above \c 0x8000.*/
+/*@{*/
+/**Sets the Huffman tables to use.
+ * The tables are copied, not stored by reference, so they can be freed after
+ *  this call.
+ * <tt>NULL</tt> may be specified to revert to the default tables.
+ *
+ * \param[in] buf <tt>#th_huff_code[#TH_NHUFFMAN_TABLES][#TH_NDCT_TOKENS]</tt>
+ * \retval TH_FAULT  \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun or one or more of the given
+ *                     tables is not full or prefix-free, \a buf is
+ *                     <tt>NULL</tt> and \a buf_sz is not zero, or \a buf is
+ *                     non-<tt>NULL</tt> and \a buf_sz is not
+ *                     <tt>sizeof(#th_huff_code)*#TH_NHUFFMAN_TABLES*#TH_NDCT_TOKENS</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_HUFFMAN_CODES (0)
+/**Sets the quantization parameters to use.
+ * The parameters are copied, not stored by reference, so they can be freed
+ *  after this call.
+ * <tt>NULL</tt> may be specified to revert to the default parameters.
+ * For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater than
+ *  <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must be no
+ *  greater than <tt>base[qti][pli][qi-1][ci]</tt>.
+ * These two conditions ensure that the actual quantizer for a given \a qti,
+ *  \a pli, and \a ci does not increase as \a qi increases.
+ *
+ * \param[in] buf #th_quant_info
+ * \retval TH_FAULT  \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun, the quantization parameters
+ *                    do not meet one of the above stated conditions, \a buf
+ *                    is <tt>NULL</tt> and \a buf_sz is not zero, or \a buf
+ *                    is non-<tt>NULL</tt> and \a buf_sz is not
+ *                    <tt>sizeof(#th_quant_info)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_QUANT_PARAMS (2)
+/**Sets the maximum distance between key frames.
+ * This can be changed during an encode, but will be bounded by
+ *  <tt>1<<th_info#keyframe_granule_shift</tt>.
+ * If it is set before encoding begins, th_info#keyframe_granule_shift will
+ *  be enlarged appropriately.
+ *
+ * \param[in]  buf <tt>ogg_uint32_t</tt>: The maximum distance between key
+ *                   frames.
+ * \param[out] buf <tt>ogg_uint32_t</tt>: The actual maximum distance set.
+ * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
+/**Disables any encoder features that would prevent lossless transcoding back
+ *  to VP3.
+ * This primarily means disabling block-level QI values and not using 4MV mode
+ *  when any of the luma blocks in a macro block are not coded.
+ * It also includes using the VP3 quantization tables and Huffman codes; if you
+ *  set them explicitly after calling this function, the resulting stream will
+ *  not be VP3-compatible.
+ * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
+ *  material, or when using a picture region smaller than the full frame (e.g.
+ *  a non-multiple-of-16 width or height), then non-VP3 bitstream features will
+ *  still be disabled, but the stream will still not be VP3-compatible, as VP3
+ *  was not capable of encoding such formats.
+ * If you call this after encoding has already begun, then the quantization
+ *  tables and codebooks cannot be changed, but the frame-level features will
+ *  be enabled or disabled as requested.
+ *
+ * \param[in]  buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
+ *                   or 0 to disable it (the default).
+ * \param[out] buf <tt>int</tt>: 1 if all bitstream features required for
+ *                   VP3-compatibility could be set, and 0 otherwise.
+ *                  The latter will be returned if the pixel format is not
+ *                   4:2:0, the picture region is smaller than the full frame,
+ *                   or if encoding has begun, preventing the quantization
+ *                   tables and codebooks from being set.
+ * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+/**Gets the maximum speed level.
+ * Higher speed levels favor quicker encoding over better quality per bit.
+ * Depending on the encoding mode, and the internal algorithms used, quality
+ *  may actually improve, but in this case bitrate will also likely increase.
+ * In any case, overall rate/distortion performance will probably decrease.
+ * The maximum value, and the meaning of each value, may change depending on
+ *  the current encoding mode (VBR vs. CQI, etc.).
+ *
+ * \param[out] buf int: The maximum encoding speed level.
+ * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+/**Sets the speed level.
+ * By default a speed value of 1 is used.
+ *
+ * \param[in] buf int: The new encoding speed level.
+ *                      0 is slowest, larger values use less CPU.
+ * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    encoding speed level is out of bounds.
+ *                   The maximum encoding speed level may be
+ *                    implementation- and encoding mode-specific, and can be
+ *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ * \retval TH_IMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_SPLEVEL (14)
+/**Puts the encoder in VBR mode.
+ * This can be done at any time during the encoding process, with different
+ *  configuration parameters, to encode different regions of the video segment
+ *  with different qualities.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.
+ *
+ * \param[in] buf <tt>#th_vbr_cfg</tt>: the configuration parameters.
+ *                 This may be <tt>NULL</tt>, in which case the current VBR
+ *                  configuration is unchanged.
+ *                 The default is to use the QI setting passed in via the
+ *                  #th_info struct when the encoder was initialized, with a
+ *                  full range of admissible quantizers.
+ * \retval OC_EFAULT \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL The configuration parameters do not meet one of their
+ *                    stated requirements, \a buf is <tt>NULL</tt> and
+ *                    \a buf_sz is not zero, or \a buf is non-<tt>NULL</tt>
+ *                    and \a buf_sz is not <tt>sizeof(#th_vbr_cfg)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SETUP_VBR (16)
+/**Puts the encoder in CQI mode.
+ * This can be done at any time during the encoding process, with different QI
+ *  values.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.
+ *
+ * \param[in] buf <tt>#th_cqi_cfg</tt>: the configuration parameters.
+ *                 This may be <tt>NULL</tt>, in which case the current CQI
+ *                  configuration is unchanged.
+ *                 The default is to use the QI setting passed in via the
+ *                  #th_info struct when the encoder was initialized.
+ * \retval OC_EFAULT \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(#th_cqi_cfg)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SETUP_CQI (18)
+/*@}*/
+
+#define OC_FAULT       -1       /**< General failure */
+#define OC_EINVAL      -10      /**< Library encountered invalid internal data */
+#define OC_DISABLED    -11      /**< Requested action is disabled */
+#define OC_BADHEADER   -20      /**< Header packet was corrupt/invalid */
+#define OC_NOTFORMAT   -21      /**< Packet is not a theora packet */
+#define OC_VERSION     -22      /**< Bitstream version is not handled */
+#define OC_IMPL        -23      /**< Feature or action not implemented */
+#define OC_BADPACKET   -24      /**< Packet is corrupt */
+#define OC_NEWPACKET   -25      /**< Packet is an (ignorable) unhandled extension */
+#define OC_DUPFRAME    1        /**< Packet is a dropped frame */
+
+/** 
+ * Retrieve a human-readable string to identify the encoder vendor and version.
+ * \returns A version string.
+ */
+extern const char *theora_version_string(void);
+
+/**
+ * Retrieve a 32-bit version number.
+ * This number is composed of a 16-bit major version, 8-bit minor version
+ * and 8 bit sub-version, composed as follows:
+<pre>
+   (VERSION_MAJOR<<16) + (VERSION_MINOR<<8) + (VERSION_SUB)
+</pre>
+* \returns The version number.
+*/
+extern ogg_uint32_t theora_version_number(void);
+
+/**
+ * Initialize the theora encoder.
+ * \param th The theora_state handle to initialize for encoding.
+ * \param ti A theora_info struct filled with the desired encoding parameters.
+ * \retval 0 Success
+ */
+extern int theora_encode_init(theora_state *th, theora_info *ti);
+
+/**
+ * Submit a YUV buffer to the theora encoder.
+ * \param t A theora_state handle previously initialized for encoding.
+ * \param yuv A buffer of YUV data to encode.  Note that both the yuv_buffer
+ *            struct and the luma/chroma buffers within should be allocated by
+ *            the user.
+ * \retval OC_EINVAL Encoder is not ready, or is finished.
+ * \retval -1 The size of the given frame differs from those previously input
+ * \retval 0 Success
+ */
+extern int theora_encode_YUVin(theora_state *t, yuv_buffer *yuv);
+
+/**
+ * Request the next packet of encoded video. 
+ * The encoded data is placed in a user-provided ogg_packet structure.
+ * \param t A theora_state handle previously initialized for encoding.
+ * \param last_p whether this is the last packet the encoder should produce.
+ * \param op An ogg_packet structure to fill. libtheora will set all
+ *           elements of this structure, including a pointer to encoded
+ *           data. The memory for the encoded data is owned by libtheora.
+ * \retval 0 No internal storage exists OR no packet is ready
+ * \retval -1 The encoding process has completed
+ * \retval 1 Success
+ */
+extern int theora_encode_packetout( theora_state *t, int last_p,
+                                    ogg_packet *op);
+
+/**
+ * Request a packet containing the initial header.
+ * A pointer to the header data is placed in a user-provided ogg_packet
+ * structure.
+ * \param t A theora_state handle previously initialized for encoding.
+ * \param op An ogg_packet structure to fill. libtheora will set all
+ *           elements of this structure, including a pointer to the header
+ *           data. The memory for the header data is owned by libtheora.
+ * \retval 0 Success
+ */
+extern int theora_encode_header(theora_state *t, ogg_packet *op);
+
+/**
+ * Request a comment header packet from provided metadata.
+ * A pointer to the comment data is placed in a user-provided ogg_packet
+ * structure.
+ * \param tc A theora_comment structure filled with the desired metadata
+ * \param op An ogg_packet structure to fill. libtheora will set all
+ *           elements of this structure, including a pointer to the encoded
+ *           comment data. The memory for the comment data is owned by
+ *           libtheora.
+ * \retval 0 Success
+ */
+extern int theora_encode_comment(theora_comment *tc, ogg_packet *op);
+
+/**
+ * Request a packet containing the codebook tables for the stream.
+ * A pointer to the codebook data is placed in a user-provided ogg_packet
+ * structure.
+ * \param t A theora_state handle previously initialized for encoding.
+ * \param op An ogg_packet structure to fill. libtheora will set all
+ *           elements of this structure, including a pointer to the codebook
+ *           data. The memory for the header data is owned by libtheora.
+ * \retval 0 Success
+ */
+extern int theora_encode_tables(theora_state *t, ogg_packet *op);
+
+/**
+ * Decode an Ogg packet, with the expectation that the packet contains
+ * an initial header, comment data or codebook tables.
+ *
+ * \param ci A theora_info structure to fill. This must have been previously
+ *           initialized with theora_info_init(). If \a op contains an initial
+ *           header, theora_decode_header() will fill \a ci with the
+ *           parsed header values. If \a op contains codebook tables,
+ *           theora_decode_header() will parse these and attach an internal
+ *           representation to \a ci->codec_setup.
+ * \param cc A theora_comment structure to fill. If \a op contains comment
+ *           data, theora_decode_header() will fill \a cc with the parsed
+ *           comments.
+ * \param op An ogg_packet structure which you expect contains an initial
+ *           header, comment data or codebook tables.
+ *
+ * \retval OC_BADHEADER \a op is NULL; OR the first byte of \a op->packet
+ *                      has the signature of an initial packet, but op is
+ *                      not a b_o_s packet; OR this packet has the signature
+ *                      of an initial header packet, but an initial header
+ *                      packet has already been seen; OR this packet has the
+ *                      signature of a comment packet, but the initial header
+ *                      has not yet been seen; OR this packet has the signature
+ *                      of a comment packet, but contains invalid data; OR
+ *                      this packet has the signature of codebook tables,
+ *                      but the initial header or comments have not yet
+ *                      been seen; OR this packet has the signature of codebook
+ *                      tables, but contains invalid data;
+ *                      OR the stream being decoded has a compatible version
+ *                      but this packet does not have the signature of a
+ *                      theora initial header, comments, or codebook packet
+ * \retval OC_VERSION   The packet data of \a op is an initial header with
+ *                      a version which is incompatible with this version of
+ *                      libtheora.
+ * \retval OC_NEWPACKET the stream being decoded has an incompatible (future)
+ *                      version and contains an unknown signature.
+ * \retval 0            Success
+ *
+ * \note The normal usage is that theora_decode_header() be called on the
+ *       first three packets of a theora logical bitstream in succession.
+ */
+extern int theora_decode_header(theora_info *ci, theora_comment *cc,
+                                ogg_packet *op);
+
+/**
+ * Initialize a theora_state handle for decoding.
+ * \param th The theora_state handle to initialize.
+ * \param c  A theora_info struct filled with the desired decoding parameters.
+ *           This is of course usually obtained from a previous call to
+ *           theora_decode_header().
+ * \retval 0 Success
+ */
+extern int theora_decode_init(theora_state *th, theora_info *c);
+
+/**
+ * Input a packet containing encoded data into the theora decoder.
+ * \param th A theora_state handle previously initialized for decoding.
+ * \param op An ogg_packet containing encoded theora data.
+ * \retval 0 Success
+ * \retval OC_BADPACKET \a op does not contain encoded video data
+ */
+extern int theora_decode_packetin(theora_state *th,ogg_packet *op);
+
+/**
+ * Output the next available frame of decoded YUV data.
+ * \param th A theora_state handle previously initialized for decoding.
+ * \param yuv A yuv_buffer in which libtheora should place the decoded data.
+ *            Note that the buffer struct itself is allocated by the user, but
+ *            that the luma and chroma pointers will be filled in by the 
+ *            library.  Also note that these luma and chroma regions should be 
+ *            considered read-only by the user.
+ * \retval 0 Success
+ */
+extern int theora_decode_YUVout(theora_state *th,yuv_buffer *yuv);
+
+/**
+ * Report whether a theora packet is a header or not
+ * This function does no verification beyond checking the header
+ * flag bit so it should not be used for bitstream identification;
+ * use theora_decode_header() for that.
+ *
+ * \param op An ogg_packet containing encoded theora data.
+ * \retval 1 The packet is a header packet
+ * \retval 0 The packet is not a header packet (and so contains frame data)
+ *
+ * Thus function was added in the 1.0alpha4 release.
+ */
+extern int theora_packet_isheader(ogg_packet *op);
+
+/**
+ * Report whether a theora packet is a keyframe or not
+ *
+ * \param op An ogg_packet containing encoded theora data.
+ * \retval 1 The packet contains a keyframe image
+ * \retval 0 The packet is contains an interframe delta
+ * \retval -1 The packet is not an image data packet at all
+ *
+ * Thus function was added in the 1.0alpha4 release.
+ */
+extern int theora_packet_iskeyframe(ogg_packet *op);
+
+/**
+ * Report the granulepos shift radix
+ *
+ * When embedded in Ogg, Theora uses a two-part granulepos, 
+ * splitting the 64-bit field into two pieces. The more-significant
+ * section represents the frame count at the last keyframe,
+ * and the less-significant section represents the count of
+ * frames since the last keyframe. In this way the overall
+ * field is still non-decreasing with time, but usefully encodes
+ * a pointer to the last keyframe, which is necessary for
+ * correctly restarting decode after a seek. 
+ *
+ * This function reports the number of bits used to represent
+ * the distance to the last keyframe, and thus how the granulepos
+ * field must be shifted or masked to obtain the two parts.
+ * 
+ * Since libtheora returns compressed data in an ogg_packet
+ * structure, this may be generally useful even if the Theora
+ * packets are not being used in an Ogg container. 
+ *
+ * \param ti A previously initialized theora_info struct
+ * \returns The bit shift dividing the two granulepos fields
+ *
+ * This function was added in the 1.0alpha5 release.
+ */
+int theora_granule_shift(theora_info *ti);
+
+/**
+ * Convert a granulepos to an absolute frame index, starting at 0.
+ * The granulepos is interpreted in the context of a given theora_state handle.
+ * 
+ * Note that while the granulepos encodes the frame count (i.e. starting
+ * from 1) this call returns the frame index, starting from zero. Thus
+ * One can calculate the presentation time by multiplying the index by
+ * the rate.
+ *
+ * \param th A previously initialized theora_state handle (encode or decode)
+ * \param granulepos The granulepos to convert.
+ * \returns The frame index corresponding to \a granulepos.
+ * \retval -1 The given granulepos is undefined (i.e. negative)
+ *
+ * Thus function was added in the 1.0alpha4 release.
+ */
+extern ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos);
+
+/**
+ * Convert a granulepos to absolute time in seconds. The granulepos is
+ * interpreted in the context of a given theora_state handle, and gives
+ * the end time of a frame's presentation as used in Ogg mux ordering.
+ *
+ * \param th A previously initialized theora_state handle (encode or decode)
+ * \param granulepos The granulepos to convert.
+ * \returns The absolute time in seconds corresponding to \a granulepos.
+ *          This is the "end time" for the frame, or the latest time it should
+ *           be displayed.
+ *          It is not the presentation time.
+ * \retval -1. The given granulepos is undefined (i.e. negative), or
+ * \retval -1. The function has been disabled because floating 
+ *              point support is not available.
+ */
+extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos);
+
+/**
+ * Initialize a theora_info structure. All values within the given theora_info
+ * structure are initialized, and space is allocated within libtheora for
+ * internal codec setup data.
+ * \param c A theora_info struct to initialize.
+ */
+extern void theora_info_init(theora_info *c);
+
+/**
+ * Clear a theora_info structure. All values within the given theora_info
+ * structure are cleared, and associated internal codec setup data is freed.
+ * \param c A theora_info struct to initialize.
+ */
+extern void theora_info_clear(theora_info *c);
+
+/**
+ * Free all internal data associated with a theora_state handle.
+ * \param t A theora_state handle.
+ */
+extern void theora_clear(theora_state *t);
+
+/**
+ * Initialize an allocated theora_comment structure
+ * \param tc An allocated theora_comment structure 
+ **/
+extern void theora_comment_init(theora_comment *tc);
+
+/**
+ * Add a comment to an initialized theora_comment structure
+ * \param tc A previously initialized theora comment structure
+ * \param comment A null-terminated string encoding the comment in the form
+ *                "TAG=the value"
+ *
+ * Neither theora_comment_add() nor theora_comment_add_tag() support
+ * comments containing null values, although the bitstream format
+ * supports this. To add such comments you will need to manipulate
+ * the theora_comment structure directly.
+ **/
+
+extern void theora_comment_add(theora_comment *tc, char *comment);
+
+/**
+ * Add a comment to an initialized theora_comment structure.
+ * \param tc A previously initialized theora comment structure
+ * \param tag A null-terminated string containing the tag 
+ *            associated with the comment.
+ * \param value The corresponding value as a null-terminated string
+ *
+ * Neither theora_comment_add() nor theora_comment_add_tag() support
+ * comments containing null values, although the bitstream format
+ * supports this. To add such comments you will need to manipulate
+ * the theora_comment structure directly.
+ **/
+extern void theora_comment_add_tag(theora_comment *tc,
+                                       char *tag, char *value);
+
+/**
+ * Look up a comment value by tag.
+ * \param tc Tn initialized theora_comment structure
+ * \param tag The tag to look up
+ * \param count The instance of the tag. The same tag can appear multiple
+ *              times, each with a distinct and ordered value, so an index
+ *              is required to retrieve them all.
+ * \returns A pointer to the queried tag's value
+ * \retval NULL No matching tag is found
+ *
+ * \note Use theora_comment_query_count() to get the legal range for the
+ * count parameter.
+ **/
+
+extern char *theora_comment_query(theora_comment *tc, char *tag, int count);
+
+/** Look up the number of instances of a tag.
+ *  \param tc An initialized theora_comment structure
+ *  \param tag The tag to look up
+ *  \returns The number on instances of a particular tag.
+ * 
+ *  Call this first when querying for a specific tag and then interate
+ *  over the number of instances with separate calls to 
+ *  theora_comment_query() to retrieve all instances in order.
+ **/
+extern int   theora_comment_query_count(theora_comment *tc, char *tag);
+
+/**
+ * Clear an allocated theora_comment struct so that it can be freed.
+ * \param tc An allocated theora_comment structure.
+ **/
+extern void  theora_comment_clear(theora_comment *tc);
+
+/**Encoder control function.
+ * This is used to provide advanced control the encoding process.
+ * \param th     A #theora_state handle.
+ * \param req    The control code to process.
+ *                See \ref encctlcodes "the list of available control codes"
+ *                 for details.
+ * \param buf    The parameters for this control code.
+ * \param buf_sz The size of the parameter buffer.*/
+extern int theora_control(theora_state *th,int req,void *buf,size_t buf_sz);
+
+/* @} */ /* end oldfuncs doxygen group */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _O_THEORA_H_ */
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/include/theora/theoradec.h
@@ -0,0 +1,290 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
+
+ ********************************************************************/
+
+/**\file
+ * The <tt>libtheoradec</tt> C decoding API.*/
+
+#if !defined(_O_THEORA_THEORADEC_H_)
+# define _O_THEORA_THEORADEC_H_ (1)
+# include <ogg/ogg.h>
+# include "codec.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/**\name th_decode_ctl() codes
+ * \anchor decctlcodes
+ * These are the available request codes for th_decode_ctl().
+ * By convention, these are odd, to distinguish them from the
+ *  \ref encctlcodes "encoder control codes".
+ * Keep any experimental or vendor-specific values above \c 0x8000.*/
+/*@{*/
+/**Gets the maximum post-processing level.
+ *
+ * \param[out] _buf int: The maximum post-processing level.
+ * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_DECCTL_GET_PPLEVEL_MAX (1)
+/**Sets the post-processing level.
+ * By default, post-processing is disabled.
+ *
+ * \param[in] _buf int: The new post-processing level.
+ *                      0 to disable; larger values use more CPU.
+ * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                     post-processing level is out of bounds.
+ *                    The maximum post-processing level may be
+ *                     implementation-specific, and can be obtained via
+ *                     #TH_DECCTL_GET_PPLEVEL_MAX.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_DECCTL_SET_PPLEVEL (3)
+/**Sets the granule position.
+ * Call this after a seek, before decoding the first frame, to ensure that the
+ *  proper granule position is returned for all subsequent frames.
+ * If you track timestamps yourself and do not use the granule position
+ *  returned by the decoder, then you need not call this function.
+ *
+ * \param[in] _buf <tt>ogg_int64_t</tt>: The granule position of the next
+ *                  frame.
+ * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(ogg_int64_t)</tt>, or the
+ *                     granule position is negative.*/
+#define TH_DECCTL_SET_GRANPOS (5)
+/**Sets the striped decode callback function.
+ * If set, this function will be called as each piece of a frame is fully
+ *  decoded in th_decode_packetin().
+ * You can pass in a #th_stripe_callback with
+ *  th_stripe_callback#stripe_decoded set to <tt>NULL</tt> to disable the
+ *  callbacks at any point.
+ * Enabling striped decode does not prevent you from calling
+ *  th_decode_ycbcr_out() after the frame is fully decoded.
+ *
+ * \param[in]  _buf #th_stripe_callback: The callback parameters.
+ * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL  \a _buf_sz is not
+ *                     <tt>sizeof(th_stripe_callback)</tt>.*/
+#define TH_DECCTL_SET_STRIPE_CB (7)
+/*@}*/
+
+
+
+/**A callback function for striped decode.
+ * This is a function pointer to an application-provided function that will be
+ *  called each time a section of the image is fully decoded in
+ *  th_decode_packetin().
+ * This allows the application to process the section immediately, while it is
+ *  still in cache.
+ * Note that the frame is decoded bottom to top, so \a _yfrag0 will steadily
+ *  decrease with each call until it reaches 0, at which point the full frame
+ *  is decoded.
+ * The number of fragment rows made available in each call depends on the pixel
+ *  format and the number of post-processing filters enabled, and may not even
+ *  be constant for the entire frame.
+ * If a non-<tt>NULL</tt> \a _granpos pointer is passed to
+ *  th_decode_packetin(), the granule position for the frame will be stored
+ *  in it before the first callback is made.
+ * If an entire frame is dropped (a 0-byte packet), then no callbacks will be
+ *  made at all for that frame.
+ * \param _ctx       An application-provided context pointer.
+ * \param _buf       The image buffer for the decoded frame.
+ * \param _yfrag0    The Y coordinate of the first row of 8x8 fragments
+ *                    decoded.
+ *                   Multiply this by 8 to obtain the pixel row number in the
+ *                    luma plane.
+ *                   If the chroma planes are subsampled in the Y direction,
+ *                    this will always be divisible by two.
+ * \param _yfrag_end The Y coordinate of the first row of 8x8 fragments past
+ *                    the newly decoded section.
+ *                   If the chroma planes are subsampled in the Y direction,
+ *                    this will always be divisible by two.
+ *                   I.e., this section contains fragment rows
+ *                    <tt>\a _yfrag0 ...\a _yfrag_end -1</tt>.*/
+typedef void (*th_stripe_decoded_func)(void *_ctx,th_ycbcr_buffer _buf,
+ int _yfrag0,int _yfrag_end);
+
+/**The striped decode callback data to pass to #TH_DECCTL_SET_STRIPE_CB.*/
+typedef struct{
+  /**An application-provided context pointer.
+   * This will be passed back verbatim to the application.*/
+  void                   *ctx;
+  /**The callback function pointer.*/
+  th_stripe_decoded_func  stripe_decoded;
+}th_stripe_callback;
+
+
+
+/**\name Decoder state
+   The following data structures are opaque, and their contents are not
+    publicly defined by this API.
+   Referring to their internals directly is unsupported, and may break without
+    warning.*/
+/*@{*/
+/**The decoder context.*/
+typedef struct th_dec_ctx    th_dec_ctx;
+/**Setup information.
+   This contains auxiliary information (Huffman tables and quantization
+    parameters) decoded from the setup header by th_decode_headerin() to be
+    passed to th_decode_alloc().
+   It can be re-used to initialize any number of decoders, and can be freed
+    via th_setup_free() at any time.*/
+typedef struct th_setup_info th_setup_info;
+/*@}*/
+
+
+
+/**\defgroup decfuncs Functions for Decoding*/
+/*@{*/
+/**\name Functions for decoding
+ * You must link to <tt>libtheoradec</tt> if you use any of the 
+ * functions in this section.
+ *
+ * The functions are listed in the order they are used in a typical decode.
+ * The basic steps are:
+ * - Parse the header packets by repeatedly calling th_decode_headerin().
+ * - Allocate a #th_dec_ctx handle with th_decode_alloc().
+ * - Call th_setup_free() to free any memory used for codec setup
+ *    information.
+ * - Perform any additional decoder configuration with th_decode_ctl().
+ * - For each video data packet:
+ *   - Submit the packet to the decoder via th_decode_packetin().
+ *   - Retrieve the uncompressed video data via th_decode_ycbcr_out().
+ * - Call th_decode_free() to release all decoder memory.*/
+/*@{*/
+/**Decodes the header packets of a Theora stream.
+ * This should be called on the initial packets of the stream, in succession,
+ *  until it returns <tt>0</tt>, indicating that all headers have been
+ *  processed, or an error is encountered.
+ * At least three header packets are required, and additional optional header
+ *  packets may follow.
+ * This can be used on the first packet of any logical stream to determine if
+ *  that stream is a Theora stream.
+ * \param _info  A #th_info structure to fill in.
+ *               This must have been previously initialized with
+ *                th_info_init().
+ *               The application may immediately begin using the contents of
+ *                this structure after the first header is decoded, though it
+ *                must continue to be passed in on all subsequent calls.
+ * \param _tc    A #th_comment structure to fill in.
+ *               The application may immediately begin using the contents of
+ *                this structure after the second header is decoded, though it
+ *                must continue to be passed in on all subsequent calls.
+ * \param _setup Returns a pointer to additional, private setup information
+ *                needed by the decoder.
+ *               The contents of this pointer must be initialized to
+ *                <tt>NULL</tt> on the first call, and the returned value must
+ *                continue to be passed in on all subsequent calls.
+ * \param _op    An <tt>ogg_packet</tt> structure which contains one of the
+ *                initial packets of an Ogg logical stream.
+ * \return A positive value indicates that a Theora header was successfully
+ *          processed.
+ * \retval 0             The first video data packet was encountered after all
+ *                        required header packets were parsed.
+ *                       The packet just passed in on this call should be saved
+ *                        and fed to th_decode_packetin() to begin decoding
+ *                        video data.
+ * \retval TH_EFAULT     One of \a _info, \a _tc, or \a _setup was
+ *                        <tt>NULL</tt>.
+ * \retval TH_EBADHEADER \a _op was <tt>NULL</tt>, the packet was not the next
+ *                        header packet in the expected sequence, or the format
+ *                        of the header data was invalid.
+ * \retval TH_EVERSION   The packet data was a Theora info header, but for a
+ *                        bitstream version not decodable with this version of
+ *                        <tt>libtheoradec</tt>.
+ * \retval TH_ENOTFORMAT The packet was not a Theora header.
+ */
+extern int th_decode_headerin(th_info *_info,th_comment *_tc,
+ th_setup_info **_setup,ogg_packet *_op);
+/**Allocates a decoder instance.
+ * \param _info  A #th_info struct filled via th_decode_headerin().
+ * \param _setup A #th_setup_info handle returned via
+ *                th_decode_headerin().
+ * \return The initialized #th_dec_ctx handle.
+ * \retval NULL If the decoding parameters were invalid.*/
+extern th_dec_ctx *th_decode_alloc(const th_info *_info,
+ const th_setup_info *_setup);
+/**Releases all storage used for the decoder setup information.
+ * This should be called after you no longer want to create any decoders for
+ *  a stream whose headers you have parsed with th_decode_headerin().
+ * \param _setup The setup information to free.
+ *               This can safely be <tt>NULL</tt>.*/
+extern void th_setup_free(th_setup_info *_setup);
+/**Decoder control function.
+ * This is used to provide advanced control of the decoding process.
+ * \param _dec    A #th_dec_ctx handle.
+ * \param _req    The control code to process.
+ *                See \ref decctlcodes "the list of available control codes"
+ *                 for details.
+ * \param _buf    The parameters for this control code.
+ * \param _buf_sz The size of the parameter buffer.*/
+extern int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf,
+ size_t _buf_sz);
+/**Submits a packet containing encoded video data to the decoder.
+ * \param _dec     A #th_dec_ctx handle.
+ * \param _op      An <tt>ogg_packet</tt> containing encoded video data.
+ * \param _granpos Returns the granule position of the decoded packet.
+ *                 If non-<tt>NULL</tt>, the granule position for this specific
+ *                  packet is stored in this location.
+ *                 This is computed incrementally from previously decoded
+ *                  packets.
+ *                 After a seek, the correct granule position must be set via
+ *                  #TH_DECCTL_SET_GRANPOS for this to work properly.
+ * \retval 0             Success.
+ *                       A new decoded frame can be retrieved by calling
+ *                        th_decode_ycbcr_out().
+ * \retval TH_DUPFRAME   The packet represented a dropped (0-byte) frame.
+ *                       The player can skip the call to th_decode_ycbcr_out(),
+ *                        as the contents of the decoded frame buffer have not
+ *                        changed.
+ * \retval TH_EFAULT     \a _dec or _op was <tt>NULL</tt>.
+ * \retval TH_EBADPACKET \a _op does not contain encoded video data.
+ * \retval TH_EIMPL      The video data uses bitstream features which this
+ *                        library does not support.*/
+extern int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
+ ogg_int64_t *_granpos);
+/**Outputs the next available frame of decoded Y'CbCr data.
+ * If a striped decode callback has been set with #TH_DECCTL_SET_STRIPE_CB,
+ *  then the application does not need to call this function.
+ * \param _dec   A #th_dec_ctx handle.
+ * \param _ycbcr A video buffer structure to fill in.
+ *               <tt>libtheoradec</tt> will fill in all the members of this
+ *                structure, including the pointers to the uncompressed video
+ *                data.
+ *               The memory for this video data is owned by
+ *                <tt>libtheoradec</tt>.
+ *               It may be freed or overwritten without notification when
+ *                subsequent frames are decoded.
+ * \retval 0 Success
+ */
+extern int th_decode_ycbcr_out(th_dec_ctx *_dec,
+ th_ycbcr_buffer _ycbcr);
+/**Frees an allocated decoder instance.
+ * \param _dec A #th_dec_ctx handle.*/
+extern void th_decode_free(th_dec_ctx *_dec);
+/*@}*/
+/*@}*/
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/Makefile.in
@@ -0,0 +1,92 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla code.
+#
+# The Initial Developer of the Original Code is the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Chris Double <chris.double@double.co.nz>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= theora
+LIBRARY_NAME	= theora
+FORCE_STATIC_LIB= 1
+
+# The encoder is currently not included.
+DEFINES += -DTHEORA_DISABLE_ENCODE
+
+ifeq ($(findstring 86,$(OS_TEST)), 86)
+DEFINES += -DOC_X86ASM
+endif
+
+ifeq ($(OS_ARCH),Linux)
+DEFINES += -DUSE_ASM
+endif
+
+CSRCS		= \
+		cpu.c \
+		dec/huffdec.c \
+		dec/quant.c \
+		dec/dequant.c \
+		dec/bitwise.c \
+		dec/internal.c \
+		dec/decinfo.c \
+		dec/decapiwrapper.c \
+		dec/idct.c \
+		dec/state.c \
+		dec/info.c \
+		dec/fragment.c \
+		dec/apiwrapper.c \
+		dec/decode.c \
+		$(NULL)
+
+ifeq ($(findstring 86,$(OS_TEST)), 86)
+CSRCS		+= \
+		dec/x86/mmxfrag.c \
+		dec/x86/x86state.c \
+		dec/x86/mmxstate.c \
+		dec/x86/mmxidct.c \
+		$(NULL)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+LOCAL_INCLUDES = -I$(srcdir)
+EXTRA_OBJDIRS = dec dec/x86
+
+export::
+	mkdir -p $(EXTRA_OBJDIRS)
+
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/config.h
@@ -0,0 +1,80 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <soundcard.h> header file. */
+/* #undef HAVE_SOUNDCARD_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+#define HAVE_SYS_SOUNDCARD_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* enable x86 assambler optimization */
+ 
+
+/* Name of package */
+#define PACKAGE "libtheora"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libtheora"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libtheora 1.0beta3"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libtheora"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.0beta3"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to exclude encode support from the build */
+ 
+
+/* Define to exclude floating point code from the build */
+/* #undef THEORA_DISABLE_FLOAT */
+
+/* make use of asm optimization */
+ 
+
+/* Version number of package */
+#define VERSION "1.0beta3"
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/cpu.c
@@ -0,0 +1,162 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+ 
+ CPU capability detection for x86 processors.
+  Originally written by Rudolf Marek.
+  
+ function:
+  last mod: $Id: cpu.c 14718 2008-04-12 08:36:58Z conrad $
+
+ ********************************************************************/
+
+#include "cpu.h"
+
+#if !defined(USE_ASM)
+
+ogg_uint32_t oc_cpu_flags_get(void){
+  return 0;
+}
+
+#else /* USE_ASM */
+
+# if defined(_MSC_VER)
+/*  Visual C cpuid helper function. For VS2005 we could
+    as well use the _cpuid builtin, but that wouldn't work
+    for VS2003 users, so we do it in inline assembler */
+
+static void oc_cpuid_helper (ogg_uint32_t * CpuInfo, ogg_uint32_t op){
+  _asm {
+    mov eax, [op]
+    mov esi, CpuInfo
+    cpuid
+    mov [esi + 0], eax
+    mov [esi + 4], ebx
+    mov [esi + 8], ecx
+    mov [esi +12], edx
+  }
+}
+
+#  define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  {                                    \
+    ogg_uint32_t nfo[4];               \
+    oc_cpuid_helper (nfo, (_op));      \
+    (_eax) = nfo[0],(_ebx) = nfo[1];   \
+    (_ecx) = nfo[2],(_edx) = nfo[3];   \
+  }
+
+# elif (defined(__amd64__) || defined(__x86_64__))
+
+#  define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  __asm__ __volatile__( \
+   "push %%rbx\n\t" \
+   "cpuid\n\t" \
+   "movl %%ebx,%1\n\t" \
+   "pop  %%rbx\n\t" \
+   :"=a" (_eax), \
+    "=r" (_ebx), \
+    "=c" (_ecx), \
+    "=d" (_edx) \
+   :"a" (_op) \
+   :"cc" \
+  )
+# else /* x86_32, GCC */
+
+#  define cpuid(_op,_eax,_ebx,_ecx,_edx) \
+  __asm__ __volatile__( \
+   "pushl %%ebx\n\t" \
+   "cpuid\n\t" \
+   "movl  %%ebx,%1\n\t" \
+   "popl  %%ebx\n\t" \
+   :"=a" (_eax), \
+    "=r" (_ebx), \
+    "=c" (_ecx), \
+    "=d" (_edx) \
+   :"a" (_op) \
+   :"cc" \
+  )
+
+# endif /* arch switch */
+
+ogg_uint32_t oc_cpu_flags_get(void){
+  ogg_uint32_t flags = 0;
+  ogg_uint32_t eax;
+  ogg_uint32_t ebx;
+  ogg_uint32_t ecx;
+  ogg_uint32_t edx;
+
+# if !defined(_MSC_VER) && !defined(__amd64__) && !defined(__x86_64__)
+  /* check for cpuid */
+  __asm__ __volatile__(
+   "pushfl\n\t"
+   "pushfl\n\t"
+   "popl          %0\n\t"
+   "movl          %0,%1\n\t"
+   "xorl   $0x200000,%0\n\t"
+   "pushl         %0\n\t"
+   "popfl\n\t"
+   "pushfl\n\t"
+   "popl          %0\n\t"
+   "popfl\n\t"
+   :"=r" (eax),
+    "=r" (ebx)
+   :
+   :"cc"
+  );
+  /*No cpuid.*/
+  if(eax==ebx)return 0;
+# endif /* GCC, x86_32 */
+
+  cpuid(0,eax,ebx,ecx,edx);
+  if(ebx==0x756e6547&&edx==0x49656e69&&ecx==0x6c65746e){
+    /*Intel:*/
+inteltest:
+    cpuid(1,eax,ebx,ecx,edx);
+    if((edx&0x00800000)==0)return 0;
+    flags=OC_CPU_X86_MMX;
+    if(edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE;
+    if(edx&0x04000000)flags|=OC_CPU_X86_SSE2;
+  }
+  else if(ebx==0x68747541&&edx==0x69746e65&&ecx==0x444d4163 ||
+          ebx==0x646f6547&&edx==0x79622065&&ecx==0x43534e20){
+    /*AMD:*/
+    /*Geode:*/
+    cpuid(0x80000000,eax,ebx,ecx,edx);
+    if(eax<0x80000001)goto inteltest;
+    cpuid(0x80000001,eax,ebx,ecx,edx);
+    if((edx&0x00800000)==0)return 0;
+    flags=OC_CPU_X86_MMX;
+    if(edx&0x80000000)flags|=OC_CPU_X86_3DNOW;
+    if(edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT;
+    if(edx&0x00400000)flags|=OC_CPU_X86_MMXEXT;
+  }
+  else{
+    /*Implement me.*/
+    flags=0;
+  }
+
+# ifdef DEBUG
+  if (flags) {
+    TH_DEBUG("vectorized instruction sets supported:");
+    if (flags & OC_CPU_X86_MMX)      TH_DEBUG(" mmx");
+    if (flags & OC_CPU_X86_MMXEXT)   TH_DEBUG(" mmxext");
+    if (flags & OC_CPU_X86_SSE)      TH_DEBUG(" sse");
+    if (flags & OC_CPU_X86_SSE2)     TH_DEBUG(" sse2");
+    if (flags & OC_CPU_X86_3DNOW)    TH_DEBUG(" 3dnow");
+    if (flags & OC_CPU_X86_3DNOWEXT) TH_DEBUG(" 3dnowext");
+    TH_DEBUG("\n");
+  }
+# endif
+
+  return flags;
+}
+
+#endif /* USE_ASM */
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/cpu.h
@@ -0,0 +1,30 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+ function:
+    last mod: $Id: cpu.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+#if !defined(_x86_cpu_H)
+# define _x86_cpu_H (1)
+#include "internal.h"
+
+#define OC_CPU_X86_MMX    (1<<0)
+#define OC_CPU_X86_3DNOW  (1<<1)
+#define OC_CPU_X86_3DNOWEXT (1<<2)
+#define OC_CPU_X86_MMXEXT (1<<3)
+#define OC_CPU_X86_SSE    (1<<4)
+#define OC_CPU_X86_SSE2   (1<<5)
+
+ogg_uint32_t oc_cpu_flags_get(void);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/apiwrapper.c
@@ -0,0 +1,166 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: apiwrapper.c 14321 2007-12-22 18:09:29Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "apiwrapper.h"
+
+
+
+const char *theora_version_string(void){
+  return th_version_string();
+}
+
+ogg_uint32_t theora_version_number(void){
+  return th_version_number();
+}
+
+void theora_info_init(theora_info *_ci){
+  memset(_ci,0,sizeof(*_ci));
+}
+
+void theora_info_clear(theora_info *_ci){
+  th_api_wrapper *api;
+  api=(th_api_wrapper *)_ci->codec_setup;
+  memset(_ci,0,sizeof(*_ci));
+  if(api!=NULL){
+    if(api->clear!=NULL)(*api->clear)(api);
+    _ogg_free(api);
+  }
+}
+
+void theora_clear(theora_state *_th){
+  /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
+  if(_th->internal_decode!=NULL){
+    (*((oc_state_dispatch_vtbl *)_th->internal_decode)->clear)(_th);
+  }
+  if(_th->internal_encode!=NULL){
+    (*((oc_state_dispatch_vtbl *)_th->internal_encode)->clear)(_th);
+  }
+  if(_th->i!=NULL)theora_info_clear(_th->i);
+  memset(_th,0,sizeof(*_th));
+}
+
+int theora_control(theora_state *_th,int _req,void *_buf,size_t _buf_sz){
+  /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
+  if(_th->internal_decode!=NULL){
+    return (*((oc_state_dispatch_vtbl *)_th->internal_decode)->control)(_th,
+     _req,_buf,_buf_sz);
+  }
+  else if(_th->internal_encode!=NULL){
+    return (*((oc_state_dispatch_vtbl *)_th->internal_encode)->control)(_th,
+     _req,_buf,_buf_sz);
+  }
+  else return TH_EINVAL;
+}
+
+ogg_int64_t theora_granule_frame(theora_state *_th,ogg_int64_t _gp){
+  /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
+  if(_th->internal_decode!=NULL){
+    return (*((oc_state_dispatch_vtbl *)_th->internal_decode)->granule_frame)(
+     _th,_gp);
+  }
+  else if(_th->internal_encode!=NULL){
+    return (*((oc_state_dispatch_vtbl *)_th->internal_encode)->granule_frame)(
+     _th,_gp);
+  }
+  else return -1;
+}
+
+double theora_granule_time(theora_state *_th, ogg_int64_t _gp){
+  /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
+  if(_th->internal_decode!=NULL){
+    return (*((oc_state_dispatch_vtbl *)_th->internal_decode)->granule_time)(
+     _th,_gp);
+  }
+  else if(_th->internal_encode!=NULL){
+    return (*((oc_state_dispatch_vtbl *)_th->internal_encode)->granule_time)(
+     _th,_gp);
+  }
+  else return -1;
+}
+
+void oc_theora_info2th_info(th_info *_info,const theora_info *_ci){
+  _info->version_major=_ci->version_major;
+  _info->version_minor=_ci->version_minor;
+  _info->version_subminor=_ci->version_subminor;
+  _info->frame_width=_ci->width;
+  _info->frame_height=_ci->height;
+  _info->pic_width=_ci->frame_width;
+  _info->pic_height=_ci->frame_height;
+  _info->pic_x=_ci->offset_x;
+  _info->pic_y=_ci->offset_y;
+  _info->fps_numerator=_ci->fps_numerator;
+  _info->fps_denominator=_ci->fps_denominator;
+  _info->aspect_numerator=_ci->aspect_numerator;
+  _info->aspect_denominator=_ci->aspect_denominator;
+  switch(_ci->colorspace){
+    case OC_CS_ITU_REC_470M:_info->colorspace=TH_CS_ITU_REC_470M;break;
+    case OC_CS_ITU_REC_470BG:_info->colorspace=TH_CS_ITU_REC_470BG;break;
+    default:_info->colorspace=TH_CS_UNSPECIFIED;break;
+  }
+  switch(_ci->pixelformat){
+    case OC_PF_420:_info->pixel_fmt=TH_PF_420;break;
+    case OC_PF_422:_info->pixel_fmt=TH_PF_422;break;
+    case OC_PF_444:_info->pixel_fmt=TH_PF_444;break;
+    default:_info->pixel_fmt=TH_PF_RSVD;
+  }
+  _info->target_bitrate=_ci->target_bitrate;
+  _info->quality=_ci->quality;
+  _info->keyframe_granule_shift=_ci->keyframe_frequency_force>0?
+   OC_MINI(31,oc_ilog(_ci->keyframe_frequency_force-1)):0;
+}
+
+int theora_packet_isheader(ogg_packet *_op){
+  return th_packet_isheader(_op);
+}
+
+int theora_packet_iskeyframe(ogg_packet *_op){
+  return th_packet_iskeyframe(_op);
+}
+
+int theora_granule_shift(theora_info *_ci){
+  /*This breaks when keyframe_frequency_force is not positive or is larger than
+     2**31 (if your int is more than 32 bits), but that's what the original
+     function does.*/
+  return oc_ilog(_ci->keyframe_frequency_force-1);
+}
+
+void theora_comment_init(theora_comment *_tc){
+  th_comment_init((th_comment *)_tc);
+}
+
+char *theora_comment_query(theora_comment *_tc,char *_tag,int _count){
+  return th_comment_query((th_comment *)_tc,_tag,_count);
+}
+
+int theora_comment_query_count(theora_comment *_tc,char *_tag){
+  return th_comment_query_count((th_comment *)_tc,_tag);
+}
+
+void theora_comment_clear(theora_comment *_tc){
+  th_comment_clear((th_comment *)_tc);
+}
+
+void theora_comment_add(theora_comment *_tc,char *_comment){
+  th_comment_add((th_comment *)_tc,_comment);
+}
+
+void theora_comment_add_tag(theora_comment *_tc, char *_tag, char *_value){
+  th_comment_add_tag((th_comment *)_tc,_tag,_value);
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/apiwrapper.h
@@ -0,0 +1,55 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: apiwrapper.h 13596 2007-08-23 20:05:38Z tterribe $
+
+ ********************************************************************/
+
+#if !defined(_apiwrapper_H)
+# define _apiwrapper_H (1)
+# include <ogg/ogg.h>
+# include <theora/theora.h>
+# include "theora/theoradec.h"
+/*# include "theora/theoraenc.h"*/
+typedef struct th_enc_ctx th_enc_ctx;
+# include "../internal.h"
+
+typedef struct th_api_wrapper th_api_wrapper;
+typedef struct th_api_info    th_api_info;
+
+/*Provide an entry point for the codec setup to clear itself in case we ever
+   want to break pieces off into a common base library shared by encoder and
+   decoder.
+  In addition, this makes several other pieces of the API wrapper cleaner.*/
+typedef void (*oc_setup_clear_func)(void *_ts);
+
+/*Generally only one of these pointers will be non-NULL in any given instance.
+  Technically we do not even really need this struct, since we should be able
+   to figure out which one from "context", but doing it this way makes sure we
+   don't flub it up.*/
+struct th_api_wrapper{
+  oc_setup_clear_func  clear;
+  th_setup_info       *setup;
+  th_dec_ctx          *decode;
+  th_enc_ctx          *encode;
+};
+
+struct th_api_info{
+  th_api_wrapper api;
+  theora_info    info;
+};
+
+
+void oc_theora_info2th_info(th_info *_info,const theora_info *_ci);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/bitwise.c
@@ -0,0 +1,126 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: packing variable sized words into an octet stream
+  last mod: $Id: bitwise.c 14546 2008-02-29 01:14:05Z tterribe $
+
+ ********************************************************************/
+
+/* We're 'MSb' endian; if we write a word but read individual bits,
+   then we'll read the msb first */
+
+#include <string.h>
+#include <stdlib.h>
+#include "bitwise.h"
+
+void theorapackB_reset(oggpack_buffer *b){
+  b->ptr=b->buffer;
+  b->buffer[0]=0;
+  b->endbit=b->endbyte=0;
+}
+
+void theorapackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
+  memset(b,0,sizeof(*b));
+  b->buffer=b->ptr=buf;
+  b->storage=bytes;
+}
+
+int theorapackB_look1(oggpack_buffer *b,long *_ret){
+  if(b->endbyte>=b->storage){
+    *_ret=0L;
+    return -1;
+  }
+  *_ret=((b->ptr[0]>>(7-b->endbit))&1);
+  return 0;
+}
+
+void theorapackB_adv1(oggpack_buffer *b){
+  if(++(b->endbit)>7){
+    b->endbit=0;
+    b->ptr++;
+    b->endbyte++;
+  }
+}
+
+/* bits <= 32 */
+int theorapackB_read(oggpack_buffer *b,int bits,long *_ret){
+  long ret;
+  long m;
+  int fail;
+  m=32-bits;
+  bits+=b->endbit;
+  if(b->endbyte+4>=b->storage){
+    /* not the main path */
+    if(b->endbyte*8+bits>b->storage*8){
+      *_ret=0L;
+      fail=-1;
+      goto overflow;
+    }
+    /* special case to avoid reading b->ptr[0], which might be past the end of
+        the buffer; also skips some useless accounting */
+    else if(!bits){
+      *_ret=0L;
+      return 0;
+    }
+  }
+  ret=b->ptr[0]<<(24+b->endbit);
+  if(bits>8){
+    ret|=b->ptr[1]<<(16+b->endbit);
+    if(bits>16){
+      ret|=b->ptr[2]<<(8+b->endbit);
+      if(bits>24){
+        ret|=b->ptr[3]<<(b->endbit);
+        if(bits>32 && b->endbit)
+          ret|=b->ptr[4]>>(8-b->endbit);
+      }
+    }
+  }
+  *_ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
+  fail=0;
+overflow:
+  b->ptr+=bits/8;
+  b->endbyte+=bits/8;
+  b->endbit=bits&7;
+  return fail;
+}
+
+int theorapackB_read1(oggpack_buffer *b,long *_ret){
+  int fail;
+  if(b->endbyte>=b->storage){
+    /* not the main path */
+    *_ret=0L;
+    fail=-1;
+    goto overflow;
+  }
+  *_ret=(b->ptr[0]>>(7-b->endbit))&1;
+  fail=0;
+overflow:
+  b->endbit++;
+  if(b->endbit>7){
+    b->endbit=0;
+    b->ptr++;
+    b->endbyte++;
+  }
+  return fail;
+}
+
+long theorapackB_bytes(oggpack_buffer *b){
+  return(b->endbyte+(b->endbit+7)/8);
+}
+
+long theorapackB_bits(oggpack_buffer *b){
+  return(b->endbyte*8+b->endbit);
+}
+
+unsigned char *theorapackB_get_buffer(oggpack_buffer *b){
+  return(b->buffer);
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/bitwise.h
@@ -0,0 +1,76 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: packing variable sized words into an octet stream
+  last mod: $Id: bitwise.c 7675 2004-09-01 00:34:39Z xiphmont $
+
+ ********************************************************************/
+#if !defined(_bitwise_H)
+# define _bitwise_H (1)
+# include <ogg/ogg.h>
+
+void theorapackB_reset(oggpack_buffer *b);
+void theorapackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+/* Read in bits without advancing the bitptr; bits <= 32 */
+static int theorapackB_look(oggpack_buffer *b,int bits,long *_ret);
+int theorapackB_look1(oggpack_buffer *b,long *_ret);
+static void theorapackB_adv(oggpack_buffer *b,int bits);
+void theorapackB_adv1(oggpack_buffer *b);
+/* bits <= 32 */
+int theorapackB_read(oggpack_buffer *b,int bits,long *_ret);
+int theorapackB_read1(oggpack_buffer *b,long *_ret);
+long theorapackB_bytes(oggpack_buffer *b);
+long theorapackB_bits(oggpack_buffer *b);
+unsigned char *theorapackB_get_buffer(oggpack_buffer *b);
+
+/*These two functions are only used in one place, and declaring them static so
+   they can be inlined saves considerable function call overhead.*/
+
+/* Read in bits without advancing the bitptr; bits <= 32 */
+static int theorapackB_look(oggpack_buffer *b,int bits,long *_ret){
+  long ret;
+  long m;
+  m=32-bits;
+  bits+=b->endbit;
+  if(b->endbyte+4>=b->storage){
+    /* not the main path */
+    if(b->endbyte>=b->storage){
+      *_ret=0L;
+      return -1;
+    }
+    /*If we have some bits left, but not enough, return the ones we have.*/
+    if((b->storage-b->endbyte)*8<bits)bits=(b->storage-b->endbyte)*8;
+  }
+  ret=b->ptr[0]<<(24+b->endbit);
+  if(bits>8){
+    ret|=b->ptr[1]<<(16+b->endbit);
+    if(bits>16){
+      ret|=b->ptr[2]<<(8+b->endbit);
+      if(bits>24){
+        ret|=b->ptr[3]<<(b->endbit);
+        if(bits>32&&b->endbit)
+          ret|=b->ptr[4]>>(8-b->endbit);
+      }
+    }
+  }
+  *_ret=((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
+  return 0;
+}
+
+static void theorapackB_adv(oggpack_buffer *b,int bits){
+  bits+=b->endbit;
+  b->ptr+=bits/8;
+  b->endbyte+=bits/8;
+  b->endbit=bits&7;
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/dct.h
@@ -0,0 +1,31 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: dct.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+/*Definitions shared by the forward and inverse DCT transforms.*/
+#if !defined(_dct_H)
+# define _dct_H (1)
+
+/*cos(n*pi/16) (resp. sin(m*pi/16)) scaled by 65536.*/
+#define OC_C1S7 ((ogg_int32_t)64277)
+#define OC_C2S6 ((ogg_int32_t)60547)
+#define OC_C3S5 ((ogg_int32_t)54491)
+#define OC_C4S4 ((ogg_int32_t)46341)
+#define OC_C5S3 ((ogg_int32_t)36410)
+#define OC_C6S2 ((ogg_int32_t)25080)
+#define OC_C7S1 ((ogg_int32_t)12785)
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/decapiwrapper.c
@@ -0,0 +1,202 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: decapiwrapper.c 13596 2007-08-23 20:05:38Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "apiwrapper.h"
+#include "theora/theoradec.h"
+
+static void th_dec_api_clear(th_api_wrapper *_api){
+  if(_api->setup)th_setup_free(_api->setup);
+  if(_api->decode)th_decode_free(_api->decode);
+  memset(_api,0,sizeof(*_api));
+}
+
+static void theora_decode_clear(theora_state *_td){
+  if(_td->i!=NULL)theora_info_clear(_td->i);
+#ifdef _TH_DEBUG_
+  fclose(debugout);
+  debugout=NULL;
+#endif
+  memset(_td,0,sizeof(*_td));
+}
+
+static int theora_decode_control(theora_state *_td,int _req,
+ void *_buf,size_t _buf_sz){
+  return th_decode_ctl(((th_api_wrapper *)_td->i->codec_setup)->decode,
+   _req,_buf,_buf_sz);
+}
+
+static ogg_int64_t theora_decode_granule_frame(theora_state *_td,
+ ogg_int64_t _gp){
+  return th_granule_frame(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
+}
+
+static double theora_decode_granule_time(theora_state *_td,ogg_int64_t _gp){
+  return th_granule_time(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
+}
+
+static const oc_state_dispatch_vtbl OC_DEC_DISPATCH_VTBL={
+  (oc_state_clear_func)theora_decode_clear,
+  (oc_state_control_func)theora_decode_control,
+  (oc_state_granule_frame_func)theora_decode_granule_frame,
+  (oc_state_granule_time_func)theora_decode_granule_time,
+};
+
+static void th_info2theora_info(theora_info *_ci,const th_info *_info){
+  _ci->version_major=_info->version_major;
+  _ci->version_minor=_info->version_minor;
+  _ci->version_subminor=_info->version_subminor;
+  _ci->width=_info->frame_width;
+  _ci->height=_info->frame_height;
+  _ci->frame_width=_info->pic_width;
+  _ci->frame_height=_info->pic_height;
+  _ci->offset_x=_info->pic_x;
+  _ci->offset_y=_info->pic_y;
+  _ci->fps_numerator=_info->fps_numerator;
+  _ci->fps_denominator=_info->fps_denominator;
+  _ci->aspect_numerator=_info->aspect_numerator;
+  _ci->aspect_denominator=_info->aspect_denominator;
+  switch(_info->colorspace){
+    case TH_CS_ITU_REC_470M:_ci->colorspace=OC_CS_ITU_REC_470M;break;
+    case TH_CS_ITU_REC_470BG:_ci->colorspace=OC_CS_ITU_REC_470BG;break;
+    default:_ci->colorspace=OC_CS_UNSPECIFIED;break;
+  }
+  switch(_info->pixel_fmt){
+    case TH_PF_420:_ci->pixelformat=OC_PF_420;break;
+    case TH_PF_422:_ci->pixelformat=OC_PF_422;break;
+    case TH_PF_444:_ci->pixelformat=OC_PF_444;break;
+    default:_ci->pixelformat=OC_PF_RSVD;
+  }
+  _ci->target_bitrate=_info->target_bitrate;
+  _ci->quality=_info->quality;
+  _ci->keyframe_frequency_force=1<<_info->keyframe_granule_shift;
+}
+
+int theora_decode_init(theora_state *_td,theora_info *_ci){
+  th_api_info    *apiinfo;
+  th_api_wrapper *api;
+  th_info         info;
+
+  api=(th_api_wrapper *)_ci->codec_setup;
+  /*Allocate our own combined API wrapper/theora_info struct.
+    We put them both in one malloc'd block so that when the API wrapper is
+     freed, the info struct goes with it.
+    This avoids having to figure out whether or not we need to free the info
+     struct in either theora_info_clear() or theora_clear().*/
+  apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo));
+  /*Make our own copy of the info struct, since its lifetime should be
+     independent of the one we were passed in.*/
+  *&apiinfo->info=*_ci;
+  /*Convert the info struct now instead of saving the the one we decoded with
+     theora_decode_header(), since the user might have modified values (i.e.,
+     color space, aspect ratio, etc. can be specified from a higher level).
+    The user also might be doing something "clever" with the header packets if
+     they are not using an Ogg encapsulation.*/
+  oc_theora_info2th_info(&info,_ci);
+  /*Don't bother to copy the setup info; th_decode_alloc() makes its own copy
+     of the stuff it needs.*/
+  apiinfo->api.decode=th_decode_alloc(&info,api->setup);
+  if(apiinfo->api.decode==NULL){
+    _ogg_free(apiinfo);
+    return OC_EINVAL;
+  }
+  apiinfo->api.clear=(oc_setup_clear_func)th_dec_api_clear;
+  _td->internal_encode=NULL;
+  /*Provide entry points for ABI compatibility with old decoder shared libs.*/
+  _td->internal_decode=(void *)&OC_DEC_DISPATCH_VTBL;
+  _td->granulepos=0;
+  _td->i=&apiinfo->info;
+  _td->i->codec_setup=&apiinfo->api;
+  return 0;
+}
+
+int theora_decode_header(theora_info *_ci,theora_comment *_cc,ogg_packet *_op){
+  th_api_wrapper *api;
+  th_info         info;
+  int             ret;
+
+#ifdef _TH_DEBUG_
+  debugout = fopen("theoradec-debugout.txt","w");
+#endif
+
+  api=(th_api_wrapper *)_ci->codec_setup;
+  /*Allocate an API wrapper struct on demand, since it will not also include a
+     theora_info struct like the ones that are used in a theora_state struct.*/
+  if(api==NULL){
+    _ci->codec_setup=_ogg_calloc(1,sizeof(*api));
+    api=(th_api_wrapper *)_ci->codec_setup;
+    api->clear=(oc_setup_clear_func)th_dec_api_clear;
+  }
+  /*Convert from the theora_info struct instead of saving our own th_info
+     struct between calls.
+    The user might be doing something "clever" with the header packets if they
+     are not using an Ogg encapsulation, and we don't want to break this.*/
+  oc_theora_info2th_info(&info,_ci);
+  /*We rely on the fact that theora_comment and th_comment structures are
+     actually identical.
+    Take care not to change this fact unless you change the code here as
+     well!*/
+  ret=th_decode_headerin(&info,(th_comment *)_cc,&api->setup,_op);
+  /*We also rely on the fact that the error return code values are the same,
+    and that the implementations of these two functions return the same set of
+    them.
+   Note that theora_decode_header() really can return OC_NOTFORMAT, even
+    though it is not currently documented to do so.*/
+  if(ret<0)return ret;
+  th_info2theora_info(_ci,&info);
+  return 0;
+}
+
+int theora_decode_packetin(theora_state *_td,ogg_packet *_op){
+  th_api_wrapper *api;
+  ogg_int64_t     gp;
+  int             ret;
+  api=(th_api_wrapper *)_td->i->codec_setup;
+  ret=th_decode_packetin(api->decode,_op,&gp);
+
+#ifdef _TH_DEBUG_
+  dframe++;
+#endif 
+
+  if(ret<0)return OC_BADPACKET;
+  _td->granulepos=gp;
+  return 0;
+}
+
+int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){
+  th_api_wrapper  *api;
+  th_ycbcr_buffer  buf;
+  int              ret;
+
+  api=(th_api_wrapper *)_td->i->codec_setup;
+  ret=th_decode_ycbcr_out(api->decode,buf);
+  if(ret>=0){
+    _yuv->y_width=buf[0].width;
+    _yuv->y_height=buf[0].height;
+    _yuv->y_stride=buf[0].stride;
+    _yuv->uv_width=buf[1].width;
+    _yuv->uv_height=buf[1].height;
+    _yuv->uv_stride=buf[1].stride;
+    _yuv->y=buf[0].data;
+    _yuv->u=buf[1].data;
+    _yuv->v=buf[2].data;
+  }
+
+  return ret;
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/decinfo.c
@@ -0,0 +1,239 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: decinfo.c 14719 2008-04-12 11:36:40Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "decint.h"
+
+
+
+/*Unpacks a series of octets from a given byte array into the pack buffer.
+  No checking is done to ensure the buffer contains enough data.
+  _opb: The pack buffer to read the octets from.
+  _buf: The byte array to store the unpacked bytes in.
+  _len: The number of octets to unpack.*/
+static void oc_unpack_octets(oggpack_buffer *_opb,char *_buf,size_t _len){
+  while(_len-->0){
+    long val;
+    theorapackB_read(_opb,8,&val);
+    *_buf++=(char)val;
+  }
+}
+
+/*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
+static long oc_unpack_length(oggpack_buffer *_opb){
+  long ret[4];
+  int  i;
+  for(i=0;i<4;i++)theorapackB_read(_opb,8,ret+i);
+  return ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24;
+}
+
+static int oc_info_unpack(oggpack_buffer *_opb,th_info *_info){
+  long val;
+  /*Check the codec bitstream version.*/
+  theorapackB_read(_opb,8,&val);
+  _info->version_major=(unsigned char)val;
+  theorapackB_read(_opb,8,&val);
+  _info->version_minor=(unsigned char)val;
+  theorapackB_read(_opb,8,&val);
+  _info->version_subminor=(unsigned char)val;
+  /*verify we can parse this bitstream version.
+     We accept earlier minors and all subminors, by spec*/
+  if(_info->version_major>TH_VERSION_MAJOR||
+   _info->version_major==TH_VERSION_MAJOR&&
+   _info->version_minor>TH_VERSION_MINOR){
+    return TH_EVERSION;
+  }
+  /*Read the encoded frame description.*/
+  theorapackB_read(_opb,16,&val);
+  _info->frame_width=(ogg_uint32_t)val<<4;
+  theorapackB_read(_opb,16,&val);
+  _info->frame_height=(ogg_uint32_t)val<<4;
+  theorapackB_read(_opb,24,&val);
+  _info->pic_width=(ogg_uint32_t)val;
+  theorapackB_read(_opb,24,&val);
+  _info->pic_height=(ogg_uint32_t)val;
+  theorapackB_read(_opb,8,&val);
+  _info->pic_x=(ogg_uint32_t)val;
+  /*Note: The sense of pic_y is inverted in what we pass back to the
+     application compared to how it is stored in the bitstream.
+    This is because the bitstream uses a right-handed coordinate system, while
+     applications expect a left-handed one.*/
+  theorapackB_read(_opb,8,&val);
+  _info->pic_y=_info->frame_height-_info->pic_height-(ogg_uint32_t)val;
+  theorapackB_read(_opb,32,&val);
+  _info->fps_numerator=(ogg_uint32_t)val;
+  theorapackB_read(_opb,32,&val);
+  _info->fps_denominator=(ogg_uint32_t)val;
+  if(_info->frame_width==0||_info->frame_height==0||
+   _info->pic_width+_info->pic_x>_info->frame_width||
+   _info->pic_height+_info->pic_y>_info->frame_height||
+   _info->fps_numerator==0||_info->fps_denominator==0){
+    return TH_EBADHEADER;
+  }
+  theorapackB_read(_opb,24,&val);
+  _info->aspect_numerator=(ogg_uint32_t)val;
+  theorapackB_read(_opb,24,&val);
+  _info->aspect_denominator=(ogg_uint32_t)val;
+  theorapackB_read(_opb,8,&val);
+  _info->colorspace=(th_colorspace)val;
+  theorapackB_read(_opb,24,&val);
+  _info->target_bitrate=(int)val;
+  theorapackB_read(_opb,6,&val);
+  _info->quality=(int)val;
+  theorapackB_read(_opb,5,&val);
+  _info->keyframe_granule_shift=(int)val;
+  theorapackB_read(_opb,2,&val);
+  _info->pixel_fmt=(th_pixel_fmt)val;
+  if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER;
+  if(theorapackB_read(_opb,3,&val)<0||val!=0)return TH_EBADHEADER;
+  return 0;
+}
+
+static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
+  long len;
+  int  i;
+  /*Read the vendor string.*/
+  len=oc_unpack_length(_opb);
+  if(len<0||theorapackB_bytes(_opb)+len>_opb->storage)return TH_EBADHEADER;
+  _tc->vendor=_ogg_malloc((size_t)len+1);
+  oc_unpack_octets(_opb,_tc->vendor,len);
+  _tc->vendor[len]='\0';
+  /*Read the user comments.*/
+  _tc->comments=(int)oc_unpack_length(_opb);
+  if(_tc->comments<0||_tc->comments>(LONG_MAX>>2)||
+   theorapackB_bytes(_opb)+((long)_tc->comments<<2)>_opb->storage){
+    return TH_EBADHEADER;
+  }
+  _tc->comment_lengths=(int *)_ogg_malloc(
+   _tc->comments*sizeof(_tc->comment_lengths[0]));
+  _tc->user_comments=(char **)_ogg_malloc(
+   _tc->comments*sizeof(_tc->user_comments[0]));
+  for(i=0;i<_tc->comments;i++){
+    len=oc_unpack_length(_opb);
+    if(len<0||theorapackB_bytes(_opb)+len>_opb->storage){
+      _tc->comments=i;
+      return TH_EBADHEADER;
+    }
+    _tc->comment_lengths[i]=len;
+    _tc->user_comments[i]=_ogg_malloc((size_t)len+1);
+    oc_unpack_octets(_opb,_tc->user_comments[i],len);
+    _tc->user_comments[i][len]='\0';
+  }
+  return theorapackB_read(_opb,0,&len)<0?TH_EBADHEADER:0;
+}
+
+static int oc_setup_unpack(oggpack_buffer *_opb,th_setup_info *_setup){
+  int ret;
+  /*Read the quantizer tables.*/
+  ret=oc_quant_params_unpack(_opb,&_setup->qinfo);
+  if(ret<0)return ret;
+  /*Read the Huffman trees.*/
+  return oc_huff_trees_unpack(_opb,_setup->huff_tables);
+}
+
+static void oc_setup_clear(th_setup_info *_setup){
+  oc_quant_params_clear(&_setup->qinfo);
+  oc_huff_trees_clear(_setup->huff_tables);
+}
+
+static int oc_dec_headerin(oggpack_buffer *_opb,th_info *_info,
+ th_comment *_tc,th_setup_info **_setup,ogg_packet *_op){
+  char buffer[6];
+  long val;
+  int  packtype;
+  int  ret;
+  theorapackB_read(_opb,8,&val);
+  packtype=(int)val;
+  /*If we're at a data packet and we have received all three headers, we're
+     done.*/
+  if(!(packtype&0x80)&&_info->frame_width>0&&_tc->vendor!=NULL&&*_setup!=NULL){
+    return 0;
+  }
+  /*Check the codec string.*/
+  oc_unpack_octets(_opb,buffer,6);
+  if(memcmp(buffer,"theora",6)!=0)return TH_ENOTFORMAT;
+  switch(packtype){
+    /*Codec info header.*/
+    case 0x80:{
+      /*This should be the first packet, and we should not already be
+         initialized.*/
+      if(!_op->b_o_s||_info->frame_width>0)return TH_EBADHEADER;
+      ret=oc_info_unpack(_opb,_info);
+      if(ret<0)th_info_clear(_info);
+      else ret=3;
+    }break;
+    /*Comment header.*/
+    case 0x81:{
+      if(_tc==NULL)return TH_EFAULT;
+      /*We shoud have already decoded the info header, and should not yet have
+         decoded the comment header.*/
+      if(_info->frame_width==0||_tc->vendor!=NULL)return TH_EBADHEADER;
+      ret=oc_comment_unpack(_opb,_tc);
+      if(ret<0)th_comment_clear(_tc);
+      else ret=2;
+    }break;
+    /*Codec setup header.*/
+    case 0x82:{
+      oc_setup_info *setup;
+      if(_tc==NULL||_setup==NULL)return TH_EFAULT;
+      /*We should have already decoded the info header and the comment header,
+         and should not yet have decoded the setup header.*/
+      if(_info->frame_width==0||_tc->vendor==NULL||*_setup!=NULL){
+        return TH_EBADHEADER;
+      }
+      setup=(oc_setup_info *)_ogg_calloc(1,sizeof(*setup));
+      ret=oc_setup_unpack(_opb,setup);
+      if(ret<0){
+        oc_setup_clear(setup);
+        _ogg_free(setup);
+      }
+      else{
+        *_setup=setup;
+        ret=1;
+      }
+    }break;
+    default:{
+      /*We don't know what this header is.*/
+      return TH_EBADHEADER;
+    }break;
+  }
+  return ret;
+}
+
+
+/*Decodes one header packet.
+  This should be called repeatedly with the packets at the beginning of the
+   stream until it returns 0.*/
+int th_decode_headerin(th_info *_info,th_comment *_tc,
+ th_setup_info **_setup,ogg_packet *_op){
+  oggpack_buffer opb;
+  int            ret;
+  if(_op==NULL)return TH_EBADHEADER;
+  if(_info==NULL)return TH_EFAULT;
+  theorapackB_readinit(&opb,_op->packet,_op->bytes);
+  ret=oc_dec_headerin(&opb,_info,_tc,_setup,_op);
+  return ret;
+}
+
+void th_setup_free(th_setup_info *_setup){
+  if(_setup!=NULL){
+    oc_setup_clear(_setup);
+    _ogg_free(_setup);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/decint.h
@@ -0,0 +1,95 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: decint.h 14369 2008-01-05 23:15:32Z tterribe $
+
+ ********************************************************************/
+
+#include <limits.h>
+#if !defined(_decint_H)
+# define _decint_H (1)
+# include "theora/theoradec.h"
+# include "../internal.h"
+# include "bitwise.h"
+
+typedef struct th_setup_info oc_setup_info;
+typedef struct th_dec_ctx    oc_dec_ctx;
+
+# include "idct.h"
+# include "huffdec.h"
+# include "dequant.h"
+
+/*Constants for the packet-in state machine specific to the decoder.*/
+
+/*Next packet to read: Data packet.*/
+#define OC_PACKET_DATA (0)
+
+
+
+struct th_setup_info{
+  /*The Huffman codes.*/
+  oc_huff_node      *huff_tables[TH_NHUFFMAN_TABLES];
+  /*The quantization parameters.*/
+  th_quant_info  qinfo;
+};
+
+
+
+struct th_dec_ctx{
+  /*Shared encoder/decoder state.*/
+  oc_theora_state          state;
+  /*Whether or not packets are ready to be emitted.
+    This takes on negative values while there are remaining header packets to
+     be emitted, reaches 0 when the codec is ready for input, and goes to 1
+     when a frame has been processed and a data packet is ready.*/
+  int                      packet_state;
+  /*Buffer in which to assemble packets.*/
+  oggpack_buffer           opb;
+  /*Huffman decode trees.*/
+  oc_huff_node            *huff_tables[TH_NHUFFMAN_TABLES];
+  /*The index of one past the last token in each plane for each coefficient.
+    The final entries are the total number of tokens for each coefficient.*/
+  int                      ti0[3][64];
+  /*The index of one past the last extra bits entry in each plane for each
+     coefficient.
+    The final entries are the total number of extra bits entries for each
+     coefficient.*/
+  int                      ebi0[3][64];
+  /*The number of outstanding EOB runs at the start of each coefficient in each
+     plane.*/
+  int                      eob_runs[3][64];
+  /*The DCT token lists.*/
+  unsigned char          **dct_tokens;
+  /*The extra bits associated with DCT tokens.*/
+  ogg_uint16_t           **extra_bits;
+  /*The out-of-loop post-processing level.*/
+  int                      pp_level;
+  /*The DC scale used for out-of-loop deblocking.*/
+  int                      pp_dc_scale[64];
+  /*The sharpen modifier used for out-of-loop deringing.*/
+  int                      pp_sharp_mod[64];
+  /*The DC quantization index of each block.*/
+  unsigned char           *dc_qis;
+  /*The variance of each block.*/
+  int                     *variances;
+  /*The storage for the post-processed frame buffer.*/
+  unsigned char           *pp_frame_data;
+  /*Whether or not the post-processsed frame buffer has space for chroma.*/
+  int                      pp_frame_has_chroma;
+  /*The buffer used for the post-processed frame.*/
+  th_ycbcr_buffer      pp_frame_buf;
+  /*The striped decode callback function.*/
+  th_stripe_callback   stripe_cb;
+};
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/decode.c
@@ -0,0 +1,2325 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: decode.c 14385 2008-01-09 19:53:18Z giles $
+  
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#include "decint.h"
+#if defined(OC_DUMP_IMAGES)
+# include <stdio.h>
+# include "png.h"
+#endif
+
+/*No post-processing.*/
+#define OC_PP_LEVEL_DISABLED  (0)
+/*Keep track of DC qi for each block only.*/
+#define OC_PP_LEVEL_TRACKDCQI (1)
+/*Deblock the luma plane.*/
+#define OC_PP_LEVEL_DEBLOCKY  (2)
+/*Dering the luma plane.*/
+#define OC_PP_LEVEL_DERINGY   (3)
+/*Stronger luma plane deringing.*/
+#define OC_PP_LEVEL_SDERINGY  (4)
+/*Deblock the chroma planes.*/
+#define OC_PP_LEVEL_DEBLOCKC  (5)
+/*Dering the chroma planes.*/
+#define OC_PP_LEVEL_DERINGC   (6)
+/*Stronger chroma plane deringing.*/
+#define OC_PP_LEVEL_SDERINGC  (7)
+/*Maximum valid post-processing level.*/
+#define OC_PP_LEVEL_MAX       (7)
+
+
+
+/*The mode alphabets for the various mode coding schemes.
+  Scheme 0 uses a custom alphabet, which is not stored in this table.*/
+static const int OC_MODE_ALPHABETS[7][OC_NMODES]={
+  /*Last MV dominates */
+  {
+    OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_MV,
+    OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
+    OC_MODE_INTER_MV_FOUR
+  },
+  {
+    OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_NOMV,
+    OC_MODE_INTER_MV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
+    OC_MODE_INTER_MV_FOUR
+  },
+  {
+    OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV,OC_MODE_INTER_MV_LAST2,
+    OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
+    OC_MODE_INTER_MV_FOUR
+  },
+  {
+    OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV,OC_MODE_INTER_NOMV,
+    OC_MODE_INTER_MV_LAST2,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,
+    OC_MODE_GOLDEN_MV,OC_MODE_INTER_MV_FOUR
+  },
+  /*No MV dominates.*/
+  {
+    OC_MODE_INTER_NOMV,OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,
+    OC_MODE_INTER_MV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
+    OC_MODE_INTER_MV_FOUR
+  },
+  {
+    OC_MODE_INTER_NOMV,OC_MODE_GOLDEN_NOMV,OC_MODE_INTER_MV_LAST,
+    OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_MV,OC_MODE_INTRA,OC_MODE_GOLDEN_MV,
+    OC_MODE_INTER_MV_FOUR
+  },
+  /*Default ordering.*/
+  {
+    OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_INTER_MV,OC_MODE_INTER_MV_LAST,
+    OC_MODE_INTER_MV_LAST2,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
+    OC_MODE_INTER_MV_FOUR
+  }
+};
+
+
+static int oc_sb_run_unpack(oggpack_buffer *_opb){
+  long bits;
+  int ret;
+  /*Coding scheme:
+       Codeword            Run Length
+     0                       1
+     10x                     2-3
+     110x                    4-5
+     1110xx                  6-9
+     11110xxx                10-17
+     111110xxxx              18-33
+     111111xxxxxxxxxxxx      34-4129*/
+  theorapackB_read1(_opb,&bits);
+  if(bits==0)return 1;
+  theorapackB_read(_opb,2,&bits);
+  if((bits&2)==0)return 2+(int)bits;
+  else if((bits&1)==0){
+    theorapackB_read1(_opb,&bits);
+    return 4+(int)bits;
+  }
+  theorapackB_read(_opb,3,&bits);
+  if((bits&4)==0)return 6+(int)bits;
+  else if((bits&2)==0){
+    ret=10+((bits&1)<<2);
+    theorapackB_read(_opb,2,&bits);
+    return ret+(int)bits;
+  }
+  else if((bits&1)==0){
+    theorapackB_read(_opb,4,&bits);
+    return 18+(int)bits;
+  }
+  theorapackB_read(_opb,12,&bits);
+  return 34+(int)bits;
+}
+
+static int oc_block_run_unpack(oggpack_buffer *_opb){
+  long bits;
+  long bits2;
+  /*Coding scheme:
+     Codeword             Run Length
+     0x                      1-2
+     10x                     3-4
+     110x                    5-6
+     1110xx                  7-10
+     11110xx                 11-14
+     11111xxxx               15-30*/
+  theorapackB_read(_opb,2,&bits);
+  if((bits&2)==0)return 1+(int)bits;
+  else if((bits&1)==0){
+    theorapackB_read1(_opb,&bits);
+    return 3+(int)bits;
+  }
+  theorapackB_read(_opb,2,&bits);
+  if((bits&2)==0)return 5+(int)bits;
+  else if((bits&1)==0){
+    theorapackB_read(_opb,2,&bits);
+    return 7+(int)bits;
+  }
+  theorapackB_read(_opb,3,&bits);
+  if((bits&4)==0)return 11+bits;
+  theorapackB_read(_opb,2,&bits2);
+  return 15+((bits&3)<<2)+bits2;
+}
+
+
+
+static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
+ const th_setup_info *_setup){
+  int qti;
+  int pli;
+  int qi;
+  int ret;
+  ret=oc_state_init(&_dec->state,_info);
+  if(ret<0)return ret;
+  oc_huff_trees_copy(_dec->huff_tables,
+   (const oc_huff_node *const *)_setup->huff_tables);
+  for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
+    _dec->state.dequant_tables[qti][pli]=
+     _dec->state.dequant_table_data[qti][pli];
+  }
+  oc_dequant_tables_init(_dec->state.dequant_tables,_dec->pp_dc_scale,
+			 &_setup->qinfo);
+  for(qi=0;qi<64;qi++){
+    int qsum;
+    qsum=0;
+    for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
+      qsum+=_dec->state.dequant_tables[qti][pli][qi][18]+
+       _dec->state.dequant_tables[qti][pli][qi][19]+
+       _dec->state.dequant_tables[qti][pli][qi][26]+
+       _dec->state.dequant_tables[qti][pli][qi][27]<<(pli==0);
+    }
+    _dec->pp_sharp_mod[qi]=-(qsum>>11);
+  }
+  _dec->dct_tokens=(unsigned char **)oc_calloc_2d(64,
+   _dec->state.nfrags,sizeof(_dec->dct_tokens[0][0]));
+  _dec->extra_bits=(ogg_uint16_t **)oc_calloc_2d(64,
+   _dec->state.nfrags,sizeof(_dec->extra_bits[0][0]));
+  memcpy(_dec->state.loop_filter_limits,_setup->qinfo.loop_filter_limits,
+   sizeof(_dec->state.loop_filter_limits));
+  _dec->pp_level=OC_PP_LEVEL_DISABLED;
+  _dec->dc_qis=NULL;
+  _dec->variances=NULL;
+  _dec->pp_frame_data=NULL;
+  _dec->stripe_cb.ctx=NULL;
+  _dec->stripe_cb.stripe_decoded=NULL;
+  return 0;
+}
+
+static void oc_dec_clear(oc_dec_ctx *_dec){
+  _ogg_free(_dec->pp_frame_data);
+  _ogg_free(_dec->variances);
+  _ogg_free(_dec->dc_qis);
+  oc_free_2d(_dec->extra_bits);
+  oc_free_2d(_dec->dct_tokens);
+  oc_huff_trees_clear(_dec->huff_tables);
+  oc_state_clear(&_dec->state);
+}
+
+
+static int oc_dec_frame_header_unpack(oc_dec_ctx *_dec){
+  long val;
+
+  TH_DEBUG("\n>>>> beginning frame %ld\n\n",dframe);
+
+  /*Check to make sure this is a data packet.*/
+  theorapackB_read1(&_dec->opb,&val);
+  TH_DEBUG("frame type = %s, ",val==0?"video":"unknown");
+  if(val!=0)return TH_EBADPACKET;
+  /*Read in the frame type (I or P).*/
+  theorapackB_read1(&_dec->opb,&val);
+  _dec->state.frame_type=(int)val;
+  TH_DEBUG("%s\n",val?"predicted":"key");
+  /*Read in the current qi.*/
+  theorapackB_read(&_dec->opb,6,&val);
+  _dec->state.qis[0]=(int)val;
+  TH_DEBUG("frame quality = { %ld ",val);
+  theorapackB_read1(&_dec->opb,&val);
+  if(!val)_dec->state.nqis=1;
+  else{
+    theorapackB_read(&_dec->opb,6,&val);
+    _dec->state.qis[1]=(int)val;
+    TH_DEBUG("%ld ",val);
+    theorapackB_read1(&_dec->opb,&val);
+    if(!val)_dec->state.nqis=2;
+    else{
+      theorapackB_read(&_dec->opb,6,&val);
+      TH_DEBUG("%ld ",val);
+      _dec->state.qis[2]=(int)val;
+      _dec->state.nqis=3;
+    }
+  }
+  TH_DEBUG("}\n");
+
+  if(_dec->state.frame_type==OC_INTRA_FRAME){
+    /*Keyframes have 3 unused configuration bits, holdovers from VP3 days.
+      Most of the other unused bits in the VP3 headers were eliminated.
+      I don't know why these remain.*/
+    /* I wanted to eliminate wasted bits, but not all config wiggle room --Monty */
+    theorapackB_read(&_dec->opb,3,&val);
+    if(val!=0)return TH_EIMPL;
+  }
+  return 0;
+}
+
+/*Mark all fragments as coded and in OC_MODE_INTRA.
+  This also builds up the coded fragment list (in coded order), and clears the
+   uncoded fragment list.
+  It does not update the coded macro block list, as that is not used when
+   decoding INTRA frames.*/
+static void oc_dec_mark_all_intra(oc_dec_ctx *_dec){
+  oc_sb *sb;
+  oc_sb *sb_end;
+  int    pli;
+  int    ncoded_fragis;
+  int    prev_ncoded_fragis;
+  prev_ncoded_fragis=ncoded_fragis=0;
+  sb=sb_end=_dec->state.sbs;
+  for(pli=0;pli<3;pli++){
+    const oc_fragment_plane *fplane;
+    fplane=_dec->state.fplanes+pli;
+    sb_end+=fplane->nsbs;
+    for(;sb<sb_end;sb++){
+      int quadi;
+      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
+        int bi;
+        for(bi=0;bi<4;bi++){
+          int fragi;
+          fragi=sb->map[quadi][bi];
+          if(fragi>=0){
+            oc_fragment *frag;
+            frag=_dec->state.frags+fragi;
+            frag->coded=1;
+            frag->mbmode=OC_MODE_INTRA;
+            _dec->state.coded_fragis[ncoded_fragis++]=fragi;
+          }
+        }
+      }
+    }
+    _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis;
+    prev_ncoded_fragis=ncoded_fragis;
+    _dec->state.nuncoded_fragis[pli]=0;
+  }
+}
+
+/*Decodes the bit flags for whether or not each super block is partially coded
+   or not.
+  Return: The number of partially coded super blocks.*/
+static int oc_dec_partial_sb_flags_unpack(oc_dec_ctx *_dec){
+  oc_sb *sb;
+  oc_sb *sb_end;
+  long   val;
+  int    flag;
+  int    npartial;
+  int    run_count;
+  theorapackB_read1(&_dec->opb,&val);
+  flag=(int)val;
+
+  sb=_dec->state.sbs;
+  sb_end=sb+_dec->state.nsbs;
+  run_count=npartial=0;
+  while(sb<sb_end){
+    int full_run;
+    run_count=oc_sb_run_unpack(&_dec->opb);
+    full_run=run_count>=4129;
+    do{
+      sb->coded_partially=flag;
+      sb->coded_fully=0;
+      npartial+=flag;
+      sb++;
+    }
+
+    while(--run_count>0&&sb<sb_end);
+    if(full_run&&sb<sb_end){
+      theorapackB_read1(&_dec->opb,&val);
+      flag=(int)val;
+    }
+    else flag=!flag;
+  }
+  /*TODO: run_count should be 0 here.
+    If it's not, we should issue a warning of some kind.*/
+  return npartial;
+}
+
+/*Decodes the bit flags for whether or not each non-partially-coded super
+   block is fully coded or not.
+  This function should only be called if there is at least one
+   non-partially-coded super block.
+  Return: The number of partially coded super blocks.*/
+static void oc_dec_coded_sb_flags_unpack(oc_dec_ctx *_dec){
+  oc_sb *sb;
+  oc_sb *sb_end;
+  long   val;
+  int    flag;
+  int    run_count;
+  sb=_dec->state.sbs;
+  sb_end=sb+_dec->state.nsbs;
+  /*Skip partially coded super blocks.*/
+  for(;sb->coded_partially;sb++);
+  theorapackB_read1(&_dec->opb,&val);
+  flag=(int)val;
+
+  while(sb<sb_end){
+    int full_run;
+    run_count=oc_sb_run_unpack(&_dec->opb);
+    full_run=run_count>=4129;
+    for(;sb<sb_end;sb++){
+      if(sb->coded_partially)continue;
+      if(run_count--<=0)break;
+      sb->coded_fully=flag;
+    }
+    if(full_run&&sb<sb_end){
+      theorapackB_read1(&_dec->opb,&val);
+      flag=(int)val;
+    }
+    else flag=!flag;
+  }
+  /*TODO: run_count should be 0 here.
+    If it's not, we should issue a warning of some kind.*/
+}
+
+static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){
+  oc_sb *sb;
+  oc_sb *sb_end;
+  long   val;
+  int    npartial;
+  int    pli;
+  int    flag;
+  int    run_count;
+  int    ncoded_fragis;
+  int    prev_ncoded_fragis;
+  int    nuncoded_fragis;
+  int    prev_nuncoded_fragis;
+  npartial=oc_dec_partial_sb_flags_unpack(_dec);
+  if(npartial<_dec->state.nsbs)oc_dec_coded_sb_flags_unpack(_dec);
+  if(npartial>0){
+    theorapackB_read1(&_dec->opb,&val);
+    flag=!(int)val;
+  }
+  else flag=0;
+  run_count=0;
+  prev_ncoded_fragis=ncoded_fragis=prev_nuncoded_fragis=nuncoded_fragis=0;
+  sb=sb_end=_dec->state.sbs;
+  for(pli=0;pli<3;pli++){
+    const oc_fragment_plane *fplane;
+    fplane=_dec->state.fplanes+pli;
+    sb_end+=fplane->nsbs;
+    for(;sb<sb_end;sb++){
+      int quadi;
+      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
+        int bi;
+        for(bi=0;bi<4;bi++){
+          int fragi;
+          fragi=sb->map[quadi][bi];
+          if(fragi>=0){
+            oc_fragment *frag;
+            frag=_dec->state.frags+fragi;
+            if(sb->coded_fully)frag->coded=1;
+            else if(!sb->coded_partially)frag->coded=0;
+            else{
+              if(run_count<=0){
+                run_count=oc_block_run_unpack(&_dec->opb);
+                flag=!flag;
+              }
+              run_count--;
+              frag->coded=flag;
+            }
+            if(frag->coded)_dec->state.coded_fragis[ncoded_fragis++]=fragi;
+            else *(_dec->state.uncoded_fragis-++nuncoded_fragis)=fragi;
+          }
+        }
+      }
+    }
+    _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis;
+    prev_ncoded_fragis=ncoded_fragis;
+    _dec->state.nuncoded_fragis[pli]=nuncoded_fragis-prev_nuncoded_fragis;
+    prev_nuncoded_fragis=nuncoded_fragis;
+  }
+  /*TODO: run_count should be 0 here.
+    If it's not, we should issue a warning of some kind.*/
+
+
+#ifdef _TH_DEBUG_
+  // assuming 4:2:0 right now; THIS IS WRONG but only an issue if dumping debug info
+  TH_DEBUG("predicted (partially coded frame)\n");
+  TH_DEBUG("superblock coded flags = {");
+  int x,y,i;
+  int w = _dec->state.info.frame_width;
+  int h = _dec->state.info.frame_height;
+
+  i=0;
+  for(y=0;y< (h+31)/32;y++){
+    TH_DEBUG("\n   ");
+    for(x=0;x< (w+31)/32;x++,i++)
+      TH_DEBUG("%x", (_dec->state.sbs[i].coded_partially!=0)|
+	       (_dec->state.sbs[i].coded_fully));
+  }
+
+  TH_DEBUG("\n   ");
+  for(y=0;y< (h+63)/64;y++){
+    TH_DEBUG("\n   ");
+    for(x=0;x< (w+63)/64;x++,i++)
+      TH_DEBUG("%x", (_dec->state.sbs[i].coded_partially!=0)|
+	       (_dec->state.sbs[i].coded_fully));
+  }
+  TH_DEBUG("\n   ");
+  for(y=0;y< (h+63)/64;y++){
+    TH_DEBUG("\n   ");
+    for(x=0;x< (w+63)/64;x++,i++)
+      TH_DEBUG("%x", (_dec->state.sbs[i].coded_partially!=0)|
+	       (_dec->state.sbs[i].coded_fully));
+  }
+  TH_DEBUG("\n}\n");
+
+  if(i!=_dec->state.nsbs)
+    TH_DEBUG("WARNING!  superblock count, raster %d != flat %d\n",
+	     i,_dec->state.nsbs);
+  
+  TH_DEBUG("block coded flags = {");
+
+  i=0;
+  for(y=0;y< (h+7)/8;y++){
+    TH_DEBUG("\n   ");
+    for(x=0;x< (w+7)/8;x++,i++)
+      TH_DEBUG("%x", (_dec->state.frags[i].coded!=0));
+  }
+  TH_DEBUG("\n   ");
+  for(y=0;y< (h+15)/16;y++){
+    TH_DEBUG("\n   ");
+    for(x=0;x< (w+15)/16;x++,i++)
+      TH_DEBUG("%x", (_dec->state.frags[i].coded!=0));
+  }
+  TH_DEBUG("\n   ");
+  for(y=0;y< (h+15)/16;y++){
+    TH_DEBUG("\n   ");
+    for(x=0;x< (w+15)/16;x++,i++)
+      TH_DEBUG("%x", (_dec->state.frags[i].coded!=0));
+  }
+  TH_DEBUG("\n}\n");
+  
+  if(i!=_dec->state.nfrags)
+    TH_DEBUG("WARNING!  block count, raster %d != flat %d\n",
+	     i,_dec->state.nfrags);
+#endif	      
+
+}
+
+
+
+typedef int (*oc_mode_unpack_func)(oggpack_buffer *_opb);
+
+static int oc_vlc_mode_unpack(oggpack_buffer *_opb){
+  long val;
+  int  i;
+  for(i=0;i<7;i++){
+    theorapackB_read1(_opb,&val);
+    if(!val)break;
+  }
+  return i;
+}
+
+static int oc_clc_mode_unpack(oggpack_buffer *_opb){
+  long val;
+  theorapackB_read(_opb,3,&val);
+  return (int)val;
+}
+
+/*Unpacks the list of macro block modes for INTER frames.*/
+static void oc_dec_mb_modes_unpack(oc_dec_ctx *_dec){
+  oc_mode_unpack_func  mode_unpack;
+  oc_mb               *mb;
+  oc_mb               *mb_end;
+  const int           *alphabet;
+  long                 val,j;
+  int                  scheme0_alphabet[8];
+  int                  mode_scheme;
+  theorapackB_read(&_dec->opb,3,&val);
+  mode_scheme=(int)val;
+  TH_DEBUG("mode encode scheme = %d\n",(int)val);
+
+  if(mode_scheme==0){
+    int mi;
+    /*Just in case, initialize the modes to something.
+      If the bitstream doesn't contain each index exactly once, it's likely
+       corrupt and the rest of the packet is garbage anyway, but this way we
+       won't crash, and we'll decode SOMETHING.*/
+    TH_DEBUG("mode scheme list = { ");
+    /*LOOP VECTORIZES.*/
+    for(mi=0;mi<OC_NMODES;mi++)scheme0_alphabet[mi]=OC_MODE_INTER_NOMV;
+    for(mi=0;mi<OC_NMODES;mi++){
+      theorapackB_read(&_dec->opb,3,&val);
+      scheme0_alphabet[val]=OC_MODE_ALPHABETS[6][mi];
+      TH_DEBUG("%d ",(int)val);
+    }
+    TH_DEBUG("}\n");
+    alphabet=scheme0_alphabet;
+  }else 
+    alphabet=OC_MODE_ALPHABETS[mode_scheme-1];
+  if(mode_scheme==7)
+    mode_unpack=oc_clc_mode_unpack;
+  else 
+    mode_unpack=oc_vlc_mode_unpack;
+  mb=_dec->state.mbs;
+  mb_end=mb+_dec->state.nmbs;
+
+  TH_DEBUG("mode list = { ");
+  for(j=0;mb<mb_end;mb++){
+    if(mb->mode!=OC_MODE_INVALID){
+      int bi;
+      for(bi=0;bi<4;bi++){
+	int fragi;
+	fragi=mb->map[0][bi];
+	if(fragi>=0&&_dec->state.frags[fragi].coded)break;
+      }
+      if(bi<4){
+	mb->mode=alphabet[(*mode_unpack)(&_dec->opb)];
+	
+#ifdef _TH_DEBUG_
+	if((j&0x1f)==0)
+	  TH_DEBUG("\n   ");
+	TH_DEBUG("%d ",mb->mode);
+	j++;
+#endif
+
+      }else 
+	mb->mode=OC_MODE_INTER_NOMV;
+    }
+  }
+  TH_DEBUG("\n}\n");
+}
+
+
+
+typedef int (*oc_mv_comp_unpack_func)(oggpack_buffer *_opb);
+
+static int oc_vlc_mv_comp_unpack(oggpack_buffer *_opb){
+  long bits;
+  int  mvsigned[2];
+  theorapackB_read(_opb,3,&bits);
+  switch(bits){
+    case  0:return 0;
+    case  1:return 1;
+    case  2:return -1;
+    case  3:
+    case  4:{
+      mvsigned[0]=(int)(bits-1);
+      theorapackB_read1(_opb,&bits);
+    }break;
+    /*case  5:
+    case  6:
+    case  7:*/
+    default:{
+      mvsigned[0]=1<<bits-3;
+      theorapackB_read(_opb,bits-2,&bits);
+      mvsigned[0]+=(int)(bits>>1);
+      bits&=1;
+    }break;
+  }
+  mvsigned[1]=-mvsigned[0];
+  return mvsigned[bits];
+}
+
+static int oc_clc_mv_comp_unpack(oggpack_buffer *_opb){
+  long bits;
+  int  mvsigned[2];
+  theorapackB_read(_opb,6,&bits);
+  mvsigned[0]=bits>>1;
+  mvsigned[1]=-mvsigned[0];
+  return mvsigned[bits&1];
+}
+
+/*Unpacks the list of motion vectors for INTER frames, and propagtes the macro
+   block modes and motion vectors to the individual fragments.*/
+static void oc_dec_mv_unpack_and_frag_modes_fill(oc_dec_ctx *_dec){
+  oc_set_chroma_mvs_func  set_chroma_mvs;
+  oc_mv_comp_unpack_func  mv_comp_unpack;
+  oc_mb                  *mb;
+  oc_mb                  *mb_end;
+  const int              *map_idxs;
+  long                    val;
+  int                     map_nidxs;
+#ifdef _TH_DEBUG_
+  int                     j=0;
+#endif
+  oc_mv                   last_mv[2];
+  oc_mv                   cbmvs[4];
+  set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt];
+  theorapackB_read1(&_dec->opb,&val);
+  TH_DEBUG("motion vector table = %d\n",(int)val);
+  mv_comp_unpack=val?oc_clc_mv_comp_unpack:oc_vlc_mv_comp_unpack;
+  map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt];
+  map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt];
+  memset(last_mv,0,sizeof(last_mv));
+  mb=_dec->state.mbs;
+  mb_end=mb+_dec->state.nmbs;
+
+  TH_DEBUG("motion vectors = {");
+
+  for(;mb<mb_end;mb++)if(mb->mode!=OC_MODE_INVALID){
+    oc_fragment *frag;
+    oc_mv        mbmv;
+    int          coded[13];
+    int          codedi;
+    int          ncoded;
+    int          mapi;
+    int          mapii;
+    int          fragi;
+    int          mb_mode;
+    /*Search for at least one coded fragment.*/
+    ncoded=mapii=0;
+    do{
+      mapi=map_idxs[mapii];
+      fragi=mb->map[mapi>>2][mapi&3];
+      if(fragi>=0&&_dec->state.frags[fragi].coded)coded[ncoded++]=mapi;
+    }
+    while(++mapii<map_nidxs);
+    if(ncoded<=0)continue;
+    mb_mode=mb->mode;
+    switch(mb_mode){
+    case OC_MODE_INTER_MV_FOUR:
+      {
+	oc_mv       lbmvs[4];
+	int         bi;
+	/*Mark the tail of the list, so we don't accidentally go past it.*/
+	coded[ncoded]=-1;
+	for(bi=codedi=0;bi<4;bi++){
+	  if(coded[codedi]==bi){
+	    codedi++;
+	    frag=_dec->state.frags+mb->map[0][bi];
+	    frag->mbmode=mb_mode;
+	    frag->mv[0]=lbmvs[bi][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+	    frag->mv[1]=lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+
+#ifdef _TH_DEBUG_
+	    if((j&0x7)==0)
+	      TH_DEBUG("\n   ");
+	    TH_DEBUG("%+03d,%+03d ",frag->mv[0],frag->mv[1]);
+	    j++;
+#endif
+
+	  }
+	  else lbmvs[bi][0]=lbmvs[bi][1]=0;
+	}
+	if(codedi>0){
+	  last_mv[1][0]=last_mv[0][0];
+	  last_mv[1][1]=last_mv[0][1];
+	  last_mv[0][0]=lbmvs[coded[codedi-1]][0];
+	  last_mv[0][1]=lbmvs[coded[codedi-1]][1];
+	}
+	if(codedi<ncoded){
+	  (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
+	  for(;codedi<ncoded;codedi++){
+	    mapi=coded[codedi];
+	    bi=mapi&3;
+	    frag=_dec->state.frags+mb->map[mapi>>2][bi];
+	    frag->mbmode=mb_mode;
+	    frag->mv[0]=cbmvs[bi][0];
+	    frag->mv[1]=cbmvs[bi][1];
+	  }
+	}
+      }
+      break;
+    case OC_MODE_INTER_MV:
+      {
+	last_mv[1][0]=last_mv[0][0];
+	last_mv[1][1]=last_mv[0][1];
+	mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+	mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+
+#ifdef _TH_DEBUG_
+	if((j&0x7)==0)
+	  TH_DEBUG("\n   ");
+	TH_DEBUG("%+03d,%+03d ",mbmv[0],mbmv[1]);
+	j++;
+#endif
+
+      }
+      break;
+    case OC_MODE_INTER_MV_LAST:
+      {
+        mbmv[0]=last_mv[0][0];
+        mbmv[1]=last_mv[0][1];
+      }
+      break;
+    case OC_MODE_INTER_MV_LAST2:
+      {
+        mbmv[0]=last_mv[1][0];
+        mbmv[1]=last_mv[1][1];
+        last_mv[1][0]=last_mv[0][0];
+        last_mv[1][1]=last_mv[0][1];
+        last_mv[0][0]=mbmv[0];
+        last_mv[0][1]=mbmv[1];
+      }
+      break;
+    case OC_MODE_GOLDEN_MV:
+      {
+        mbmv[0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+        mbmv[1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+
+#ifdef _TH_DEBUG_
+	if((j&0x7)==0)
+	  TH_DEBUG("\n   ");
+	TH_DEBUG("%+03d,%+03d ",mbmv[0],mbmv[1]);
+	j++;
+#endif
+
+      }
+      break;
+    default:
+      mbmv[0]=mbmv[1]=0;
+      break;
+    }
+    /*4MV mode fills in the fragments itself.
+      For all other modes we can use this common code.*/
+    if(mb_mode!=OC_MODE_INTER_MV_FOUR){
+      for(codedi=0;codedi<ncoded;codedi++){
+        mapi=coded[codedi];
+        fragi=mb->map[mapi>>2][mapi&3];
+        frag=_dec->state.frags+fragi;
+        frag->mbmode=mb_mode;
+        frag->mv[0]=mbmv[0];
+        frag->mv[1]=mbmv[1];
+      }
+    }
+  }
+
+  TH_DEBUG("\n}\n");
+
+}
+
+static void oc_dec_block_qis_unpack(oc_dec_ctx *_dec){
+  oc_fragment *frag;
+  int         *coded_fragi;
+  int         *coded_fragi_end;
+  int          ncoded_fragis;
+  ncoded_fragis=_dec->state.ncoded_fragis[0]+
+   _dec->state.ncoded_fragis[1]+_dec->state.ncoded_fragis[2];
+  if(ncoded_fragis<=0)return;
+  coded_fragi=_dec->state.coded_fragis;
+  coded_fragi_end=coded_fragi+ncoded_fragis;
+  if(_dec->state.nqis==1){
+    /*If this frame has only a single qi value, then just set it in all coded
+       fragments.*/
+    while(coded_fragi<coded_fragi_end){
+      _dec->state.frags[*coded_fragi++].qi=_dec->state.qis[0];
+    }
+  }
+  else{
+    long val;
+    int  flag;
+    int  nqi0;
+    int  run_count;
+    /*Otherwise, we decode a qi index for each fragment, using two passes of
+      the same binary RLE scheme used for super-block coded bits.
+     The first pass marks each fragment as having a qii of 0 or greater than
+      0, and the second pass (if necessary), distinguishes between a qii of
+      1 and 2.
+     At first we just store the qii in the fragment.
+     After all the qii's are decoded, we make a final pass to replace them
+      with the corresponding qi's for this frame.*/
+    theorapackB_read1(&_dec->opb,&val);
+    flag=(int)val;
+    run_count=nqi0=0;
+    while(coded_fragi<coded_fragi_end){
+      int full_run;
+      run_count=oc_sb_run_unpack(&_dec->opb);
+      full_run=run_count>=4129;
+      do{
+        _dec->state.frags[*coded_fragi++].qi=flag;
+        nqi0+=!flag;
+      }
+      while(--run_count>0&&coded_fragi<coded_fragi_end);
+      if(full_run&&coded_fragi<coded_fragi_end){
+        theorapackB_read1(&_dec->opb,&val);
+        flag=(int)val;
+      }
+      else flag=!flag;
+    }
+    /*TODO: run_count should be 0 here.
+      If it's not, we should issue a warning of some kind.*/
+    /*If we have 3 different qi's for this frame, and there was at least one
+       fragment with a non-zero qi, make the second pass.*/
+    if(_dec->state.nqis==3&&nqi0<ncoded_fragis){
+      /*Skip qii==0 fragments.*/
+      for(coded_fragi=_dec->state.coded_fragis;
+       _dec->state.frags[*coded_fragi].qi==0;coded_fragi++);
+      theorapackB_read1(&_dec->opb,&val);
+      flag=(int)val;
+      while(coded_fragi<coded_fragi_end){
+        int full_run;
+        run_count=oc_sb_run_unpack(&_dec->opb);
+        full_run=run_count>=4129;
+        for(;coded_fragi<coded_fragi_end;coded_fragi++){
+          oc_fragment *frag;
+          frag=_dec->state.frags+*coded_fragi;
+          if(frag->qi==0)continue;
+          if(run_count--<=0)break;
+          frag->qi+=flag;
+        }
+        if(full_run&&coded_fragi<coded_fragi_end){
+          theorapackB_read1(&_dec->opb,&val);
+          flag=(int)val;
+        }
+        else flag=!flag;
+      }
+      /*TODO: run_count should be 0 here.
+        If it's not, we should issue a warning of some kind.*/
+    }
+    /*Finally, translate qii's to qi's.*/
+    for(coded_fragi=_dec->state.coded_fragis;coded_fragi<coded_fragi_end;
+     coded_fragi++){
+      frag=_dec->state.frags+*coded_fragi;
+      frag->qi=_dec->state.qis[frag->qi];
+    }
+  }
+}
+
+
+
+/*Returns the decoded value of the given token.
+  It CANNOT be called for any of the EOB tokens.
+  _token:      The token value to skip.
+  _extra_bits: The extra bits attached to this token.
+  Return: The decoded coefficient value.*/
+typedef int (*oc_token_dec1val_func)(int _token,int _extra_bits);
+
+/*Handles zero run tokens.*/
+static int oc_token_dec1val_zrl(void){
+  return 0;
+}
+
+/*Handles 1, -1, 2 and -2 tokens.*/
+static int oc_token_dec1val_const(int _token){
+  static const int CONST_VALS[4]={1,-1,2,-2};
+  return CONST_VALS[_token-OC_NDCT_ZRL_TOKEN_MAX];
+}
+
+/*Handles DCT value tokens category 2.*/
+static int oc_token_dec1val_cat2(int _token,int _extra_bits){
+  int valsigned[2];
+  valsigned[0]=_token-OC_DCT_VAL_CAT2+3;
+  valsigned[1]=-valsigned[0];
+  return valsigned[_extra_bits];
+}
+
+/*Handles DCT value tokens categories 3 through 8.*/
+static int oc_token_dec1val_cati(int _token,int _extra_bits){
+  static const int VAL_CAT_OFFS[6]={
+    OC_NDCT_VAL_CAT2_SIZE+3,
+    OC_NDCT_VAL_CAT2_SIZE+5,
+    OC_NDCT_VAL_CAT2_SIZE+9,
+    OC_NDCT_VAL_CAT2_SIZE+17,
+    OC_NDCT_VAL_CAT2_SIZE+33,
+    OC_NDCT_VAL_CAT2_SIZE+65
+  };
+  static const int VAL_CAT_MASKS[6]={
+    0x001,0x003,0x007,0x00F,0x01F,0x1FF
+  };
+  static const int VAL_CAT_SHIFTS[6]={1,2,3,4,5,9};
+  int valsigned[2];
+  int cati;
+  cati=_token-OC_NDCT_VAL_CAT2_MAX;
+  valsigned[0]=VAL_CAT_OFFS[cati]+(_extra_bits&VAL_CAT_MASKS[cati]);
+  valsigned[1]=-valsigned[0];
+  return valsigned[_extra_bits>>VAL_CAT_SHIFTS[cati]&1];
+}
+
+/*A jump table for compute the first coefficient value the given token value
+   represents.*/
+static const oc_token_dec1val_func OC_TOKEN_DEC1VAL_TABLE[TH_NDCT_TOKENS-
+ OC_NDCT_EOB_TOKEN_MAX]={
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_const,
+  (oc_token_dec1val_func)oc_token_dec1val_const,
+  (oc_token_dec1val_func)oc_token_dec1val_const,
+  (oc_token_dec1val_func)oc_token_dec1val_const,
+  oc_token_dec1val_cat2,
+  oc_token_dec1val_cat2,
+  oc_token_dec1val_cat2,
+  oc_token_dec1val_cat2,
+  oc_token_dec1val_cati,
+  oc_token_dec1val_cati,
+  oc_token_dec1val_cati,
+  oc_token_dec1val_cati,
+  oc_token_dec1val_cati,
+  oc_token_dec1val_cati,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl,
+  (oc_token_dec1val_func)oc_token_dec1val_zrl
+};
+
+/*Returns the decoded value of the given token.
+  It CANNOT be called for any of the EOB tokens.
+  _token:      The token value to skip.
+  _extra_bits: The extra bits attached to this token.
+  Return: The decoded coefficient value.*/
+static int oc_dct_token_dec1val(int _token,int _extra_bits){
+  return (*OC_TOKEN_DEC1VAL_TABLE[_token-OC_NDCT_EOB_TOKEN_MAX])(_token,
+   _extra_bits);
+}
+
+/*Unpacks the DC coefficient tokens.
+  Unlike when unpacking the AC coefficient tokens, we actually need to decode
+   the DC coefficient values now so that we can do DC prediction.
+  _huff_idx:   The index of the Huffman table to use for each color plane.
+  _ntoks_left: The number of tokens left to be decoded in each color plane for
+                each coefficient.
+               This is updated as EOB tokens and zero run tokens are decoded.
+  Return: The length of any outstanding EOB run.*/
+static int oc_dec_dc_coeff_unpack(oc_dec_ctx *_dec,int _huff_idxs[3],
+ int _ntoks_left[3][64]){
+  long  val;
+  int  *coded_fragi;
+  int  *coded_fragi_end;
+  int   run_counts[64];
+  int   cfi;
+  int   eobi;
+  int   eobs;
+  int   ti;
+  int   ebi;
+  int   pli;
+  int   rli;
+  eobs=0;
+  ti=ebi=0;
+  coded_fragi_end=coded_fragi=_dec->state.coded_fragis;
+  for(pli=0;pli<3;pli++){
+    coded_fragi_end+=_dec->state.ncoded_fragis[pli];
+    memset(run_counts,0,sizeof(run_counts));
+    _dec->eob_runs[pli][0]=eobs;
+    /*Continue any previous EOB run, if there was one.*/
+    for(eobi=eobs;eobi-->0&&coded_fragi<coded_fragi_end;){
+      _dec->state.frags[*coded_fragi++].dc=0;
+    }
+    cfi=0;
+    while(eobs<_ntoks_left[pli][0]-cfi){
+      int token;
+      int neb;
+      int eb;
+      int skip;
+      cfi+=eobs;
+      run_counts[63]+=eobs;
+      token=oc_huff_token_decode(&_dec->opb,
+       _dec->huff_tables[_huff_idxs[pli]]);
+      _dec->dct_tokens[0][ti++]=(unsigned char)token;
+      neb=OC_DCT_TOKEN_EXTRA_BITS[token];
+      if(neb){
+        theorapackB_read(&_dec->opb,neb,&val);
+        eb=(int)val;
+        _dec->extra_bits[0][ebi++]=(ogg_uint16_t)eb;
+      }
+      else eb=0;
+      skip=oc_dct_token_skip(token,eb);
+      if(skip<0){
+        eobs=eobi=-skip;
+        while(eobi-->0&&coded_fragi<coded_fragi_end){
+          _dec->state.frags[*coded_fragi++].dc=0;
+        }
+      }
+      else{
+        run_counts[skip-1]++;
+        cfi++;
+        eobs=0;
+        _dec->state.frags[*coded_fragi++].dc=oc_dct_token_dec1val(token,eb);
+      }
+    }
+    _dec->ti0[pli][0]=ti;
+    _dec->ebi0[pli][0]=ebi;
+    /*Set the EOB count to the portion of the last EOB run which extends past
+       this coefficient.*/
+    eobs=eobs+cfi-_ntoks_left[pli][0];
+    /*Add the portion of the last EOB which was included in this coefficient to
+       to the longest run length.*/
+    run_counts[63]+=_ntoks_left[pli][0]-cfi;
+    /*And convert the run_counts array to a moment table.*/
+    for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1];
+    /*Finally, subtract off the number of coefficients that have been
+       accounted for by runs started in this coefficient.*/
+    for(rli=64;rli-->0;)_ntoks_left[pli][rli]-=run_counts[rli];
+  }
+  return eobs;
+}
+
+/*Unpacks the AC coefficient tokens.
+  This can completely discard coefficient values while unpacking, and so is
+   somewhat simpler than unpacking the DC coefficient tokens.
+  _huff_idx:   The index of the Huffman table to use for each color plane.
+  _ntoks_left: The number of tokens left to be decoded in each color plane for
+                each coefficient.
+               This is updated as EOB tokens and zero run tokens are decoded.
+  _eobs:       The length of any outstanding EOB run from previous
+                coefficients.
+  Return: The length of any outstanding EOB run.*/
+static int oc_dec_ac_coeff_unpack(oc_dec_ctx *_dec,int _zzi,int _huff_idxs[3],
+ int _ntoks_left[3][64],int _eobs){
+  long val;
+  int  run_counts[64];
+  int  cfi;
+  int  ti;
+  int  ebi;
+  int  pli;
+  int  rli;
+  ti=ebi=0;
+  for(pli=0;pli<3;pli++){
+    memset(run_counts,0,sizeof(run_counts));
+    _dec->eob_runs[pli][_zzi]=_eobs;
+    cfi=0;
+    while(_eobs<_ntoks_left[pli][_zzi]-cfi){
+      int token;
+      int neb;
+      int eb;
+      int skip;
+      cfi+=_eobs;
+      run_counts[63]+=_eobs;
+      token=oc_huff_token_decode(&_dec->opb,
+       _dec->huff_tables[_huff_idxs[pli]]);
+      _dec->dct_tokens[_zzi][ti++]=(unsigned char)token;
+      neb=OC_DCT_TOKEN_EXTRA_BITS[token];
+      if(neb){
+        theorapackB_read(&_dec->opb,neb,&val);
+        eb=(int)val;
+        _dec->extra_bits[_zzi][ebi++]=(ogg_uint16_t)eb;
+      }
+      else eb=0;
+      skip=oc_dct_token_skip(token,eb);
+      if(skip<0)_eobs=-skip;
+      else{
+        run_counts[skip-1]++;
+        cfi++;
+        _eobs=0;
+      }
+    }
+    _dec->ti0[pli][_zzi]=ti;
+    _dec->ebi0[pli][_zzi]=ebi;
+    /*Set the EOB count to the portion of the last EOB run which extends past
+       this coefficient.*/
+    _eobs=_eobs+cfi-_ntoks_left[pli][_zzi];
+    /*Add the portion of the last EOB which was included in this coefficient to
+       to the longest run length.*/
+    run_counts[63]+=_ntoks_left[pli][_zzi]-cfi;
+    /*And convert the run_counts array to a moment table.*/
+    for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1];
+    /*Finally, subtract off the number of coefficients that have been
+       accounted for by runs started in this coefficient.*/
+    for(rli=64-_zzi;rli-->0;)_ntoks_left[pli][_zzi+rli]-=run_counts[rli];
+  }
+  return _eobs;
+}
+
+/*Tokens describing the DCT coefficients that belong to each fragment are
+   stored in the bitstream grouped by coefficient, not by fragment.
+
+  This means that we either decode all the tokens in order, building up a
+   separate coefficient list for each fragment as we go, and then go back and
+   do the iDCT on each fragment, or we have to create separate lists of tokens
+   for each coefficient, so that we can pull the next token required off the
+   head of the appropriate list when decoding a specific fragment.
+
+  The former was VP3's choice, and it meant 2*w*h extra storage for all the
+   decoded coefficient values.
+
+  We take the second option, which lets us store just one or three bytes per
+   token (generally far fewer than the number of coefficients, due to EOB
+   tokens and zero runs), and which requires us to only maintain a counter for
+   each of the 64 coefficients, instead of a counter for every fragment to
+   determine where the next token goes.
+
+  Actually, we use 3 counters per coefficient, one for each color plane, so we
+   can decode all color planes simultaneously.
+
+  This lets color conversion, etc., be done as soon as a full MCU (one or
+   two super block rows) is decoded, while the image data is still in cache.*/
+
+static void oc_dec_residual_tokens_unpack(oc_dec_ctx *_dec){
+  static const int OC_HUFF_LIST_MAX[5]={1,6,15,28,64};
+  long val;
+  int  ntoks_left[3][64];
+  int  huff_idxs[3];
+  int  pli;
+  int  zzi;
+  int  hgi;
+  int  huffi_y;
+  int  huffi_c;
+  int  eobs;
+  for(pli=0;pli<3;pli++)for(zzi=0;zzi<64;zzi++){
+    ntoks_left[pli][zzi]=_dec->state.ncoded_fragis[pli];
+  }
+  theorapackB_read(&_dec->opb,4,&val);
+  huffi_y=(int)val;
+  theorapackB_read(&_dec->opb,4,&val);
+  huffi_c=(int)val;
+  huff_idxs[0]=huffi_y;
+  huff_idxs[1]=huff_idxs[2]=huffi_c;
+  _dec->eob_runs[0][0]=0;
+  eobs=oc_dec_dc_coeff_unpack(_dec,huff_idxs,ntoks_left);
+  theorapackB_read(&_dec->opb,4,&val);
+  huffi_y=(int)val;
+  theorapackB_read(&_dec->opb,4,&val);
+  huffi_c=(int)val;
+  zzi=1;
+  for(hgi=1;hgi<5;hgi++){
+    huff_idxs[0]=huffi_y+(hgi<<4);
+    huff_idxs[1]=huff_idxs[2]=huffi_c+(hgi<<4);
+    for(;zzi<OC_HUFF_LIST_MAX[hgi];zzi++){
+      eobs=oc_dec_ac_coeff_unpack(_dec,zzi,huff_idxs,ntoks_left,eobs);
+    }
+  }
+  /*TODO: eobs should be exactly zero, or 4096 or greater.
+    The second case occurs when an EOB run of size zero is encountered, which
+     gets treated as an infinite EOB run (where infinity is INT_MAX).
+    If neither of these conditions holds, then a warning should be issued.*/
+}
+
+
+
+/*Expands a single token into the given coefficient list.
+  This fills in the zeros for zero runs as well as coefficient values, and
+   updates the index of the current coefficient.
+  It CANNOT be called for any of the EOB tokens.
+  _token:      The token value to expand.
+  _extra_bits: The extra bits associated with the token.
+  _dct_coeffs: The current list of coefficients, in zig-zag order.
+  _zzi:        A pointer to the zig-zag index of the next coefficient to write
+                to.
+               This is updated before the function returns.*/
+typedef void (*oc_token_expand_func)(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi);
+
+/*Expands a zero run token.*/
+static void oc_token_expand_zrl(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi){
+  int zzi;
+  zzi=*_zzi;
+  do _dct_coeffs[zzi++]=0;
+  while(_extra_bits-->0);
+  *_zzi=zzi;
+}
+
+/*Expands a constant, single-value token.*/
+static void oc_token_expand_const(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi){
+  _dct_coeffs[(*_zzi)++]=(ogg_int16_t)oc_token_dec1val_const(_token);
+}
+
+/*Expands category 2 single-valued tokens.*/
+static void oc_token_expand_cat2(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi){
+  _dct_coeffs[(*_zzi)++]=
+   (ogg_int16_t)oc_token_dec1val_cat2(_token,_extra_bits);
+}
+
+/*Expands category 3 through 8 single-valued tokens.*/
+static void oc_token_expand_cati(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi){
+  _dct_coeffs[(*_zzi)++]=
+   (ogg_int16_t)oc_token_dec1val_cati(_token,_extra_bits);
+}
+
+/*Expands a category 1a zero run/value combo token.*/
+static void oc_token_expand_run_cat1a(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi){
+  int zzi;
+  int rl;
+  zzi=*_zzi;
+  /*LOOP VECTORIZES.*/
+  for(rl=_token-OC_DCT_RUN_CAT1A+1;rl-->0;)_dct_coeffs[zzi++]=0;
+  _dct_coeffs[zzi++]=(ogg_int16_t)(1-(_extra_bits<<1));
+  *_zzi=zzi;
+}
+
+/*Expands all other zero run/value combo tokens.*/
+static void oc_token_expand_run(int _token,int _extra_bits,
+ ogg_int16_t _dct_coeffs[128],int *_zzi){
+  static const int NZEROS_ADJUST[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    6,10,1,2
+  };
+  static const int NZEROS_MASK[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    3,7,0,1
+  };
+  static const int VALUE_SHIFT[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    0,0,0,1
+  };
+  static const int VALUE_MASK[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    0,0,1,1
+  };
+  static const int VALUE_ADJUST[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    1,1,2,2
+  };
+  static const int SIGN_SHIFT[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    2,3,1,2
+  };
+  int valsigned[2];
+  int zzi;
+  int rl;
+  _token-=OC_DCT_RUN_CAT1B;
+  rl=(_extra_bits&NZEROS_MASK[_token])+NZEROS_ADJUST[_token];
+  zzi=*_zzi;
+  /*LOOP VECTORIZES.*/
+  while(rl-->0)_dct_coeffs[zzi++]=0;
+  valsigned[0]=VALUE_ADJUST[_token]+
+   (_extra_bits>>VALUE_SHIFT[_token]&VALUE_MASK[_token]);
+  valsigned[1]=-valsigned[0];
+  _dct_coeffs[zzi++]=(ogg_int16_t)valsigned[
+   _extra_bits>>SIGN_SHIFT[_token]];
+  *_zzi=zzi;
+}
+
+/*A jump table for expanding token values into coefficient values.
+  This reduces all the conditional branches, etc., needed to parse these token
+   values down to one indirect jump.*/
+static const oc_token_expand_func OC_TOKEN_EXPAND_TABLE[TH_NDCT_TOKENS-
+ OC_NDCT_EOB_TOKEN_MAX]={
+  oc_token_expand_zrl,
+  oc_token_expand_zrl,
+  oc_token_expand_const,
+  oc_token_expand_const,
+  oc_token_expand_const,
+  oc_token_expand_const,
+  oc_token_expand_cat2,
+  oc_token_expand_cat2,
+  oc_token_expand_cat2,
+  oc_token_expand_cat2,
+  oc_token_expand_cati,
+  oc_token_expand_cati,
+  oc_token_expand_cati,
+  oc_token_expand_cati,
+  oc_token_expand_cati,
+  oc_token_expand_cati,
+  oc_token_expand_run_cat1a,
+  oc_token_expand_run_cat1a,
+  oc_token_expand_run_cat1a,
+  oc_token_expand_run_cat1a,
+  oc_token_expand_run_cat1a,
+  oc_token_expand_run,
+  oc_token_expand_run,
+  oc_token_expand_run,
+  oc_token_expand_run
+};
+
+/*Expands a single token into the given coefficient list.
+  This fills in the zeros for zero runs as well as coefficient values, and
+   updates the index of the current coefficient.
+  It CANNOT be called for any of the EOB tokens.
+  _token:      The token value to expand.
+  _extra_bits: The extra bits associated with the token.
+  _dct_coeffs: The current list of coefficients, in zig-zag order.
+  _zzi:        A pointer to the zig-zag index of the next coefficient to write
+                to.
+               This is updated before the function returns.*/
+static void oc_dct_token_expand(int _token,int _extra_bits,
+ ogg_int16_t *_dct_coeffs,int *_zzi){
+  (*OC_TOKEN_EXPAND_TABLE[_token-OC_NDCT_EOB_TOKEN_MAX])(_token,
+   _extra_bits,_dct_coeffs,_zzi);
+}
+
+
+
+static int oc_dec_postprocess_init(oc_dec_ctx *_dec){
+  /*pp_level 0: disabled; free any memory used and return*/
+  if(_dec->pp_level<=OC_PP_LEVEL_DISABLED){
+    if(_dec->dc_qis!=NULL){
+      _ogg_free(_dec->dc_qis);
+      _dec->dc_qis=NULL;
+      _ogg_free(_dec->variances);
+      _dec->variances=NULL;
+      _ogg_free(_dec->pp_frame_data);
+      _dec->pp_frame_data=NULL;
+    }
+    return 1;
+  }
+  if(_dec->dc_qis==NULL){
+    /*If we haven't been tracking DC quantization indices, there's no point in
+       starting now.*/
+    if(_dec->state.frame_type!=OC_INTRA_FRAME)return 1;
+    _dec->dc_qis=(unsigned char *)_ogg_malloc(
+     _dec->state.nfrags*sizeof(_dec->dc_qis[0]));
+    memset(_dec->dc_qis,_dec->state.qis[0],_dec->state.nfrags);
+  }
+  else{
+    int           *coded_fragi;
+    int           *coded_fragi_end;
+    unsigned char  qi0;
+    /*Update the DC quantization index of each coded block.*/
+    qi0=(unsigned char)_dec->state.qis[0];
+    coded_fragi_end=_dec->state.coded_fragis+_dec->state.ncoded_fragis[0]+
+     _dec->state.ncoded_fragis[1]+_dec->state.ncoded_fragis[2];
+    for(coded_fragi=_dec->state.coded_fragis;coded_fragi<coded_fragi_end;
+     coded_fragi++){
+      _dec->dc_qis[*coded_fragi]=qi0;
+    }
+  }
+  /*pp_level 1: Stop after updating DC quantization indices.*/
+  if(_dec->pp_level<=OC_PP_LEVEL_TRACKDCQI){
+    if(_dec->variances!=NULL){
+      _ogg_free(_dec->variances);
+      _dec->variances=NULL;
+      _ogg_free(_dec->pp_frame_data);
+      _dec->pp_frame_data=NULL;
+    }
+    return 1;
+  }
+  if(_dec->variances==NULL||
+   _dec->pp_frame_has_chroma!=(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC)){
+    size_t frame_sz;
+    frame_sz=_dec->state.info.frame_width*_dec->state.info.frame_height;
+    if(_dec->pp_level<OC_PP_LEVEL_DEBLOCKC){
+      _dec->variances=(int *)_ogg_realloc(_dec->variances,
+       _dec->state.fplanes[0].nfrags*sizeof(_dec->variances[0]));
+      _dec->pp_frame_data=(unsigned char *)_ogg_realloc( 
+       _dec->pp_frame_data,frame_sz*sizeof(_dec->pp_frame_data[0]));
+      _dec->pp_frame_buf[0].width=_dec->state.info.frame_width;
+      _dec->pp_frame_buf[0].height=_dec->state.info.frame_height;
+      _dec->pp_frame_buf[0].stride=-_dec->pp_frame_buf[0].width;
+      _dec->pp_frame_buf[0].data=_dec->pp_frame_data+
+       (1-_dec->pp_frame_buf[0].height)*_dec->pp_frame_buf[0].stride;
+    }
+    else{
+      size_t y_sz;
+      size_t c_sz;
+      int    c_w;
+      int    c_h;
+      _dec->variances=(int *)_ogg_realloc(_dec->variances,
+       _dec->state.nfrags*sizeof(_dec->variances[0]));
+      y_sz=frame_sz;
+      c_w=_dec->state.info.frame_width>>!(_dec->state.info.pixel_fmt&1);
+      c_h=_dec->state.info.frame_height>>!(_dec->state.info.pixel_fmt&2);
+      c_sz=c_w*c_h;
+      frame_sz+=c_sz<<1;
+      _dec->pp_frame_data=(unsigned char *)_ogg_realloc( 
+       _dec->pp_frame_data,frame_sz*sizeof(_dec->pp_frame_data[0]));
+      _dec->pp_frame_buf[0].width=_dec->state.info.frame_width;
+      _dec->pp_frame_buf[0].height=_dec->state.info.frame_height;
+      _dec->pp_frame_buf[0].stride=_dec->pp_frame_buf[0].width;
+      _dec->pp_frame_buf[0].data=_dec->pp_frame_data;
+      _dec->pp_frame_buf[1].width=c_w;
+      _dec->pp_frame_buf[1].height=c_h;
+      _dec->pp_frame_buf[1].stride=_dec->pp_frame_buf[1].width;
+      _dec->pp_frame_buf[1].data=_dec->pp_frame_buf[0].data+y_sz;
+      _dec->pp_frame_buf[2].width=c_w;
+      _dec->pp_frame_buf[2].height=c_h;
+      _dec->pp_frame_buf[2].stride=_dec->pp_frame_buf[2].width;
+      _dec->pp_frame_buf[2].data=_dec->pp_frame_buf[1].data+c_sz;
+      oc_ycbcr_buffer_flip(_dec->pp_frame_buf,_dec->pp_frame_buf);
+    }
+    _dec->pp_frame_has_chroma=(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC);
+  }
+  /*If we're not processing chroma, copy the reference frame's chroma planes.*/
+  if(_dec->pp_level<OC_PP_LEVEL_DEBLOCKC){
+    memcpy(_dec->pp_frame_buf+1,
+     _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]]+1,
+     sizeof(_dec->pp_frame_buf[1])*2);
+  }
+  return 0;
+}
+
+
+
+typedef struct{
+  int  ti[3][64];
+  int  ebi[3][64];
+  int  eob_runs[3][64];
+  int  bounding_values[256];
+  int *coded_fragis[3];
+  int *uncoded_fragis[3];
+  int  fragy0[3];
+  int  fragy_end[3];
+  int  ncoded_fragis[3];
+  int  nuncoded_fragis[3];
+  int  pred_last[3][3];
+  int  mcu_nvfrags;
+  int  loop_filter;
+  int  pp_level;
+}oc_dec_pipeline_state;
+
+
+
+/*Initialize the main decoding pipeline.*/
+static void oc_dec_pipeline_init(oc_dec_ctx *_dec,
+ oc_dec_pipeline_state *_pipe){
+  int *coded_fragi_end;
+  int *uncoded_fragi_end;
+  int  pli;
+  /*If chroma is sub-sampled in the vertical direction, we have to decode two
+     super block rows of Y' for each super block row of Cb and Cr.*/
+  _pipe->mcu_nvfrags=4<<!(_dec->state.info.pixel_fmt&2);
+  /*Initialize the token and extra bits indices for each plane and
+     coefficient.*/
+  memset(_pipe->ti[0],0,sizeof(_pipe->ti[0]));
+  memset(_pipe->ebi[0],0,sizeof(_pipe->ebi[0]));
+  for(pli=1;pli<3;pli++){
+    memcpy(_pipe->ti[pli],_dec->ti0[pli-1],sizeof(_pipe->ti[0]));
+    memcpy(_pipe->ebi[pli],_dec->ebi0[pli-1],sizeof(_pipe->ebi[0]));
+  }
+  /*Also copy over the initial the EOB run counts.*/
+  memcpy(_pipe->eob_runs,_dec->eob_runs,sizeof(_pipe->eob_runs));
+  /*Set up per-plane pointers to the coded and uncoded fragments lists.*/
+  coded_fragi_end=_dec->state.coded_fragis;
+  uncoded_fragi_end=_dec->state.uncoded_fragis;
+  for(pli=0;pli<3;pli++){
+    _pipe->coded_fragis[pli]=coded_fragi_end;
+    _pipe->uncoded_fragis[pli]=uncoded_fragi_end;
+    coded_fragi_end+=_dec->state.ncoded_fragis[pli];
+    uncoded_fragi_end-=_dec->state.nuncoded_fragis[pli];
+  }
+  /*Set the previous DC predictor to 0 for all color planes and frame types.*/
+  memset(_pipe->pred_last,0,sizeof(_pipe->pred_last));
+  /*Initialize the bounding value array for the loop filter.*/
+  _pipe->loop_filter=!oc_state_loop_filter_init(&_dec->state,
+   _pipe->bounding_values);
+  /*Initialize any buffers needed for post-processing.
+    We also save the current post-processing level, to guard against the user
+     changing it from a callback.*/
+  if(!oc_dec_postprocess_init(_dec))_pipe->pp_level=_dec->pp_level;
+  /*If we don't have enough information to post-process, disable it, regardless
+     of the user-requested level.*/
+  else{
+    _pipe->pp_level=OC_PP_LEVEL_DISABLED;
+    memcpy(_dec->pp_frame_buf,
+     _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]],
+     sizeof(_dec->pp_frame_buf[0])*3);
+  }
+}
+
+/*Undo the DC prediction in a single plane of an MCU (one or two super block
+   rows).
+  As a side effect, the number of coded and uncoded fragments in this plane of
+   the MCU is also computed.*/
+static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec,
+ oc_dec_pipeline_state *_pipe,int _pli){
+  /*Undo the DC prediction.*/
+  oc_fragment_plane *fplane;
+  oc_fragment       *frag;
+  int               *pred_last;
+  int                ncoded_fragis;
+  int                fragx;
+  int                fragy;
+  int                fragy0;
+  int                fragy_end;
+  /*Compute the first and last fragment row of the current MCU for this
+     plane.*/
+  fplane=_dec->state.fplanes+_pli;
+  fragy0=_pipe->fragy0[_pli];
+  fragy_end=_pipe->fragy_end[_pli];
+  frag=_dec->state.frags+fplane->froffset+(fragy0*fplane->nhfrags);
+  ncoded_fragis=0;
+  pred_last=_pipe->pred_last[_pli];
+  for(fragy=fragy0;fragy<fragy_end;fragy++){
+    for(fragx=0;fragx<fplane->nhfrags;fragx++,frag++){
+      if(!frag->coded)continue;
+#ifdef _TH_DEBUG_
+      frag->quant[0] = frag->dc; /* stash un-predicted dc for debug output */
+#endif
+      pred_last[OC_FRAME_FOR_MODE[frag->mbmode]]=frag->dc+=
+       oc_frag_pred_dc(frag,fplane,fragx,fragy,pred_last);
+      ncoded_fragis++;
+    }
+  }
+  _pipe->ncoded_fragis[_pli]=ncoded_fragis;
+  /*Also save the number of uncoded fragments so we know how many to copy.*/
+  _pipe->nuncoded_fragis[_pli]=
+   (fragy_end-fragy0)*fplane->nhfrags-ncoded_fragis;
+}
+
+/*Reconstructs all coded fragments in a single MCU (one or two super block
+   rows).
+  This requires that each coded fragment have a proper macro block mode and
+   motion vector (if not in INTRA mode), and have it's DC value decoded, with
+   the DC prediction process reversed, and the number of coded and uncoded
+   fragments in this plane of the MCU be counted.
+  The token lists for each color plane and coefficient should also be filled
+   in, along with initial token offsets, extra bits offsets, and EOB run
+   counts.*/
+static void oc_dec_frags_recon_mcu_plane(oc_dec_ctx *_dec,
+ oc_dec_pipeline_state *_pipe,int _pli){
+  /*Decode the AC coefficients.*/
+  int *ti;
+  int *ebi;
+  int *eob_runs;
+  int *coded_fragi;
+  int *coded_fragi_end;
+  ti=_pipe->ti[_pli];
+  ebi=_pipe->ebi[_pli];
+  eob_runs=_pipe->eob_runs[_pli];
+  coded_fragi_end=coded_fragi=_pipe->coded_fragis[_pli];
+  coded_fragi_end+=_pipe->ncoded_fragis[_pli];
+  for(;coded_fragi<coded_fragi_end;coded_fragi++){
+    oc_fragment    *frag;
+    oc_quant_table *iquants;
+    /*This array is made one bigger than necessary so that an invalid zero
+       run cannot cause a buffer overflow.
+      The inverse zig-zag mapping sends all out of range indices to the last
+       entry of this array, where they are ignored.*/
+    ogg_int16_t    dct_coeffs[128];
+    int            fragi;
+    int            zzi;
+    int            last_zzi;
+    fragi=*coded_fragi;
+    frag=_dec->state.frags+fragi;
+    for(zzi=0;zzi<64;){
+      int token;
+      int eb;
+      last_zzi=zzi;
+      if(eob_runs[zzi]){
+        eob_runs[zzi]--;
+        break;
+      }
+      else{
+        int ebflag;
+        token=_dec->dct_tokens[zzi][ti[zzi]++];
+        ebflag=OC_DCT_TOKEN_EXTRA_BITS[token]!=0;
+        eb=_dec->extra_bits[zzi][ebi[zzi]]&-ebflag;
+        ebi[zzi]+=ebflag;
+        if(token<OC_NDCT_EOB_TOKEN_MAX){
+          eob_runs[zzi]=-oc_dct_token_skip(token,eb);
+        }
+        else oc_dct_token_expand(token,eb,dct_coeffs,&zzi);
+      }
+    }
+    /*TODO: zzi should be exactly 64 here.
+      If it's not, we should report some kind of warning.*/
+    zzi=OC_MINI(zzi,64);
+    dct_coeffs[0]=(ogg_int16_t)frag->dc;
+    iquants=_dec->state.dequant_tables[frag->mbmode!=OC_MODE_INTRA][_pli];
+    /*last_zzi is always initialized.
+      If your compiler thinks otherwise, it is dumb.*/
+    oc_state_frag_recon(&_dec->state,frag,_pli,dct_coeffs,last_zzi,zzi,
+     iquants[_dec->state.qis[0]][0],iquants[frag->qi]);
+  }
+  _pipe->coded_fragis[_pli]=coded_fragi;
+  /*Right now the reconstructed MCU has only the coded blocks in it.*/
+  /*TODO: We make the decision here to always copy the uncoded blocks into it
+     from the reference frame.
+    We could also copy the coded blocks back over the reference frame, if we
+     wait for an additional MCU to be decoded, which might be faster if only a
+     small number of blocks are coded.
+    However, this introduces more latency, creating a larger cache footprint.
+    It's unknown which decision is better, but this one results in simpler
+     code, and the hard case (high bitrate, high resolution) is handled
+     correctly.*/
+  /*Copy the uncoded blocks from the previous reference frame.*/
+  _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli];
+  oc_state_frag_copy(&_dec->state,_pipe->uncoded_fragis[_pli],
+   _pipe->nuncoded_fragis[_pli],OC_FRAME_SELF,OC_FRAME_PREV,_pli);
+
+#ifdef _TH_DEBUG_
+  {
+    int i,j,k;
+    int framei=_dec->state.ref_frame_idx[OC_FRAME_SELF];
+    int ystride=_dec->state.ref_frame_bufs[framei][_pli].stride;
+    int *fragi_end = _pipe->coded_fragis[_pli];
+    int *fragi = fragi_end-_pipe->ncoded_fragis[_pli];
+
+    for(;fragi<fragi_end;fragi++){
+      oc_fragment   *frag=_dec->state.frags+*fragi;
+      unsigned char *src=frag->buffer[framei];
+      for(i=0,j=0;j<8;j++){
+	for(k=0;k<8;k++,i++)
+	  frag->recon[i] = src[k];
+	src+=ystride;
+      }
+    }
+
+    fragi = _pipe->uncoded_fragis[_pli];
+    fragi_end = fragi+_pipe->nuncoded_fragis[_pli];
+
+    for(;fragi<fragi_end;fragi++){
+      oc_fragment   *frag=_dec->state.frags+*fragi;
+      unsigned char *src=frag->buffer[framei];
+      for(i=0,j=0;j<8;j++){
+	for(k=0;k<8;k++,i++)
+	  frag->recon[i] = src[k];
+	src+=ystride;
+      }
+    }
+  }
+#endif
+    
+}
+
+/*Filter a horizontal block edge.*/
+static void oc_filter_hedge(unsigned char *_dst,int _dst_ystride,
+ const unsigned char *_src,int _src_ystride,int _qstep,int _flimit,
+ int *_variance0,int *_variance1){
+  unsigned char       *rdst;
+  const unsigned char *rsrc;
+  unsigned char       *cdst;
+  const unsigned char *csrc;
+  int                  r[10];
+  int                  sum0;
+  int                  sum1;
+  int                  bx;
+  int                  by;
+  rdst=_dst;
+  rsrc=_src;
+  for(bx=0;bx<8;bx++){
+    cdst=rdst;
+    csrc=rsrc;
+    for(by=0;by<10;by++){
+      r[by]=*csrc;
+      csrc+=_src_ystride;
+    }
+    sum0=sum1=0;
+    for(by=0;by<4;by++){
+      sum0+=abs(r[by+1]-r[by]);
+      sum1+=abs(r[by+5]-r[by+6]);
+    }
+    *_variance0+=OC_MINI(255,sum0);
+    *_variance1+=OC_MINI(255,sum1);
+    if(sum0<_flimit&&sum1<_flimit&&r[5]-r[4]<_qstep&&r[4]-r[5]<_qstep){
+      *cdst=(unsigned char)(r[0]*3+r[1]*2+r[2]+r[3]+r[4]+4>>3);
+      cdst+=_dst_ystride;
+      *cdst=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3);
+      cdst+=_dst_ystride;
+      for(by=0;by<4;by++){
+        *cdst=(unsigned char)(r[by]+r[by+1]+r[by+2]+r[by+3]*2+
+         r[by+4]+r[by+5]+r[by+6]+4>>3);
+        cdst+=_dst_ystride;
+      }
+      *cdst=(unsigned char)(r[4]+r[5]+r[6]+r[7]*2+r[8]+r[9]*2+4>>3);
+      cdst+=_dst_ystride;
+      *cdst=(unsigned char)(r[5]+r[6]+r[7]+r[8]*2+r[9]*3+4>>3);
+    }
+    else{
+      for(by=1;by<=8;by++){
+        *cdst=(unsigned char)r[by];
+        cdst+=_dst_ystride;
+      }
+    }
+    rdst++;
+    rsrc++;
+  }
+}
+
+/*Filter a vertical block edge.*/
+static void oc_filter_vedge(unsigned char *_dst,int _dst_ystride,
+ int _qstep,int _flimit,int *_variances){
+  unsigned char       *rdst;
+  const unsigned char *rsrc;
+  unsigned char       *cdst;
+  int                  r[10];
+  int                  sum0;
+  int                  sum1;
+  int                  bx;
+  int                  by;
+  cdst=_dst;
+  for(by=0;by<8;by++){
+    rsrc=cdst-1;
+    rdst=cdst;
+    for(bx=0;bx<10;bx++)r[bx]=*rsrc++;
+    sum0=sum1=0;
+    for(bx=0;bx<4;bx++){
+      sum0+=abs(r[bx+1]-r[bx]);
+      sum1+=abs(r[bx+5]-r[bx+6]);
+    }
+    _variances[0]+=OC_MINI(255,sum0);
+    _variances[1]+=OC_MINI(255,sum1);
+    if(sum0<_flimit&&sum1<_flimit&&r[5]-r[4]<_qstep&&r[4]-r[5]<_qstep){
+      *rdst++=(unsigned char)(r[0]*3+r[1]*2+r[2]+r[3]+r[4]+4>>3);
+      *rdst++=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3);
+      for(bx=0;bx<4;bx++){
+        *rdst++=(unsigned char)(r[bx]+r[bx+1]+r[bx+2]+r[bx+3]*2+
+         r[bx+4]+r[bx+5]+r[bx+6]+4>>3);
+      }
+      *rdst++=(unsigned char)(r[4]+r[5]+r[6]+r[7]*2+r[8]+r[9]*2+4>>3);
+      *rdst=(unsigned char)(r[5]+r[6]+r[7]+r[8]*2+r[9]*3+4>>3);
+    }
+    else for(bx=1;bx<=8;bx++)*rdst++=(unsigned char)r[bx];
+    cdst+=_dst_ystride;
+  }
+}
+
+static void oc_dec_deblock_frag_rows(oc_dec_ctx *_dec,
+ th_img_plane *_dst,th_img_plane *_src,int _pli,int _fragy0,
+ int _fragy_end){
+  oc_fragment_plane   *fplane;
+  int                 *variance;
+  unsigned char       *dc_qi;
+  unsigned char       *dst;
+  const unsigned char *src;
+  int                  notstart;
+  int                  notdone;
+  int                  froffset;
+  int                  flimit;
+  int                  qstep;
+  int                  y_end;
+  int                  y;
+  int                  x;
+  _dst+=_pli;
+  _src+=_pli;
+  fplane=_dec->state.fplanes+_pli;
+  froffset=fplane->froffset+_fragy0*fplane->nhfrags;
+  variance=_dec->variances+froffset;
+  dc_qi=_dec->dc_qis+froffset;
+  notstart=_fragy0>0;
+  notdone=_fragy_end<fplane->nvfrags;
+  /*We want to clear an extra row of variances, except at the end.*/
+  memset(variance+(fplane->nhfrags&-notstart),0,
+   (_fragy_end+notdone-_fragy0-notstart)*fplane->nhfrags*sizeof(variance[0]));
+  /*Except for the first time, we want to point to the middle of the row.*/
+  y=(_fragy0<<3)+(notstart<<2);
+  dst=_dst->data+y*_dst->stride;
+  src=_src->data+y*_src->stride;
+  for(;y<4;y++){
+    memcpy(dst,src,_dst->width*sizeof(dst[0]));
+    dst+=_dst->stride;
+    src+=_src->stride;
+  }
+  /*We also want to skip the last row in the frame for this loop.*/
+  y_end=_fragy_end-!notdone<<3;
+  for(;y<y_end;y+=8){
+    qstep=_dec->pp_dc_scale[*dc_qi];
+    flimit=(qstep*3)>>2;
+    oc_filter_hedge(dst,_dst->stride,src-_src->stride,_src->stride,
+     qstep,flimit,variance,variance+fplane->nhfrags);
+    variance++;
+    dc_qi++;
+    for(x=8;x<_dst->width;x+=8){
+      qstep=_dec->pp_dc_scale[*dc_qi];
+      flimit=(qstep*3)>>2;
+      oc_filter_hedge(dst+x,_dst->stride,src+x-_src->stride,_src->stride,
+       qstep,flimit,variance,variance+fplane->nhfrags);
+      oc_filter_vedge(dst+x-(_dst->stride<<2)-4,_dst->stride,
+       qstep,flimit,variance-1);
+      variance++;
+      dc_qi++;
+    }
+    dst+=_dst->stride<<3;
+    src+=_src->stride<<3;
+  }
+  /*And finally, handle the last row in the frame, if it's in the range.*/
+  if(!notdone){
+    for(;y<_dst->height;y++){
+      memcpy(dst,src,_dst->width*sizeof(dst[0]));
+      dst+=_dst->stride;
+      src+=_src->stride;
+    }
+    /*Filter the last row of vertical block edges.*/
+    dc_qi++;
+    for(x=8;x<_dst->width;x+=8){
+      qstep=_dec->pp_dc_scale[*dc_qi++];
+      flimit=(qstep*3)>>2;
+      oc_filter_vedge(dst+x-(_dst->stride<<3)-4,_dst->stride,
+       qstep,flimit,variance++);
+    }
+  }
+}
+
+static void oc_dering_block(unsigned char *_idata,int _ystride,int _b,
+ int _dc_scale,int _sharp_mod,int _strong){
+  static const int     MOD_MAX[2]={24,32};
+  static const int     MOD_SHIFT[2]={1,0};
+  const unsigned char *psrc;
+  const unsigned char *src;
+  const unsigned char *nsrc;
+  unsigned char       *dst;
+  int                  vmod[72];
+  int                  hmod[72];
+  int                  mod_hi;
+  int                  by;
+  int                  bx;
+  mod_hi=OC_MINI(3*_dc_scale,MOD_MAX[_strong]);
+  dst=_idata;
+  src=dst;
+  psrc=src-(_ystride&-!(_b&4));
+  for(by=0;by<9;by++){
+    for(bx=0;bx<8;bx++){
+      int mod;
+      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<MOD_SHIFT[_strong]);
+      vmod[(by<<3)+bx]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
+    }
+    psrc=src;
+    src+=_ystride&-(!(_b&8)|by<7);
+  }
+  nsrc=dst;
+  psrc=dst-!(_b&1);
+  for(bx=0;bx<9;bx++){
+    src=nsrc;
+    for(by=0;by<8;by++){
+      int mod;
+      mod=32+_dc_scale-(abs(*src-*psrc)<<MOD_SHIFT[_strong]);
+      hmod[(bx<<3)+by]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
+      psrc+=_ystride;
+      src+=_ystride;
+    }
+    psrc=nsrc;
+    nsrc+=!(_b&2)|bx<7;
+  }
+  src=dst;
+  psrc=src-(_ystride&-!(_b&4));
+  nsrc=src+_ystride;
+  for(by=0;by<8;by++){
+    int a;
+    int b;
+    int w;
+    a=128;
+    b=64;
+    w=hmod[by];
+    a-=w;
+    b+=w**(src-!(_b&1));
+    w=vmod[(by<<3)];
+    a-=w;
+    b+=w*psrc[0];
+    w=vmod[(by+1<<3)];
+    a-=w;
+    b+=w*nsrc[0];
+    w=hmod[(1<<3)+by];
+    a-=w;
+    b+=w*src[1];
+    dst[0]=OC_CLAMP255(a*src[0]+b>>7);
+    for(bx=1;bx<7;bx++){
+      a=128;
+      b=64;
+      w=hmod[(bx<<3)+by];
+      a-=w;
+      b+=w*src[bx-1];
+      w=vmod[(by<<3)+bx];
+      a-=w;
+      b+=w*psrc[bx];
+      w=vmod[(by+1<<3)+bx];
+      a-=w;
+      b+=w*nsrc[bx];
+      w=hmod[(bx+1<<3)+by];
+      a-=w;
+      b+=w*src[bx+1];
+      dst[bx]=OC_CLAMP255(a*src[bx]+b>>7);
+    }
+    a=128;
+    b=64;
+    w=hmod[(7<<3)+by];
+    a-=w;
+    b+=w*src[6];
+    w=vmod[(by<<3)+7];
+    a-=w;
+    b+=w*psrc[7];
+    w=vmod[(by+1<<3)+7];
+    a-=w;
+    b+=w*nsrc[7];
+    w=hmod[(8<<3)+by];
+    a-=w;
+    b+=w*src[7+!(_b&2)];
+    dst[7]=OC_CLAMP255(a*src[7]+b>>7);
+    dst+=_ystride;
+    psrc=src;
+    src=nsrc;
+    nsrc+=_ystride&-(!(_b&8)|by<6);
+  }
+}
+
+#define OC_DERING_THRESH1 (384)
+#define OC_DERING_THRESH2 (4*OC_DERING_THRESH1)
+#define OC_DERING_THRESH3 (5*OC_DERING_THRESH1)
+#define OC_DERING_THRESH4 (10*OC_DERING_THRESH1)
+
+static void oc_dec_dering_frag_rows(oc_dec_ctx *_dec,th_img_plane *_img,
+ int _pli,int _fragy0,int _fragy_end){
+  th_img_plane  *iplane;
+  oc_fragment_plane *fplane;
+  oc_fragment       *frag;
+  int               *variance;
+  unsigned char     *idata;
+  int                sthresh;
+  int                strong;
+  int                froffset;
+  int                y_end;
+  int                y;
+  int                x;
+  iplane=_img+_pli;
+  fplane=_dec->state.fplanes+_pli;
+  froffset=fplane->froffset+_fragy0*fplane->nhfrags;
+  variance=_dec->variances+froffset;
+  frag=_dec->state.frags+froffset;
+  strong=_dec->pp_level>=(_pli?OC_PP_LEVEL_SDERINGC:OC_PP_LEVEL_SDERINGY);
+  sthresh=_pli?OC_DERING_THRESH4:OC_DERING_THRESH3;
+  y=_fragy0<<3;
+  idata=iplane->data+y*iplane->stride;
+  y_end=_fragy_end<<3;
+  for(;y<y_end;y+=8){
+    for(x=0;x<iplane->width;x+=8){
+      int b;
+      int qi;
+      int var;
+      qi=frag->qi;
+      var=*variance;
+      b=(x<=0)|(x+8>=iplane->width)<<1|(y<=0)<<2|(y+8>=iplane->height)<<3;
+      if(strong&&var>sthresh){
+        oc_dering_block(idata+x,iplane->stride,b,
+         _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
+        if(_pli||(b&1)&&*(variance-1)>OC_DERING_THRESH4||
+         (b&2)&&variance[1]>OC_DERING_THRESH4||
+         (b&4)&&*(variance-fplane->nvfrags)>OC_DERING_THRESH4||
+         (b&8)&&variance[fplane->nvfrags]>OC_DERING_THRESH4){
+          oc_dering_block(idata+x,iplane->stride,b,
+           _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
+          oc_dering_block(idata+x,iplane->stride,b,
+           _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
+        }
+      }
+      else if(var>OC_DERING_THRESH2){
+        oc_dering_block(idata+x,iplane->stride,b,
+         _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
+      }
+      else if(var>OC_DERING_THRESH1){
+        oc_dering_block(idata+x,iplane->stride,b,
+         _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],0);
+      }
+      frag++;
+      variance++;
+    }
+    idata+=iplane->stride<<3;
+  }
+}
+
+
+
+th_dec_ctx *th_decode_alloc(const th_info *_info,
+ const th_setup_info *_setup){
+  oc_dec_ctx *dec;
+  if(_info==NULL||_setup==NULL)return NULL;
+  dec=_ogg_malloc(sizeof(*dec));
+  if(oc_dec_init(dec,_info,_setup)<0){
+    _ogg_free(dec);
+    return NULL;
+  }
+  dec->state.curframe_num=0;
+  return dec;
+}
+
+void th_decode_free(th_dec_ctx *_dec){
+  if(_dec!=NULL){
+    oc_dec_clear(_dec);
+    _ogg_free(_dec);
+  }
+}
+
+int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf,
+ size_t _buf_sz){
+  switch(_req){
+    case TH_DECCTL_GET_PPLEVEL_MAX:{
+      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+      if(_buf_sz!=sizeof(int))return TH_EINVAL;
+      (*(int *)_buf)=OC_PP_LEVEL_MAX;
+      return 0;
+    }break;
+    case TH_DECCTL_SET_PPLEVEL:{
+      int pp_level;
+      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+      if(_buf_sz!=sizeof(int))return TH_EINVAL;
+      pp_level=*(int *)_buf;
+      if(pp_level<0||pp_level>OC_PP_LEVEL_MAX)return TH_EINVAL;
+      _dec->pp_level=pp_level;
+      return 0;
+    }break;
+    case TH_DECCTL_SET_GRANPOS:{
+      ogg_int64_t granpos;
+      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+      if(_buf_sz!=sizeof(ogg_int64_t))return TH_EINVAL;
+      granpos=*(ogg_int64_t *)_buf;
+      if(granpos<0)return TH_EINVAL;
+      _dec->state.granpos=granpos;
+      _dec->state.keyframe_num=
+       granpos>>_dec->state.info.keyframe_granule_shift;
+      _dec->state.curframe_num=_dec->state.keyframe_num+
+       (granpos&(1<<_dec->state.info.keyframe_granule_shift)-1);
+      return 0;
+    }break;
+    case TH_DECCTL_SET_STRIPE_CB:{
+      th_stripe_callback *cb;
+      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+      if(_buf_sz!=sizeof(th_stripe_callback))return TH_EINVAL;
+      cb=(th_stripe_callback *)_buf;
+      _dec->stripe_cb.ctx=cb->ctx;
+      _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
+      return 0;
+    }break;
+    default:return TH_EIMPL;
+  }
+}
+
+int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
+ ogg_int64_t *_granpos){
+  int ret;
+  if(_dec==NULL||_op==NULL)return TH_EFAULT;
+  /*A completely empty packet indicates a dropped frame and is treated exactly
+     like an inter frame with no coded blocks.
+    Only proceed if we have a non-empty packet.*/
+
+  if(_op->bytes!=0){
+    oc_dec_pipeline_state pipe;
+    th_ycbcr_buffer       stripe_buf;
+    int                   stripe_fragy;
+    int                   refi;
+    int                   pli;
+    int                   notstart;
+    int                   notdone;
+    theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes);
+    ret=oc_dec_frame_header_unpack(_dec);
+    if(ret<0)return ret;
+    /*Select a free buffer to use for the reconstructed version of this
+       frame.*/
+    if(_dec->state.frame_type!=OC_INTRA_FRAME&&
+     (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
+     _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){
+      th_info *info;
+      size_t       yplane_sz;
+      size_t       cplane_sz;
+      int          yhstride;
+      int          yvstride;
+      int          chstride;
+      int          cvstride;
+      /*We're decoding an INTER frame, but have no initialized reference
+         buffers (i.e., decoding did not start on a key frame).
+        We initialize them to a solid gray here.*/
+      _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0;
+      _dec->state.ref_frame_idx[OC_FRAME_PREV]=0;
+      _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi=1;
+      info=&_dec->state.info;
+      yhstride=info->frame_width+2*OC_UMV_PADDING;
+      yvstride=info->frame_height+2*OC_UMV_PADDING;
+      chstride=yhstride>>!(info->pixel_fmt&1);
+      cvstride=yvstride>>!(info->pixel_fmt&2);
+      yplane_sz=(size_t)yhstride*yvstride;
+      cplane_sz=(size_t)chstride*cvstride;
+      memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz);
+    }
+    else{
+      for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
+       refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++);
+      _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
+    }
+    if(_dec->state.frame_type==OC_INTRA_FRAME){
+      oc_dec_mark_all_intra(_dec);
+      _dec->state.keyframe_num=_dec->state.curframe_num;
+    }else{
+      oc_dec_coded_flags_unpack(_dec);
+      oc_dec_mb_modes_unpack(_dec);
+      oc_dec_mv_unpack_and_frag_modes_fill(_dec);
+    }
+    oc_dec_block_qis_unpack(_dec);
+    oc_dec_residual_tokens_unpack(_dec);
+
+    /*Update granule position.
+      This must be done before the striped decode callbacks so that the
+       application knows what to do with the frame data.*/
+    _dec->state.granpos=
+     (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
+     (_dec->state.curframe_num-_dec->state.keyframe_num);
+    _dec->state.curframe_num++;
+    if(_granpos!=NULL)*_granpos=_dec->state.granpos;
+    /*All of the rest of the operations -- DC prediction reversal,
+       reconstructing coded fragments, copying uncoded fragments, loop
+       filtering, extending borders, and out-of-loop post-processing -- should
+       be pipelined.
+      I.e., DC prediction reversal, reconstruction, and uncoded fragment
+       copying are done for one or two super block rows, then loop filtering is
+       run as far as it can, then bordering copying, then post-processing.
+      For 4:2:0 video a Minimum Codable Unit or MCU contains two luma super
+       block rows, and one chroma.
+      Otherwise, an MCU consists of one super block row from each plane.
+      Inside each MCU, we perform all of the steps on one color plane before
+       moving on to the next.
+      After reconstruction, the additional filtering stages introduce a delay
+       since they need some pixels from the next fragment row.
+      Thus the actual number of decoded rows available is slightly smaller for
+       the first MCU, and slightly larger for the last.
+
+      This entire process allows us to operate on the data while it is still in
+       cache, resulting in big performance improvements.
+      An application callback allows further application processing (blitting
+       to video memory, color conversion, etc.) to also use the data while it's
+       in cache.*/
+    oc_dec_pipeline_init(_dec,&pipe);
+    oc_ycbcr_buffer_flip(stripe_buf,_dec->pp_frame_buf);
+    notstart=0;
+    notdone=1;
+    for(stripe_fragy=notstart=0;notdone;stripe_fragy+=pipe.mcu_nvfrags){
+      int avail_fragy0;
+      int avail_fragy_end;
+      avail_fragy0=avail_fragy_end=_dec->state.fplanes[0].nvfrags;
+      notdone=stripe_fragy+pipe.mcu_nvfrags<avail_fragy_end;
+      for(pli=0;pli<3;pli++){
+        oc_fragment_plane *fplane;
+        int                frag_shift;
+        int                pp_offset;
+        int                sdelay;
+        int                edelay;
+        fplane=_dec->state.fplanes+pli;
+        /*Compute the first and last fragment row of the current MCU for this
+           plane.*/
+        frag_shift=pli!=0&&!(_dec->state.info.pixel_fmt&2);
+        pipe.fragy0[pli]=stripe_fragy>>frag_shift;
+        pipe.fragy_end[pli]=OC_MINI(fplane->nvfrags,
+         pipe.fragy0[pli]+(pipe.mcu_nvfrags>>frag_shift));
+        oc_dec_dc_unpredict_mcu_plane(_dec,&pipe,pli);
+        oc_dec_frags_recon_mcu_plane(_dec,&pipe,pli);
+        sdelay=edelay=0;
+        if(pipe.loop_filter){
+          sdelay+=notstart;
+          edelay+=notdone;
+          oc_state_loop_filter_frag_rows(&_dec->state,pipe.bounding_values,
+           refi,pli,pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay);
+        }
+        /*To fill the borders, we have an additional two pixel delay, since a
+           fragment in the next row could filter its top edge, using two pixels
+           from a fragment in this row.
+          But there's no reason to delay a full fragment between the two.*/
+        oc_state_borders_fill_rows(&_dec->state,refi,pli,
+         (pipe.fragy0[pli]-sdelay<<3)-(sdelay<<1),
+         (pipe.fragy_end[pli]-edelay<<3)-(edelay<<1));
+        /*Out-of-loop post-processing.*/
+        pp_offset=3*(pli!=0);
+        if(pipe.pp_level>=OC_PP_LEVEL_DEBLOCKY+pp_offset){
+          /*Perform de-blocking in one plane.*/
+          sdelay+=notstart;
+          edelay+=notdone;
+          oc_dec_deblock_frag_rows(_dec,_dec->pp_frame_buf,
+           _dec->state.ref_frame_bufs[refi],pli,
+           pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay);
+          if(pipe.pp_level>=OC_PP_LEVEL_DERINGY+pp_offset){
+            /*Perform de-ringing in one plane.*/
+            sdelay+=notstart;
+            edelay+=notdone;
+            oc_dec_dering_frag_rows(_dec,_dec->pp_frame_buf,pli,
+             pipe.fragy0[pli]-sdelay,pipe.fragy_end[pli]-edelay);
+          }
+        }
+        /*If no post-processing is done, we still need to delay a row for the
+           loop filter, thanks to the strange filtering order VP3 chose.*/
+        else if(pipe.loop_filter){
+          sdelay+=notstart;
+          edelay+=notdone;
+        }
+        /*Compute the intersection of the available rows in all planes.
+          If chroma is sub-sampled, the effect of each of its delays is
+           doubled, but luma might have more post-processing filters enabled
+           than chroma, so we don't know up front which one is the limiting
+           factor.*/
+        avail_fragy0=OC_MINI(avail_fragy0,pipe.fragy0[pli]-sdelay<<frag_shift);
+        avail_fragy_end=OC_MINI(avail_fragy_end,
+         pipe.fragy_end[pli]-edelay<<frag_shift);
+      }
+      if(_dec->stripe_cb.stripe_decoded!=NULL){
+        /*Make the callback, ensuring we flip the sense of the "start" and
+           "end" of the available region upside down.*/
+        (*_dec->stripe_cb.stripe_decoded)(_dec->stripe_cb.ctx,stripe_buf,
+         _dec->state.fplanes[0].nvfrags-avail_fragy_end,
+         _dec->state.fplanes[0].nvfrags-avail_fragy0);
+      }
+      notstart=1;
+    }
+
+#ifdef _TH_DEBUG_
+    {
+      int x,y,i,j,k,xn,yn;
+      int plane;
+      int buf;
+
+      /* dump fragment DCT components */
+      for(plane=0;plane<3;plane++){
+	char *plstr;
+	int offset;
+	switch(plane){
+	case 0:
+	  plstr="Y";
+	  xn = _dec->state.info.frame_width>>3;
+	  yn = _dec->state.info.frame_height>>3;
+	  offset = 0; 
+	  break;
+	case 1:
+	  plstr="U";
+	  xn = _dec->state.info.frame_width>>4;
+	  yn = _dec->state.info.frame_height>>4;
+	  offset = xn*yn*4;
+	  break;
+	case 2:
+	  plstr="V";
+	  xn = _dec->state.info.frame_width>>4;
+	  yn = _dec->state.info.frame_height>>4;
+	  offset = xn*yn*5;
+	  break;
+	}
+	for(y=0;y<yn;y++){
+	  for(x=0;x<xn;x++,i++){
+	    
+	    for(buf=0;buf<4;buf++){
+	      int *ptr;
+	      char *bufn;
+	      int codecheck=0;
+
+	      i = offset + y*xn + x;
+
+	      switch(buf){
+	      case 0:
+		codecheck=1;
+		bufn = "coded";
+		ptr = _dec->state.frags[i].quant;
+		break;
+	      case 1:
+		codecheck=1;
+		bufn = "coeff";
+		ptr = _dec->state.frags[i].freq;
+		break;
+	      case 2:
+		codecheck=1;
+		bufn = "idct";
+		ptr = _dec->state.frags[i].time;
+		break;
+	      case 3:
+		bufn = "recon";
+		ptr = _dec->state.frags[i].loop;
+		break;
+	      }
+	      
+	      
+	      TH_DEBUG("%s %s [%d][%d] = {",bufn,plstr,x,y);
+	      if(codecheck && !_dec->state.frags[i].coded)
+		TH_DEBUG(" not coded }\n");
+	      else{
+		int l=0;
+		for(j=0;j<8;j++){
+		  TH_DEBUG("\n   ");
+		  for(k=0;k<8;k++,l++){
+		    TH_DEBUG("%d ",ptr[l]);
+		  }
+		}
+		TH_DEBUG(" }\n");
+	      }
+	    }
+	    TH_DEBUG("\n");
+	  }
+	}
+      }
+    }
+#endif
+
+    /*Finish filling in the reference frame borders.*/
+    for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_dec->state,refi,pli);
+    /*Update the reference frame indices.*/
+    if(_dec->state.frame_type==OC_INTRA_FRAME){
+      /*The new frame becomes both the previous and gold reference frames.*/
+      _dec->state.ref_frame_idx[OC_FRAME_GOLD]=
+       _dec->state.ref_frame_idx[OC_FRAME_PREV]=
+       _dec->state.ref_frame_idx[OC_FRAME_SELF];
+    }
+    else{
+      /*Otherwise, just replace the previous reference frame.*/
+      _dec->state.ref_frame_idx[OC_FRAME_PREV]=
+       _dec->state.ref_frame_idx[OC_FRAME_SELF];
+    }
+#if defined(OC_DUMP_IMAGES)
+    /*Don't dump images for dropped frames.*/
+    oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec");
+#endif
+    return 0;
+  }
+  else{
+    /*Just update the granule position and return.*/
+    _dec->state.granpos=
+     (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
+     (_dec->state.curframe_num-_dec->state.keyframe_num);
+    _dec->state.curframe_num++;
+    if(_granpos!=NULL)*_granpos=_dec->state.granpos;
+    return TH_DUPFRAME;
+  }
+}
+
+int th_decode_ycbcr_out(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr){
+  oc_ycbcr_buffer_flip(_ycbcr,_dec->pp_frame_buf);
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/dequant.c
@@ -0,0 +1,230 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: dequant.c 14369 2008-01-05 23:15:32Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#include "dequant.h"
+#include "decint.h"
+
+int oc_quant_params_unpack(oggpack_buffer *_opb,
+ th_quant_info *_qinfo){
+  th_quant_base *base_mats;
+  long           val;
+  int            nbase_mats;
+  int            sizes[64];
+  int            indices[64];
+  int            nbits;
+  int            bmi;
+  int            ci;
+  int            qti;
+  int            pli;
+  int            qri;
+  int            qi;
+  int            i;
+  theorapackB_read(_opb,3,&val);
+  nbits=(int)val;
+  for(qi=0;qi<64;qi++){
+    theorapackB_read(_opb,nbits,&val);
+    _qinfo->loop_filter_limits[qi]=(unsigned char)val;
+  }
+  theorapackB_read(_opb,4,&val);
+  nbits=(int)val+1;
+  for(qi=0;qi<64;qi++){
+    theorapackB_read(_opb,nbits,&val);
+    _qinfo->ac_scale[qi]=(ogg_uint16_t)val;
+  }
+  theorapackB_read(_opb,4,&val);
+  nbits=(int)val+1;
+  for(qi=0;qi<64;qi++){
+    theorapackB_read(_opb,nbits,&val);
+    _qinfo->dc_scale[qi]=(ogg_uint16_t)val;
+  }
+  theorapackB_read(_opb,9,&val);
+  nbase_mats=(int)val+1;
+  base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0]));
+  for(bmi=0;bmi<nbase_mats;bmi++){
+    for(ci=0;ci<64;ci++){
+      theorapackB_read(_opb,8,&val);
+      base_mats[bmi][ci]=(unsigned char)val;
+    }
+  }
+  nbits=oc_ilog(nbase_mats-1);
+  for(i=0;i<6;i++){
+    th_quant_ranges *qranges;
+    th_quant_base   *qrbms;
+    int             *qrsizes;
+    qti=i/3;
+    pli=i%3;
+    qranges=_qinfo->qi_ranges[qti]+pli;
+    if(i>0){
+      theorapackB_read1(_opb,&val);
+      if(!val){
+        int qtj;
+        int plj;
+        if(qti>0){
+          theorapackB_read1(_opb,&val);
+          if(val){
+            qtj=qti-1;
+            plj=pli;
+          }
+          else{
+            qtj=(i-1)/3;
+            plj=(i-1)%3;
+          }
+        }
+        else{
+          qtj=(i-1)/3;
+          plj=(i-1)%3;
+        }
+        *qranges=*(_qinfo->qi_ranges[qtj]+plj);
+        continue;
+      }
+    }
+    theorapackB_read(_opb,nbits,&val);
+    indices[0]=(int)val;
+    for(qi=qri=0;qi<63;){
+      theorapackB_read(_opb,oc_ilog(62-qi),&val);
+      sizes[qri]=(int)val+1;
+      qi+=(int)val+1;
+      theorapackB_read(_opb,nbits,&val);
+      indices[++qri]=(int)val;
+    }
+    /*Note: The caller is responsible for cleaning up any partially
+       constructed qinfo.*/
+    if(qi>63){
+      _ogg_free(base_mats);
+      return TH_EBADHEADER;
+    }
+    qranges->nranges=qri;
+    qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0]));
+    memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0]));
+    qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0]));
+    qranges->base_matrices=(const th_quant_base *)qrbms;
+    do{
+      bmi=indices[qri];
+      /*Note: The caller is responsible for cleaning up any partially
+         constructed qinfo.*/
+      if(bmi>=nbase_mats){
+        _ogg_free(base_mats);
+        return TH_EBADHEADER;
+      }
+      memcpy(qrbms[qri],base_mats[bmi],sizeof(qrbms[qri]));
+    }
+    while(qri-->0);
+  }
+
+#ifdef _TH_DEBUG_
+  /* dump the tables */
+  {
+    int i, j, k, l, m;
+    TH_DEBUG("loop filter limits = {");
+    for(i=0;i<64;){
+      TH_DEBUG("\n        ");
+      for(j=0;j<16;i++,j++)
+	TH_DEBUG("%3d ",_qinfo->loop_filter_limits[i]);
+    }
+    TH_DEBUG("\n}\n\n");
+
+    TH_DEBUG("ac scale = {");
+    for(i=0;i<64;){
+      TH_DEBUG("\n        ");
+      for(j=0;j<16;i++,j++)
+	TH_DEBUG("%3d ",_qinfo->ac_scale[i]);
+    }
+    TH_DEBUG("\n}\n\n");
+
+    TH_DEBUG("dc scale = {");
+    for(i=0;i<64;){
+      TH_DEBUG("\n        ");
+      for(j=0;j<16;i++,j++)
+	TH_DEBUG("%3d ",_qinfo->dc_scale[i]);
+    }
+    TH_DEBUG("\n}\n\n");
+
+    for(k=0;k<2;k++)
+      for(l=0;l<3;l++){
+	char *name[2][3]={
+	  {"intra Y bases","intra U bases", "intra V bases"},
+	  {"inter Y bases","inter U bases", "inter V bases"}
+	};
+
+	th_quant_ranges *r = &_qinfo->qi_ranges[k][l];
+	TH_DEBUG("%s = {\n",name[k][l]);
+	TH_DEBUG("        ranges = %d\n",r->nranges);
+	TH_DEBUG("        intervals = { ");
+	for(i=0;i<r->nranges;i++)
+	  TH_DEBUG("%3d ",r->sizes[i]);
+	TH_DEBUG("}\n");
+	TH_DEBUG("\n        matricies = { ");
+	for(m=0;m<r->nranges+1;m++){
+	  TH_DEBUG("\n          { ");
+	  for(i=0;i<64;){
+	    TH_DEBUG("\n            ");
+	    for(j=0;j<8;i++,j++)
+	      TH_DEBUG("%3d ",r->base_matrices[m][i]);
+	  }
+	  TH_DEBUG("\n          }");
+	}
+	TH_DEBUG("\n        }\n");
+      }
+  }
+    
+#endif
+
+  _ogg_free(base_mats);
+  return 0;
+}
+
+void oc_quant_params_clear(th_quant_info *_qinfo){
+  int i;
+  for(i=6;i-->0;){
+    int qti;
+    int pli;
+    qti=i/3;
+    pli=i%3;
+    /*Clear any duplicate pointer references.*/
+    if(i>0){
+      int qtj;
+      int plj;
+      qtj=(i-1)/3;
+      plj=(i-1)%3;
+      if(_qinfo->qi_ranges[qti][pli].sizes==
+       _qinfo->qi_ranges[qtj][plj].sizes){
+        _qinfo->qi_ranges[qti][pli].sizes=NULL;
+      }
+      if(_qinfo->qi_ranges[qti][pli].base_matrices==
+       _qinfo->qi_ranges[qtj][plj].base_matrices){
+        _qinfo->qi_ranges[qti][pli].base_matrices=NULL;
+      }
+    }
+    if(qti>0){
+      if(_qinfo->qi_ranges[1][pli].sizes==
+       _qinfo->qi_ranges[0][pli].sizes){
+        _qinfo->qi_ranges[1][pli].sizes=NULL;
+      }
+      if(_qinfo->qi_ranges[1][pli].base_matrices==
+       _qinfo->qi_ranges[0][pli].base_matrices){
+        _qinfo->qi_ranges[1][pli].base_matrices=NULL;
+      }
+    }
+    /*Now free all the non-duplicate storage.*/
+    _ogg_free((void *)_qinfo->qi_ranges[qti][pli].sizes);
+    _ogg_free((void *)_qinfo->qi_ranges[qti][pli].base_matrices);
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/dequant.h
@@ -0,0 +1,26 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: dequant.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+#if !defined(_dequant_H)
+# define _dequant_H (1)
+# include "quant.h"
+
+int oc_quant_params_unpack(oggpack_buffer *_opb,
+ th_quant_info *_qinfo);
+void oc_quant_params_clear(th_quant_info *_qinfo);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/enquant.h
@@ -0,0 +1,43 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: enquant.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+#if !defined(_enquant_H)
+# define _enquant_H (1)
+# include "quant.h"
+
+/*The amount to scale the forward quantizer value by.*/
+#define OC_FQUANT_SCALE ((ogg_uint32_t)1<<OC_FQUANT_SHIFT)
+/*The amount to add to the scaled forward quantizer for rounding.*/
+#define OC_FQUANT_ROUND (1<<OC_FQUANT_SHIFT-1)
+/*The amount to shift the resulting product by.*/
+#define OC_FQUANT_SHIFT (16)
+
+
+
+/*The default quantization parameters used by VP3.1.*/
+extern const th_quant_info TH_VP31_QUANT_INFO;
+/*Our default quantization parameters.*/
+extern const th_quant_info OC_DEF_QUANT_INFO[4];
+
+
+
+void oc_quant_params_pack(oggpack_buffer *_opb,
+ const th_quant_info *_qinfo);
+void oc_enquant_tables_init(oc_quant_table *_dequant[2][3],
+ oc_quant_table *_enquant[2][3],const th_quant_info *_qinfo);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/fragment.c
@@ -0,0 +1,199 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: fragment.c 14348 2008-01-04 18:17:00Z tterribe $
+
+ ********************************************************************/
+
+#include "../internal.h"
+
+void oc_frag_recon_intra(const oc_theora_state *_state,unsigned char *_dst,
+ int _dst_ystride,const ogg_int16_t *_residue){
+  _state->opt_vtable.frag_recon_intra(_dst,_dst_ystride,_residue);
+}
+
+void oc_frag_recon_intra_c(unsigned char *_dst,int _dst_ystride,
+ const ogg_int16_t *_residue){
+  int i;
+  for(i=0;i<8;i++){
+    int j;
+    for(j=0;j<8;j++){
+      int res;
+      res=*_residue++;
+      _dst[j]=OC_CLAMP255(res+128);
+    }
+    _dst+=_dst_ystride;
+  }
+}
+
+void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst,
+ int _dst_ystride,const unsigned char *_src,int _src_ystride,
+ const ogg_int16_t *_residue){
+  _state->opt_vtable.frag_recon_inter(_dst,_dst_ystride,_src,_src_ystride,
+   _residue);
+}
+
+void oc_frag_recon_inter_c(unsigned char *_dst,int _dst_ystride,
+ const unsigned char *_src,int _src_ystride,const ogg_int16_t *_residue){
+  int i;
+  for(i=0;i<8;i++){
+    int j;
+    for(j=0;j<8;j++){
+      int res;
+      res=*_residue++;
+      _dst[j]=OC_CLAMP255(res+_src[j]);
+    }
+    _dst+=_dst_ystride;
+    _src+=_src_ystride;
+  }
+}
+
+void oc_frag_recon_inter2(const oc_theora_state *_state,unsigned char *_dst,
+ int _dst_ystride,const unsigned char *_src1,int _src1_ystride,
+ const unsigned char *_src2,int _src2_ystride,const ogg_int16_t *_residue){
+  _state->opt_vtable.frag_recon_inter2(_dst,_dst_ystride,_src1,_src1_ystride,
+   _src2,_src2_ystride,_residue);
+}
+
+void oc_frag_recon_inter2_c(unsigned char *_dst,int _dst_ystride,
+ const unsigned char *_src1,int _src1_ystride,const unsigned char *_src2,
+ int _src2_ystride,const ogg_int16_t *_residue){
+  int i;
+  for(i=0;i<8;i++){
+    int j;
+    for(j=0;j<8;j++){
+      int res;
+      res=*_residue++;
+      _dst[j]=OC_CLAMP255(res+((int)_src1[j]+_src2[j]>>1));
+    }
+    _dst+=_dst_ystride;
+    _src1+=_src1_ystride;
+    _src2+=_src2_ystride;
+  }
+}
+
+/*Computes the predicted DC value for the given fragment.
+  This requires that the fully decoded DC values be available for the left,
+   upper-left, upper, and upper-right fragments (if they exist).
+  _frag:      The fragment to predict the DC value for.
+  _fplane:    The fragment plane the fragment belongs to.
+  _x:         The x-coordinate of the fragment.
+  _y:         The y-coordinate of the fragment.
+  _pred_last: The last fully-decoded DC value for each predictor frame
+               (OC_FRAME_GOLD, OC_FRAME_PREV and OC_FRAME_SELF).
+              This should be initialized to 0's for the first fragment in each
+               color plane.
+  Return: The predicted DC value for this fragment.*/
+int oc_frag_pred_dc(const oc_fragment *_frag,
+ const oc_fragment_plane *_fplane,int _x,int _y,int _pred_last[3]){
+  static const int PRED_SCALE[16][4]={
+    /*0*/
+    {0,0,0,0},
+    /*OC_PL*/
+    {1,0,0,0},
+    /*OC_PUL*/
+    {1,0,0,0},
+    /*OC_PL|OC_PUL*/
+    {1,0,0,0},
+    /*OC_PU*/
+    {1,0,0,0},
+    /*OC_PL|OC_PU*/
+    {1,1,0,0},
+    /*OC_PUL|OC_PU*/
+    {0,1,0,0},
+    /*OC_PL|OC_PUL|PC_PU*/
+    {29,-26,29,0},
+    /*OC_PUR*/
+    {1,0,0,0},
+    /*OC_PL|OC_PUR*/
+    {75,53,0,0},
+    /*OC_PUL|OC_PUR*/
+    {1,1,0,0},
+    /*OC_PL|OC_PUL|OC_PUR*/
+    {75,0,53,0},
+    /*OC_PU|OC_PUR*/
+    {1,0,0,0},
+    /*OC_PL|OC_PU|OC_PUR*/
+    {75,0,53,0},
+    /*OC_PUL|OC_PU|OC_PUR*/
+    {3,10,3,0},
+    /*OC_PL|OC_PUL|OC_PU|OC_PUR*/
+    {29,-26,29,0}
+  };
+  static const int PRED_SHIFT[16]={0,0,0,0,0,1,0,5,0,7,1,7,0,7,4,5};
+  static const int PRED_RMASK[16]={0,0,0,0,0,1,0,31,0,127,1,127,0,127,15,31};
+  static const int BC_MASK[8]={
+    /*No boundary condition.*/
+    OC_PL|OC_PUL|OC_PU|OC_PUR,
+    /*Left column.*/
+    OC_PU|OC_PUR,
+    /*Top row.*/
+    OC_PL,
+    /*Top row, left column.*/
+    0,
+    /*Right column.*/
+    OC_PL|OC_PUL|OC_PU,
+    /*Right and left column.*/
+    OC_PU,
+    /*Top row, right column.*/
+    OC_PL,
+    /*Top row, right and left column.*/
+    0
+  };
+  /*Predictor fragments, left, up-left, up, up-right.*/
+  const oc_fragment *predfr[4];
+  /*The frame used for prediction for this fragment.*/
+  int                pred_frame;
+  /*The boundary condition flags.*/
+  int                bc;
+  /*DC predictor values: left, up-left, up, up-right, missing values
+     skipped.*/
+  int                p[4];
+  /*Predictor count.*/
+  int                np;
+  /*Which predictor constants to use.*/
+  int                pflags;
+  /*The predicted DC value.*/
+  int                ret;
+  int                i;
+  pred_frame=OC_FRAME_FOR_MODE[_frag->mbmode];
+  bc=(_x==0)+((_y==0)<<1)+((_x+1==_fplane->nhfrags)<<2);
+  predfr[0]=_frag-1;
+  predfr[1]=_frag-_fplane->nhfrags-1;
+  predfr[2]=predfr[1]+1;
+  predfr[3]=predfr[2]+1;
+  np=0;
+  pflags=0;
+  for(i=0;i<4;i++){
+    int pflag;
+    pflag=1<<i;
+    if((BC_MASK[bc]&pflag)&&predfr[i]->coded&&
+     OC_FRAME_FOR_MODE[predfr[i]->mbmode]==pred_frame){
+      p[np++]=predfr[i]->dc;
+      pflags|=pflag;
+    }
+  }
+  if(pflags==0)return _pred_last[pred_frame];
+  else{
+    ret=PRED_SCALE[pflags][0]*p[0];
+    /*LOOP VECTORIZES.*/
+    for(i=1;i<np;i++)ret+=PRED_SCALE[pflags][i]*p[i];
+    ret=OC_DIV_POW2(ret,PRED_SHIFT[pflags],PRED_RMASK[pflags]);
+  }
+  if((pflags&(OC_PL|OC_PUL|OC_PU))==(OC_PL|OC_PUL|OC_PU)){
+    if(abs(ret-p[2])>128)ret=p[2];
+    else if(abs(ret-p[0])>128)ret=p[0];
+    else if(abs(ret-p[1])>128)ret=p[1];
+  }
+  return ret;
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/huffdec.c
@@ -0,0 +1,279 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: huffdec.c 14493 2008-02-13 09:25:37Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <ogg/ogg.h>
+#include "huffdec.h"
+#include "decint.h"
+
+
+/*The ANSI offsetof macro is broken on some platforms (e.g., older DECs).*/
+#define _ogg_offsetof(_type,_field)\
+ ((size_t)((char *)&((_type *)0)->_field-(char *)0))
+
+/*The log_2 of the size of a lookup table is allowed to grow to relative to
+   the number of unique nodes it contains.
+  E.g., if OC_HUFF_SLUSH is 2, then at most 75% of the space in the tree is
+   wasted (each node will have an amortized cost of at most 20 bytes when using
+   4-byte pointers).
+  Larger numbers can decode tokens with fewer read operations, while smaller
+   numbers may save more space (requiring as little as 8 bytes amortized per
+   node, though there will be more nodes).
+  With a sample file:
+  32233473 read calls are required when no tree collapsing is done (100.0%).
+  19269269 read calls are required when OC_HUFF_SLUSH is 0 (59.8%).
+  11144969 read calls are required when OC_HUFF_SLUSH is 1 (34.6%).
+  10538563 read calls are required when OC_HUFF_SLUSH is 2 (32.7%).
+  10192578 read calls are required when OC_HUFF_SLUSH is 3 (31.6%).
+  Since a value of 1 gets us the vast majority of the speed-up with only a
+   small amount of wasted memory, this is what we use.*/
+#define OC_HUFF_SLUSH (1)
+
+
+/*Allocates a Huffman tree node that represents a subtree of depth _nbits.
+  _nbits: The depth of the subtree.
+          If this is 0, the node is a leaf node.
+          Otherwise 1<<_nbits pointers are allocated for children.
+  Return: The newly allocated and fully initialized Huffman tree node.*/
+static oc_huff_node *oc_huff_node_alloc(int _nbits){
+  oc_huff_node *ret;
+  size_t        size;
+  size=_ogg_offsetof(oc_huff_node,nodes);
+  if(_nbits>0)size+=sizeof(oc_huff_node *)*(1<<_nbits);
+  ret=_ogg_calloc(1,size);
+  ret->nbits=(unsigned char)_nbits;
+  return ret;
+}
+
+/*Frees a Huffman tree node allocated with oc_huf_node_alloc.
+  _node: The node to free.
+         This may be NULL.*/
+static void oc_huff_node_free(oc_huff_node *_node){
+  _ogg_free(_node);
+}
+
+/*Frees the memory used by a Huffman tree.
+  _node: The Huffman tree to free.
+         This may be NULL.*/
+static void oc_huff_tree_free(oc_huff_node *_node){
+  if(_node==NULL)return;
+  if(_node->nbits){
+    int nchildren;
+    int i;
+    int inext;
+    nchildren=1<<_node->nbits;
+    for(i=0;i<nchildren;i=inext){
+      inext=i+(_node->nodes[i]!=NULL?1<<_node->nbits-_node->nodes[i]->depth:1);
+      oc_huff_tree_free(_node->nodes[i]);
+    }
+  }
+  oc_huff_node_free(_node);
+}
+
+/*Unpacks a sub-tree from the given buffer.
+  _opb:    The buffer to unpack from.
+  _binode: The location to store a pointer to the sub-tree in.
+  _depth:  The current depth of the tree.
+           This is used to prevent infinite recursion.
+  Return: 0 on success, or a negative value on error.*/
+static int oc_huff_tree_unpack(oggpack_buffer *_opb,
+ oc_huff_node **_binode,int _depth){
+  oc_huff_node *binode;
+  long          bits;
+  /*Prevent infinite recursion.*/
+  if(++_depth>32)return TH_EBADHEADER;
+  if(theorapackB_read1(_opb,&bits)<0)return TH_EBADHEADER;
+  /*Read an internal node:*/
+  if(!bits){
+    int ret;
+    binode=oc_huff_node_alloc(1);
+    binode->depth=(unsigned char)(_depth>1);
+    ret=oc_huff_tree_unpack(_opb,binode->nodes,_depth);
+    if(ret>=0)ret=oc_huff_tree_unpack(_opb,binode->nodes+1,_depth);
+    if(ret<0){
+      oc_huff_tree_free(binode);
+      *_binode=NULL;
+      return ret;
+    }
+  }
+  /*Read a leaf node:*/
+  else{
+    if(theorapackB_read(_opb,OC_NDCT_TOKEN_BITS,&bits)<0)return TH_EBADHEADER;
+    binode=oc_huff_node_alloc(0);
+    binode->depth=(unsigned char)(_depth>1);
+    binode->token=(unsigned char)bits;
+  }
+  *_binode=binode;
+  return 0;
+}
+
+/*Finds the depth of shortest branch of the given sub-tree.
+  The tree must be binary.
+  _binode: The root of the given sub-tree.
+           _binode->nbits must be 0 or 1.
+  Return: The smallest depth of a leaf node in this sub-tree.
+          0 indicates this sub-tree is a leaf node.*/
+static int oc_huff_tree_mindepth(oc_huff_node *_binode){
+  int depth0;
+  int depth1;
+  if(_binode->nbits==0)return 0;
+  depth0=oc_huff_tree_mindepth(_binode->nodes[0]);
+  depth1=oc_huff_tree_mindepth(_binode->nodes[1]);
+  return OC_MINI(depth0,depth1)+1;
+}
+
+/*Finds the number of internal nodes at a given depth, plus the number of
+   leaves at that depth or shallower.
+  The tree must be binary.
+  _binode: The root of the given sub-tree.
+           _binode->nbits must be 0 or 1.
+  Return: The number of entries that would be contained in a jump table of the
+           given depth.*/
+static int oc_huff_tree_occupancy(oc_huff_node *_binode,int _depth){
+  if(_binode->nbits==0||_depth<=0)return 1;
+  else{
+    return oc_huff_tree_occupancy(_binode->nodes[0],_depth-1)+
+     oc_huff_tree_occupancy(_binode->nodes[1],_depth-1);
+  }
+}
+
+static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode);
+
+/*Fills the given nodes table with all the children in the sub-tree at the
+   given depth.
+  The nodes in the sub-tree with a depth less than that stored in the table
+   are freed.
+  The sub-tree must be binary and complete up until the given depth.
+  _nodes:  The nodes table to fill.
+  _binode: The root of the sub-tree to fill it with.
+           _binode->nbits must be 0 or 1.
+  _level:  The current level in the table.
+           0 indicates that the current node should be stored, regardless of
+            whether it is a leaf node or an internal node.
+  _depth:  The depth of the nodes to fill the table with, relative to their
+            parent.*/
+static void oc_huff_node_fill(oc_huff_node **_nodes,
+ oc_huff_node *_binode,int _level,int _depth){
+  if(_level<=0||_binode->nbits==0){
+    int i;
+    _binode->depth=(unsigned char)(_depth-_level);
+    _nodes[0]=oc_huff_tree_collapse(_binode);
+    for(i=1;i<1<<_level;i++)_nodes[i]=_nodes[0];
+  }
+  else{
+    _level--;
+    oc_huff_node_fill(_nodes,_binode->nodes[0],_level,_depth);
+    oc_huff_node_fill(_nodes+(1<<_level),_binode->nodes[1],_level,_depth);
+    oc_huff_node_free(_binode);
+  }
+}
+
+/*Finds the largest complete sub-tree rooted at the current node and collapses
+   it into a single node.
+  This procedure is then applied recursively to all the children of that node.
+  _binode: The root of the sub-tree to collapse.
+           _binode->nbits must be 0 or 1.
+  Return: The new root of the collapsed sub-tree.*/
+static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode){
+  oc_huff_node *root;
+  int           mindepth;
+  int           depth;
+  int           loccupancy;
+  int           occupancy;
+  depth=mindepth=oc_huff_tree_mindepth(_binode);
+  occupancy=1<<mindepth;
+  do{
+    loccupancy=occupancy;
+    occupancy=oc_huff_tree_occupancy(_binode,++depth);
+  }
+  while(occupancy>loccupancy&&occupancy>=1<<OC_MAXI(depth-OC_HUFF_SLUSH,0));
+  depth--;
+  if(depth<=1)return _binode;
+  root=oc_huff_node_alloc(depth);
+  root->depth=_binode->depth;
+  oc_huff_node_fill(root->nodes,_binode,depth,depth);
+  return root;
+}
+
+/*Makes a copy of the given Huffman tree.
+  _node: The Huffman tree to copy.
+  Return: The copy of the Huffman tree.*/
+static oc_huff_node *oc_huff_tree_copy(const oc_huff_node *_node){
+  oc_huff_node *ret;
+  ret=oc_huff_node_alloc(_node->nbits);
+  ret->depth=_node->depth;
+  if(_node->nbits){
+    int nchildren;
+    int i;
+    int inext;
+    nchildren=1<<_node->nbits;
+    for(i=0;i<nchildren;){
+      ret->nodes[i]=oc_huff_tree_copy(_node->nodes[i]);
+      inext=i+(1<<_node->nbits-ret->nodes[i]->depth);
+      while(++i<inext)ret->nodes[i]=ret->nodes[i-1];
+    }
+  }
+  else ret->token=_node->token;
+  return ret;
+}
+
+/*Unpacks a set of Huffman trees, and reduces them to a collapsed
+   representation.
+  _opb:   The buffer to unpack the trees from.
+  _nodes: The table to fill with the Huffman trees.
+  Return: 0 on success, or a negative value on error.*/
+int oc_huff_trees_unpack(oggpack_buffer *_opb,
+ oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
+  int i;
+  for(i=0;i<TH_NHUFFMAN_TABLES;i++){
+    int ret;
+    ret=oc_huff_tree_unpack(_opb,_nodes+i,0);
+    if(ret<0)return ret;
+    _nodes[i]=oc_huff_tree_collapse(_nodes[i]);
+  }
+  return 0;
+}
+
+/*Makes a copy of the given set of Huffman trees.
+  _dst: The array to store the copy in.
+  _src: The array of trees to copy.*/
+void oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
+ const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]){
+  int i;
+  for(i=0;i<TH_NHUFFMAN_TABLES;i++)_dst[i]=oc_huff_tree_copy(_src[i]);
+}
+
+/*Frees the memory used by a set of Huffman trees.
+  _nodes: The array of trees to free.*/
+void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
+  int i;
+  for(i=0;i<TH_NHUFFMAN_TABLES;i++)oc_huff_tree_free(_nodes[i]);
+}
+
+/*Unpacks a single token using the given Huffman tree.
+  _opb:  The buffer to unpack the token from.
+  _node: The tree to unpack the token with.
+  Return: The token value.*/
+int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node){
+  long bits;
+  while(_node->nbits!=0){
+    theorapackB_look(_opb,_node->nbits,&bits);
+    _node=_node->nodes[bits];
+    theorapackB_adv(_opb,_node->depth);
+  }
+  return _node->token;
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/huffdec.h
@@ -0,0 +1,91 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: huffdec.h 14359 2008-01-04 20:11:13Z tterribe $
+
+ ********************************************************************/
+
+#if !defined(_huffdec_H)
+# define _huffdec_H (1)
+# include "huffman.h"
+
+
+
+typedef struct oc_huff_node oc_huff_node;
+
+/*A node in the Huffman tree.
+  Instead of storing every branching in the tree, subtrees can be collapsed
+   into one node, with a table of size 1<<nbits pointing directly to its
+   descedents nbits levels down.
+  This allows more than one bit to be read at a time, and avoids following all
+   the intermediate branches with next to no increased code complexity once
+   the collapsed tree has been built.
+  We do _not_ require that a subtree be complete to be collapsed, but instead
+   store duplicate pointers in the table, and record the actual depth of the
+   node below its parent.
+  This tells us the number of bits to advance the stream after reaching it.
+
+  This turns out to be equivalent to the method described in \cite{Hash95},
+   without the requirement that codewords be sorted by length.
+  If the codewords were sorted by length (so-called ``canonical-codes''), they
+   could be decoded much faster via either Lindell and Moffat's approach or
+   Hashemian's Condensed Huffman Code approach, the latter of which has an
+   extremely small memory footprint.
+  We can't use Choueka et al.'s finite state machine approach, which is
+   extremely fast, because we can't allow multiple symbols to be output at a
+   time; the codebook can and does change between symbols.
+  It also has very large memory requirements, which impairs cache coherency.
+
+  @ARTICLE{Hash95,
+    author="Reza Hashemian",
+    title="Memory Efficient and High-Speed Search {Huffman} Coding",
+    journal="{IEEE} Transactions on Communications",
+    volume=43,
+    number=10,
+    pages="2576--2581",
+    month=Oct,
+    year=1995
+  }*/
+struct oc_huff_node{
+  /*The number of bits of the code needed to descend through this node.
+    0 indicates a leaf node.
+    Otherwise there are 1<<nbits nodes in the nodes table, which can be
+     indexed by reading nbits bits from the stream.*/
+  unsigned char  nbits;
+  /*The value of a token stored in a leaf node.
+    The value in non-leaf nodes is undefined.*/
+  unsigned char  token;
+  /*The depth of the current node, relative to its parent in the collapsed
+     tree.
+    This can be less than its parent's nbits value, in which case there are
+     1<<nbits-depth copies of this node in the table, and the bitstream should
+     only be advanced depth bits after reaching this node.*/
+  unsigned char  depth;
+  /*The table of child nodes.
+    The ACTUAL size of this array is 1<<nbits, despite what the declaration
+     below claims.
+    The exception is that for leaf nodes the size is 0.*/
+  oc_huff_node  *nodes[1];
+};
+
+
+
+int oc_huff_trees_unpack(oggpack_buffer *_opb,
+ oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
+void oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
+ const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]);
+void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
+int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node);
+
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/huffman.h
@@ -0,0 +1,70 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: huffman.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+#if !defined(_huffman_H)
+# define _hufffman_H (1)
+# include "theora/codec.h"
+# include "ocintrin.h"
+
+/*The range of valid quantized DCT coefficient values.
+  VP3 used 511 in the encoder, but the bitstream is capable of 580.*/
+#define OC_DCT_VAL_RANGE         (580)
+
+#define OC_NDCT_TOKEN_BITS       (5)
+
+#define OC_DCT_EOB1_TOKEN        (0)
+#define OC_DCT_EOB2_TOKEN        (1)
+#define OC_DCT_EOB3_TOKEN        (2)
+#define OC_DCT_REPEAT_RUN0_TOKEN (3)
+#define OC_DCT_REPEAT_RUN1_TOKEN (4)
+#define OC_DCT_REPEAT_RUN2_TOKEN (5)
+#define OC_DCT_REPEAT_RUN3_TOKEN (6)
+
+#define OC_DCT_SHORT_ZRL_TOKEN   (7)
+#define OC_DCT_ZRL_TOKEN         (8)
+
+#define OC_ONE_TOKEN             (9)
+#define OC_MINUS_ONE_TOKEN       (10)
+#define OC_TWO_TOKEN             (11)
+#define OC_MINUS_TWO_TOKEN       (12)
+
+#define OC_DCT_VAL_CAT2          (13)
+#define OC_DCT_VAL_CAT3          (17)
+#define OC_DCT_VAL_CAT4          (18)
+#define OC_DCT_VAL_CAT5          (19)
+#define OC_DCT_VAL_CAT6          (20)
+#define OC_DCT_VAL_CAT7          (21)
+#define OC_DCT_VAL_CAT8          (22)
+
+#define OC_DCT_RUN_CAT1A         (23)
+#define OC_DCT_RUN_CAT1B         (28)
+#define OC_DCT_RUN_CAT1C         (29)
+#define OC_DCT_RUN_CAT2A         (30)
+#define OC_DCT_RUN_CAT2B         (31)
+
+#define OC_NDCT_EOB_TOKEN_MAX    (7)
+#define OC_NDCT_ZRL_TOKEN_MAX    (9)
+#define OC_NDCT_VAL_MAX          (23)
+#define OC_NDCT_VAL_CAT1_MAX     (13)
+#define OC_NDCT_VAL_CAT2_MAX     (17)
+#define OC_NDCT_VAL_CAT2_SIZE    (OC_NDCT_VAL_CAT2_MAX-OC_DCT_VAL_CAT2)
+#define OC_NDCT_RUN_MAX          (32)
+#define OC_NDCT_RUN_CAT1A_MAX    (28)
+
+extern const int OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS];
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/idct.c
@@ -0,0 +1,270 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: idct.c 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+#include <string.h>
+#include <ogg/ogg.h>
+#include "dct.h"
+#include "idct.h"
+
+/*Performs an inverse 8 point Type-II DCT transform.
+  The output is scaled by a factor of 2 relative to the orthonormal version of
+   the transform.
+  _y: The buffer to store the result in.
+      Data will be placed in every 8th entry (e.g., in a column of an 8x8
+       block).
+  _x: The input coefficients.
+      The first 8 entries are used (e.g., from a row of an 8x8 block).*/
+static void idct8(ogg_int16_t *_y,const ogg_int16_t _x[8]){
+  ogg_int32_t t[8];
+  ogg_int32_t r;
+  /*Stage 1:*/
+  /*0-1 butterfly.*/
+  t[0]=OC_C4S4*(ogg_int16_t)(_x[0]+_x[4])>>16;
+  t[1]=OC_C4S4*(ogg_int16_t)(_x[0]-_x[4])>>16;
+  /*2-3 rotation by 6pi/16.*/
+  t[2]=(OC_C6S2*_x[2]>>16)-(OC_C2S6*_x[6]>>16);
+  t[3]=(OC_C2S6*_x[2]>>16)+(OC_C6S2*_x[6]>>16);
+  /*4-7 rotation by 7pi/16.*/
+  t[4]=(OC_C7S1*_x[1]>>16)-(OC_C1S7*_x[7]>>16);
+  /*5-6 rotation by 3pi/16.*/
+  t[5]=(OC_C3S5*_x[5]>>16)-(OC_C5S3*_x[3]>>16);
+  t[6]=(OC_C5S3*_x[5]>>16)+(OC_C3S5*_x[3]>>16);
+  t[7]=(OC_C1S7*_x[1]>>16)+(OC_C7S1*_x[7]>>16);
+  /*Stage 2:*/
+  /*4-5 butterfly.*/
+  r=t[4]+t[5];
+  t[5]=OC_C4S4*(ogg_int16_t)(t[4]-t[5])>>16;
+  t[4]=r;
+  /*7-6 butterfly.*/
+  r=t[7]+t[6];
+  t[6]=OC_C4S4*(ogg_int16_t)(t[7]-t[6])>>16;
+  t[7]=r;
+  /*Stage 3:*/
+  /*0-3 butterfly.*/
+  r=t[0]+t[3];
+  t[3]=t[0]-t[3];
+  t[0]=r;
+  /*1-2 butterfly.*/
+  r=t[1]+t[2];
+  t[2]=t[1]-t[2];
+  t[1]=r;
+  /*6-5 butterfly.*/
+  r=t[6]+t[5];
+  t[5]=t[6]-t[5];
+  t[6]=r;
+  /*Stage 4:*/
+  /*0-7 butterfly.*/
+  _y[0<<3]=(ogg_int16_t)(t[0]+t[7]);
+  /*1-6 butterfly.*/
+  _y[1<<3]=(ogg_int16_t)(t[1]+t[6]);
+  /*2-5 butterfly.*/
+  _y[2<<3]=(ogg_int16_t)(t[2]+t[5]);
+  /*3-4 butterfly.*/
+  _y[3<<3]=(ogg_int16_t)(t[3]+t[4]);
+  _y[4<<3]=(ogg_int16_t)(t[3]-t[4]);
+  _y[5<<3]=(ogg_int16_t)(t[2]-t[5]);
+  _y[6<<3]=(ogg_int16_t)(t[1]-t[6]);
+  _y[7<<3]=(ogg_int16_t)(t[0]-t[7]);
+}
+
+/*Performs an inverse 8 point Type-II DCT transform.
+  The output is scaled by a factor of 2 relative to the orthonormal version of
+   the transform.
+  _y: The buffer to store the result in.
+      Data will be placed in every 8th entry (e.g., in a column of an 8x8
+       block).
+  _x: The input coefficients.
+      Only the first 4 entries are used.
+      The other 4 are assumed to be 0.*/
+static void idct8_4(ogg_int16_t *_y,const ogg_int16_t _x[8]){
+  ogg_int32_t t[8];
+  ogg_int32_t r;
+  /*Stage 1:*/
+  t[0]=OC_C4S4*_x[0]>>16;
+  t[2]=OC_C6S2*_x[2]>>16;
+  t[3]=OC_C2S6*_x[2]>>16;
+  t[4]=OC_C7S1*_x[1]>>16;
+  t[5]=-(OC_C5S3*_x[3]>>16);
+  t[6]=OC_C3S5*_x[3]>>16;
+  t[7]=OC_C1S7*_x[1]>>16;
+  /*Stage 2:*/
+  r=t[4]+t[5];
+  t[5]=OC_C4S4*(ogg_int16_t)(t[4]-t[5])>>16;
+  t[4]=r;
+  r=t[7]+t[6];
+  t[6]=OC_C4S4*(ogg_int16_t)(t[7]-t[6])>>16;
+  t[7]=r;
+  /*Stage 3:*/
+  t[1]=t[0]+t[2];
+  t[2]=t[0]-t[2];
+  r=t[0]+t[3];
+  t[3]=t[0]-t[3];
+  t[0]=r;
+  r=t[6]+t[5];
+  t[5]=t[6]-t[5];
+  t[6]=r;
+  /*Stage 4:*/
+  _y[0<<3]=(ogg_int16_t)(t[0]+t[7]);
+  _y[1<<3]=(ogg_int16_t)(t[1]+t[6]);
+  _y[2<<3]=(ogg_int16_t)(t[2]+t[5]);
+  _y[3<<3]=(ogg_int16_t)(t[3]+t[4]);
+  _y[4<<3]=(ogg_int16_t)(t[3]-t[4]);
+  _y[5<<3]=(ogg_int16_t)(t[2]-t[5]);
+  _y[6<<3]=(ogg_int16_t)(t[1]-t[6]);
+  _y[7<<3]=(ogg_int16_t)(t[0]-t[7]);
+}
+
+/*Performs an inverse 8 point Type-II DCT transform.
+  The output is scaled by a factor of 2 relative to the orthonormal version of
+   the transform.
+  _y: The buffer to store the result in.
+      Data will be placed in every 8th entry (e.g., in a column of an 8x8
+       block).
+  _x: The input coefficients.
+      Only the first 3 entries are used.
+      The other 5 are assumed to be 0.*/
+static void idct8_3(ogg_int16_t *_y,const ogg_int16_t _x[8]){
+  ogg_int32_t t[8];
+  ogg_int32_t r;
+  /*Stage 1:*/
+  t[0]=OC_C4S4*_x[0]>>16;
+  t[2]=OC_C6S2*_x[2]>>16;
+  t[3]=OC_C2S6*_x[2]>>16;
+  t[4]=OC_C7S1*_x[1]>>16;
+  t[7]=OC_C1S7*_x[1]>>16;
+  /*Stage 2:*/
+  t[5]=OC_C4S4*t[4]>>16;
+  t[6]=OC_C4S4*t[7]>>16;
+  /*Stage 3:*/
+  t[1]=t[0]+t[2];
+  t[2]=t[0]-t[2];
+  r=t[0]+t[3];
+  t[3]=t[0]-t[3];
+  t[0]=r;
+  r=t[6]+t[5];
+  t[5]=t[6]-t[5];
+  t[6]=r;
+  /*Stage 4:*/
+  _y[0<<3]=(ogg_int16_t)(t[0]+t[7]);
+  _y[1<<3]=(ogg_int16_t)(t[1]+t[6]);
+  _y[2<<3]=(ogg_int16_t)(t[2]+t[5]);
+  _y[3<<3]=(ogg_int16_t)(t[3]+t[4]);
+  _y[4<<3]=(ogg_int16_t)(t[3]-t[4]);
+  _y[5<<3]=(ogg_int16_t)(t[2]-t[5]);
+  _y[6<<3]=(ogg_int16_t)(t[1]-t[6]);
+  _y[7<<3]=(ogg_int16_t)(t[0]-t[7]);
+}
+
+
+/*Performs an inverse 8 point Type-II DCT transform.
+  The output is scaled by a factor of 2 relative to the orthonormal version of
+   the transform.
+  _y: The buffer to store the result in.
+      Data will be placed in every 8th entry (e.g., in a column of an 8x8
+       block).
+  _x: The input coefficients.
+      Only the first 2 entries are used.
+      The other 6 are assumed to be 0.*/
+static void idct8_2(ogg_int16_t *_y,const ogg_int16_t _x[8]){
+  ogg_int32_t t[8];
+  ogg_int32_t r;
+  /*Stage 1:*/
+  t[0]=OC_C4S4*_x[0]>>16;
+  t[4]=OC_C7S1*_x[1]>>16;
+  t[7]=OC_C1S7*_x[1]>>16;
+  /*Stage 2:*/
+  t[5]=OC_C4S4*t[4]>>16;
+  t[6]=OC_C4S4*t[7]>>16;
+  /*Stage 3:*/
+  r=t[6]+t[5];
+  t[5]=t[6]-t[5];
+  t[6]=r;
+  /*Stage 4:*/
+  _y[0<<3]=(ogg_int16_t)(t[0]+t[7]);
+  _y[1<<3]=(ogg_int16_t)(t[0]+t[6]);
+  _y[2<<3]=(ogg_int16_t)(t[0]+t[5]);
+  _y[3<<3]=(ogg_int16_t)(t[0]+t[4]);
+  _y[4<<3]=(ogg_int16_t)(t[0]-t[4]);
+  _y[5<<3]=(ogg_int16_t)(t[0]-t[5]);
+  _y[6<<3]=(ogg_int16_t)(t[0]-t[6]);
+  _y[7<<3]=(ogg_int16_t)(t[0]-t[7]);
+}
+
+
+/*Performs an inverse 8 point Type-II DCT transform.
+  The output is scaled by a factor of 2 relative to the orthonormal version of
+   the transform.
+  _y: The buffer to store the result in.
+      Data will be placed in every 8th entry (e.g., in a column of an 8x8
+       block).
+  _x: The input coefficients.
+      Only the first entry is used.
+      The other 7 are assumed to be 0.*/
+static void idct8_1(ogg_int16_t *_y,const ogg_int16_t _x[1]){
+  _y[0<<3]=_y[1<<3]=_y[2<<3]=_y[3<<3]=
+   _y[4<<3]=_y[5<<3]=_y[6<<3]=_y[7<<3]=(ogg_int16_t)(OC_C4S4*_x[0]>>16);
+}
+
+/*Performs an inverse 8x8 Type-II DCT transform.
+  The input is assumed to be scaled by a factor of 4 relative to orthonormal
+   version of the transform.
+  _y: The buffer to store the result in.
+      This may be the same as _x.
+  _x: The input coefficients. */
+void oc_idct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
+  const ogg_int16_t *in;
+  ogg_int16_t       *end;
+  ogg_int16_t       *out;
+  ogg_int16_t        w[64];
+  /*Transform rows of x into columns of w.*/
+  for(in=_x,out=w,end=out+8;out<end;in+=8,out++)idct8(out,in);
+  /*Transform rows of w into columns of y.*/
+  for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8(out,in);
+  /*Adjust for scale factor.*/
+  for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4);
+}
+
+/*Performs an inverse 8x8 Type-II DCT transform.
+  The input is assumed to be scaled by a factor of 4 relative to orthonormal
+   version of the transform.
+  All coefficients but the first 10 in zig-zag scan order are assumed to be 0:
+   x  x  x  x  0  0  0  0
+   x  x  x  0  0  0  0  0
+   x  x  0  0  0  0  0  0
+   x  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+  _y: The buffer to store the result in.
+      This may be the same as _x.
+  _x: The input coefficients. */
+void oc_idct8x8_10_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
+  const ogg_int16_t *in;
+  ogg_int16_t       *end;
+  ogg_int16_t       *out;
+  ogg_int16_t        w[64];
+  /*Transform rows of x into columns of w.*/
+  idct8_4(w,_x);
+  idct8_3(w+1,_x+8);
+  idct8_2(w+2,_x+16);
+  idct8_1(w+3,_x+24);
+  /*Transform rows of w into columns of y.*/
+  for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8_4(out,in);
+  /*Adjust for scale factor.*/
+  for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4);
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/idct.h
@@ -0,0 +1,26 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: idct.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+/*Inverse DCT transforms.*/
+#include <ogg/ogg.h>
+#if !defined(_idct_H)
+# define _idct_H (1)
+
+void oc_idct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
+void oc_idct8x8_10_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/info.c
@@ -0,0 +1,123 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: info.c 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "../internal.h"
+
+
+
+/*This is more or less the same as strncasecmp, but that doesn't exist
+   everywhere, and this is a fairly trivial function, so we include it.
+  Note: We take advantage of the fact that we know _n is less than or equal to
+   the length of at least one of the strings.*/
+static int oc_tagcompare(const char *_s1,const char *_s2,int _n){
+  int c;
+  for(c=0;c<_n;c++){
+    if(toupper(_s1[c])!=toupper(_s2[c]))return !0;
+  }
+  return _s1[c]!='=';
+}
+
+
+
+void th_info_init(th_info *_info){
+  memset(_info,0,sizeof(*_info));
+  _info->version_major=TH_VERSION_MAJOR;
+  _info->version_minor=TH_VERSION_MINOR;
+  _info->version_subminor=TH_VERSION_SUB;
+  _info->keyframe_granule_shift=6;
+}
+
+void th_info_clear(th_info *_info){
+  memset(_info,0,sizeof(*_info));
+}
+
+
+
+void th_comment_init(th_comment *_tc){
+  memset(_tc,0,sizeof(*_tc));
+}
+
+void th_comment_add(th_comment *_tc,char *_comment){
+  int comment_len;
+  _tc->user_comments=_ogg_realloc(_tc->user_comments,
+   (_tc->comments+2)*sizeof(*_tc->user_comments));
+  _tc->comment_lengths=_ogg_realloc(_tc->comment_lengths,
+   (_tc->comments+2)*sizeof(*_tc->comment_lengths));
+  comment_len=strlen(_comment);
+  _tc->comment_lengths[_tc->comments]=comment_len;
+  _tc->user_comments[_tc->comments]=_ogg_malloc(comment_len+1);
+  memcpy(_tc->user_comments[_tc->comments],_comment,comment_len+1);
+  _tc->comments++;
+  _tc->user_comments[_tc->comments]=NULL;
+}
+
+void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){
+  char *comment;
+  int   tag_len;
+  int   val_len;
+  tag_len=strlen(_tag);
+  val_len=strlen(_val);
+  /*+2 for '=' and '\0'.*/
+  comment=_ogg_malloc(tag_len+val_len+2);
+  memcpy(comment,_tag,tag_len);
+  comment[tag_len]='=';
+  memcpy(comment+tag_len+1,_val,val_len+1);
+  th_comment_add(_tc,comment);
+  _ogg_free(comment);
+}
+
+char *th_comment_query(th_comment *_tc,char *_tag,int _count){
+  long i;
+  int  found;
+  int  tag_len;
+  tag_len=strlen(_tag);
+  found=0;
+  for(i=0;i<_tc->comments;i++){
+    if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len)){
+      /*We return a pointer to the data, not a copy.*/
+      if(_count==found++)return _tc->user_comments[i]+tag_len+1;
+    }
+  }
+  /*Didn't find anything.*/
+  return NULL;
+}
+
+int th_comment_query_count(th_comment *_tc,char *_tag){
+  long i;
+  int  tag_len;
+  int  count;
+  tag_len=strlen(_tag);
+  count=0;
+  for(i=0;i<_tc->comments;i++){
+    if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len))count++;
+  }
+  return count;
+}
+
+void th_comment_clear(th_comment *_tc){
+  if(_tc!=NULL){
+    long i;
+    for(i=0;i<_tc->comments;i++)_ogg_free(_tc->user_comments[i]);
+    _ogg_free(_tc->user_comments);
+    _ogg_free(_tc->comment_lengths);
+    _ogg_free(_tc->vendor);
+    memset(_tc,0,sizeof(*_tc));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/internal.c
@@ -0,0 +1,383 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: internal.c 14385 2008-01-09 19:53:18Z giles $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include "../internal.h"
+#include "idct.h"
+
+
+
+/*A map from the index in the zig zag scan to the coefficient number in a
+   block.
+  All zig zag indices beyond 63 are sent to coefficient 64, so that zero runs
+   past the end of a block in bogus streams get mapped to a known location.*/
+const int OC_FZIG_ZAG[128]={
+   0, 1, 8,16, 9, 2, 3,10,
+  17,24,32,25,18,11, 4, 5,
+  12,19,26,33,40,48,41,34,
+  27,20,13, 6, 7,14,21,28,
+  35,42,49,56,57,50,43,36,
+  29,22,15,23,30,37,44,51,
+  58,59,52,45,38,31,39,46,
+  53,60,61,54,47,55,62,63,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64,
+  64,64,64,64,64,64,64,64
+};
+
+/*A map from the coefficient number in a block to its index in the zig zag
+   scan.*/
+const int OC_IZIG_ZAG[64]={
+   0, 1, 5, 6,14,15,27,28,
+   2, 4, 7,13,16,26,29,42,
+   3, 8,12,17,25,30,41,43,
+   9,11,18,24,31,40,44,53,
+  10,19,23,32,39,45,52,54,
+  20,22,33,38,46,51,55,60,
+  21,34,37,47,50,56,59,61,
+  35,36,48,49,57,58,62,63
+};
+
+/*The predictor frame to use for each macro block mode.*/
+const int OC_FRAME_FOR_MODE[8]={
+  /*OC_MODE_INTER_NOMV*/
+  OC_FRAME_PREV,
+  /*OC_MODE_INTRA*/
+  OC_FRAME_SELF,
+  /*OC_MODE_INTER_MV*/
+  OC_FRAME_PREV,
+  /*OC_MODE_INTER_MV_LAST*/
+  OC_FRAME_PREV,
+  /*OC_MODE_INTER_MV_LAST2*/
+  OC_FRAME_PREV,
+  /*OC_MODE_GOLDEN*/
+  OC_FRAME_GOLD,
+  /*OC_MODE_GOLDEN_MV*/
+  OC_FRAME_GOLD,
+  /*OC_MODE_INTER_MV_FOUR*/
+  OC_FRAME_PREV,
+};
+
+/*A map from physical macro block ordering to bitstream macro block
+   ordering within a super block.*/
+const int OC_MB_MAP[2][2]={{0,3},{1,2}};
+
+/*A list of the indices in the oc_mb.map array that can be valid for each of
+   the various chroma decimation types.*/
+const int OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]={
+  {0,1,2,3,4,8},
+  {0,1,2,3,4,5,8,9},
+  {0,1,2,3,4,6,8,10},
+  {0,1,2,3,4,5,6,7,8,9,10,11}
+};
+
+/*The number of indices in the oc_mb.map array that can be valid for each of
+   the various chroma decimation types.*/
+const int OC_MB_MAP_NIDXS[TH_PF_NFORMATS]={6,8,8,12};
+
+/*The number of extra bits that are coded with each of the DCT tokens.
+  Each DCT token has some fixed number of additional bits (possibly 0) stored
+   after the token itself, containing, for example, coefficient magnitude,
+   sign bits, etc.*/
+const int OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS]={
+  0,0,0,2,3,4,12,3,6,
+  0,0,0,0,
+  1,1,1,1,2,3,4,5,6,10,
+  1,1,1,1,1,3,4,
+  2,3
+};
+
+
+
+int oc_ilog(unsigned _v){
+  int ret;
+  for(ret=0;_v;ret++)_v>>=1;
+  return ret;
+}
+
+
+
+/*Determines the number of blocks or coefficients to be skipped for a given
+   token value.
+  _token:      The token value to skip.
+  _extra_bits: The extra bits attached to this token.
+  Return: A positive value indicates that number of coefficients are to be
+           skipped in the current block.
+          Otherwise, the negative of the return value indicates that number of
+           blocks are to be ended.*/
+typedef int (*oc_token_skip_func)(int _token,int _extra_bits);
+
+/*Handles the simple end of block tokens.*/
+static int oc_token_skip_eob(int _token,int _extra_bits){
+  static const int NBLOCKS_ADJUST[OC_NDCT_EOB_TOKEN_MAX]={1,2,3,4,8,16,0};
+  return -_extra_bits-NBLOCKS_ADJUST[_token];
+}
+
+/*The last EOB token has a special case, where an EOB run of size zero ends all
+   the remaining blocks in the frame.*/
+static int oc_token_skip_eob6(int _token,int _extra_bits){
+  if(!_extra_bits)return -INT_MAX;
+  return -_extra_bits;
+}
+
+/*Handles the pure zero run tokens.*/
+static int oc_token_skip_zrl(int _token,int _extra_bits){
+  return _extra_bits+1;
+}
+
+/*Handles a normal coefficient value token.*/
+static int oc_token_skip_val(void){
+  return 1;
+}
+
+/*Handles a category 1A zero run/coefficient value combo token.*/
+static int oc_token_skip_run_cat1a(int _token){
+  return _token-OC_DCT_RUN_CAT1A+2;
+}
+
+/*Handles category 1b and 2 zero run/coefficient value combo tokens.*/
+static int oc_token_skip_run(int _token,int _extra_bits){
+  static const int NCOEFFS_ADJUST[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    7,11,2,3
+  };
+  static const int NCOEFFS_MASK[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
+    3,7,0,1
+  };
+  _token-=OC_DCT_RUN_CAT1B;
+  return (_extra_bits&NCOEFFS_MASK[_token])+NCOEFFS_ADJUST[_token];
+}
+
+/*A jump table for computing the number of coefficients or blocks to skip for
+   a given token value.
+  This reduces all the conditional branches, etc., needed to parse these token
+   values down to one indirect jump.*/
+static const oc_token_skip_func OC_TOKEN_SKIP_TABLE[TH_NDCT_TOKENS]={
+  oc_token_skip_eob,
+  oc_token_skip_eob,
+  oc_token_skip_eob,
+  oc_token_skip_eob,
+  oc_token_skip_eob,
+  oc_token_skip_eob,
+  oc_token_skip_eob6,
+  oc_token_skip_zrl,
+  oc_token_skip_zrl,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_val,
+  (oc_token_skip_func)oc_token_skip_run_cat1a,
+  (oc_token_skip_func)oc_token_skip_run_cat1a,
+  (oc_token_skip_func)oc_token_skip_run_cat1a,
+  (oc_token_skip_func)oc_token_skip_run_cat1a,
+  (oc_token_skip_func)oc_token_skip_run_cat1a,
+  oc_token_skip_run,
+  oc_token_skip_run,
+  oc_token_skip_run,
+  oc_token_skip_run
+};
+
+/*Determines the number of blocks or coefficients to be skipped for a given
+   token value.
+  _token:      The token value to skip.
+  _extra_bits: The extra bits attached to this token.
+  Return: A positive value indicates that number of coefficients are to be
+           skipped in the current block.
+          Otherwise, the negative of the return value indicates that number of
+           blocks are to be ended.
+          0 will never be returned, so that at least one coefficient in one
+           block will always be decoded for every token.*/
+int oc_dct_token_skip(int _token,int _extra_bits){
+  return (*OC_TOKEN_SKIP_TABLE[_token])(_token,_extra_bits);
+}
+
+
+/*The function used to fill in the chroma plane motion vectors for a macro
+   block when 4 different motion vectors are specified in the luma plane.
+  This version is for use with chroma decimated in the X and Y directions.
+  _cbmvs: The chroma block-level motion vectors to fill in.
+  _lbmvs: The luma block-level motion vectors.*/
+static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
+  int dx;
+  int dy;
+  dx=_lbmvs[0][0]+_lbmvs[1][0]+_lbmvs[2][0]+_lbmvs[3][0];
+  dy=_lbmvs[0][1]+_lbmvs[1][1]+_lbmvs[2][1]+_lbmvs[3][1];
+  _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,2,2);
+  _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,2,2);
+}
+
+/*The function used to fill in the chroma plane motion vectors for a macro
+   block when 4 different motion vectors are specified in the luma plane.
+  This version is for use with chroma decimated in the Y direction.
+  _cbmvs: The chroma block-level motion vectors to fill in.
+  _lbmvs: The luma block-level motion vectors.*/
+static void oc_set_chroma_mvs01(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
+  int dx;
+  int dy;
+  dx=_lbmvs[0][0]+_lbmvs[2][0];
+  dy=_lbmvs[0][1]+_lbmvs[2][1];
+  _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
+  _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
+  dx=_lbmvs[1][0]+_lbmvs[3][0];
+  dy=_lbmvs[1][1]+_lbmvs[3][1];
+  _cbmvs[1][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
+  _cbmvs[1][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
+}
+
+/*The function used to fill in the chroma plane motion vectors for a macro
+   block when 4 different motion vectors are specified in the luma plane.
+  This version is for use with chroma decimated in the X direction.
+  _cbmvs: The chroma block-level motion vectors to fill in.
+  _lbmvs: The luma block-level motion vectors.*/
+static void oc_set_chroma_mvs10(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
+  int dx;
+  int dy;
+  dx=_lbmvs[0][0]+_lbmvs[1][0];
+  dy=_lbmvs[0][1]+_lbmvs[1][1];
+  _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
+  _cbmvs[0][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
+  dx=_lbmvs[2][0]+_lbmvs[3][0];
+  dy=_lbmvs[2][1]+_lbmvs[3][1];
+  _cbmvs[2][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
+  _cbmvs[2][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
+}
+
+/*The function used to fill in the chroma plane motion vectors for a macro
+   block when 4 different motion vectors are specified in the luma plane.
+  This version is for use with no chroma decimation.
+  _cbmvs: The chroma block-level motion vectors to fill in.
+  _lmbmv: The luma macro-block level motion vector to fill in for use in
+           prediction.
+  _lbmvs: The luma block-level motion vectors.*/
+static void oc_set_chroma_mvs11(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
+  memcpy(_cbmvs,_lbmvs,4*sizeof(_lbmvs[0]));
+}
+
+/*A table of functions used to fill in the chroma plane motion vectors for a
+   macro block when 4 different motion vectors are specified in the luma
+   plane.*/
+const oc_set_chroma_mvs_func OC_SET_CHROMA_MVS_TABLE[TH_PF_NFORMATS]={
+  (oc_set_chroma_mvs_func)oc_set_chroma_mvs00,
+  (oc_set_chroma_mvs_func)oc_set_chroma_mvs01,
+  (oc_set_chroma_mvs_func)oc_set_chroma_mvs10,
+  (oc_set_chroma_mvs_func)oc_set_chroma_mvs11
+};
+
+
+
+void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz){
+  size_t  rowsz;
+  size_t  colsz;
+  size_t  datsz;
+  char   *ret;
+  colsz=_height*sizeof(void *);
+  rowsz=_sz*_width;
+  datsz=rowsz*_height;
+  /*Alloc array and row pointers.*/
+  ret=(char *)_ogg_malloc(datsz+colsz);
+  /*Initialize the array.*/
+  if(ret!=NULL){
+    size_t   i;
+    void   **p;
+    char    *datptr;
+    p=(void **)ret;
+    i=_height;
+    for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
+  }
+  return (void **)ret;
+}
+
+void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz){
+  size_t  colsz;
+  size_t  rowsz;
+  size_t  datsz;
+  char   *ret;
+  colsz=_height*sizeof(void *);
+  rowsz=_sz*_width;
+  datsz=rowsz*_height;
+  /*Alloc array and row pointers.*/
+  ret=(char *)_ogg_calloc(datsz+colsz,1);
+  /*Initialize the array.*/
+  if(ret!=NULL){
+    size_t   i;
+    void   **p;
+    char    *datptr;
+    p=(void **)ret;
+    i=_height;
+    for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
+  }
+  return (void **)ret;
+}
+
+void oc_free_2d(void *_ptr){
+  _ogg_free(_ptr);
+}
+
+/*Fills in a Y'CbCr buffer with a pointer to the image data in the first
+   buffer, but with the opposite vertical orientation.
+  _dst: The destination buffer.
+        This can be the same as _src.
+  _src: The source buffer.*/
+void oc_ycbcr_buffer_flip(th_ycbcr_buffer _dst,
+ const th_ycbcr_buffer _src){
+  int pli;
+  for(pli=0;pli<3;pli++){
+    _dst[pli].width=_src[pli].width;
+    _dst[pli].height=_src[pli].height;
+    _dst[pli].stride=-_src[pli].stride;
+    _dst[pli].data=_src[pli].data+(1-_dst[pli].height)*_dst[pli].stride;
+  }
+}
+
+const char *th_version_string(void){
+  return OC_VENDOR_STRING;
+}
+
+ogg_uint32_t th_version_number(void){
+  return (TH_VERSION_MAJOR<<16)+(TH_VERSION_MINOR<<8)+(TH_VERSION_SUB);
+}
+
+/*Determines the packet type.
+  Note that this correctly interprets a 0-byte packet as a video data packet.
+  Return: 1 for a header packet, 0 for a data packet.*/
+int th_packet_isheader(ogg_packet *_op){
+  return _op->bytes>0?_op->packet[0]>>7:0;
+}
+
+/*Determines the frame type of a video data packet.
+  Note that this correctly interprets a 0-byte packet as a delta frame.
+  Return: 1 for a key frame, 0 for a delta frame, and -1 for a header
+           packet.*/
+int th_packet_iskeyframe(ogg_packet *_op){
+  return _op->bytes<=0?0:_op->packet[0]&0x80?-1:!(_op->packet[0]&0x40);
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/ocintrin.h
@@ -0,0 +1,88 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: ocintrin.h 13884 2007-09-22 08:38:10Z giles $
+
+ ********************************************************************/
+
+/*Some common macros for potential platform-specific optimization.*/
+#include <math.h>
+#if !defined(_ocintrin_H)
+# define _ocintrin_H (1)
+
+/*Some specific platforms may have optimized intrinsic or inline assembly
+   versions of these functions which can substantially improve performance.
+  We define macros for them to allow easy incorporation of these non-ANSI
+   features.*/
+
+/*Branchless, but not correct for differences larger than INT_MAX.
+static int oc_mini(int _a,int _b){
+  int ambsign;
+  ambsign=_a-_b>>sizeof(int)*8-1;
+  return (_a&~ambsign)+(_b&ambsign);
+}*/
+
+
+#define OC_MAXI(_a,_b)      ((_a)<(_b)?(_b):(_a))
+#define OC_MINI(_a,_b)      ((_a)>(_b)?(_b):(_a))
+/*Clamps an integer into the given range.
+  If _a>_c, then the lower bound _a is respected over the upper bound _c (this
+   behavior is required to meet our documented API behavior).
+  _a: The lower bound.
+  _b: The value to clamp.
+  _c: The upper boud.*/
+#define OC_CLAMPI(_a,_b,_c) (OC_MAXI(_a,OC_MINI(_b,_c)))
+#define OC_CLAMP255(_x)     ((unsigned char)((((_x)<0)-1)&((_x)|-((_x)>255))))
+/*Divides an integer by a power of two, truncating towards 0.
+  _dividend: The integer to divide.
+  _shift:    The non-negative power of two to divide by.
+  _rmask:    (1<<_shift)-1*/
+#define OC_DIV_POW2(_dividend,_shift,_rmask)\
+  ((_dividend)+(((_dividend)>>sizeof(_dividend)*8-1)&(_rmask))>>(_shift))
+/*Divides _x by 65536, truncating towards 0.*/
+#define OC_DIV2_16(_x) OC_DIV_POW2(_x,16,0xFFFF)
+/*Divides _x by 2, truncating towards 0.*/
+#define OC_DIV2(_x) OC_DIV_POW2(_x,1,0x1)
+/*Divides _x by 8, truncating towards 0.*/
+#define OC_DIV8(_x) OC_DIV_POW2(_x,3,0x7)
+/*Divides _x by 16, truncating towards 0.*/
+#define OC_DIV16(_x) OC_DIV_POW2(_x,4,0xF)
+/*Right shifts _dividend by _shift, adding _rval, and subtracting one for
+   negative dividends first..
+  When _rval is (1<<_shift-1), this is equivalent to division with rounding
+   ties towards positive infinity.*/
+#define OC_DIV_ROUND_POW2(_dividend,_shift,_rval)\
+  ((_dividend)+((_dividend)>>sizeof(_dividend)*8-1)+(_rval)>>(_shift))
+/*Swaps two integers _a and _b if _a>_b.*/
+#define OC_SORT2I(_a,_b)\
+  if((_a)>(_b)){\
+    int t__;\
+    t__=(_a);\
+    (_a)=(_b);\
+    (_b)=t__;\
+  }
+
+
+
+/*All of these macros should expect floats as arguments.*/
+#define OC_MAXF(_a,_b)      ((_a)<(_b)?(_b):(_a))
+#define OC_MINF(_a,_b)      ((_a)>(_b)?(_b):(_a))
+#define OC_CLAMPF(_a,_b,_c) (OC_MINF(_a,OC_MAXF(_b,_c)))
+#define OC_FABSF(_f)        ((float)fabs(_f))
+#define OC_SQRTF(_f)        ((float)sqrt(_f))
+#define OC_POWF(_b,_e)      ((float)pow(_b,_e))
+#define OC_LOGF(_f)         ((float)log(_f))
+#define OC_IFLOORF(_f)      ((int)floor(_f))
+#define OC_ICEILF(_f)       ((int)ceil(_f))
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/quant.c
@@ -0,0 +1,152 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: quant.c 14375 2008-01-06 05:37:33Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#include "quant.h"
+#include "decint.h"
+
+unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2};
+unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2};
+
+/*Initializes the dequantization tables from a set of quantizer info.
+  Currently the dequantizer (and elsewhere enquantizer) tables are expected to
+   be initialized as pointing to the storage reserved for them in the
+   oc_theora_state (resp. oc_enc_ctx) structure.
+  If some tables are duplicates of others, the pointers will be adjusted to
+   point to a single copy of the tables, but the storage for them will not be
+   freed.
+  If you're concerned about the memory footprint, the obvious thing to do is
+   to move the storage out of its fixed place in the structures and allocate
+   it on demand.
+  However, a much, much better option is to only store the quantization
+   matrices being used for the current frame, and to recalculate these as the
+   qi values change between frames (this is what VP3 did).*/
+void oc_dequant_tables_init(oc_quant_table *_dequant[2][3],
+ int _pp_dc_scale[64],const th_quant_info *_qinfo){
+  int          qti; /* coding mode: intra or inter */
+  int          pli; /* Y U V */
+  for(qti=0;qti<2;qti++){
+    for(pli=0;pli<3;pli++){
+      oc_quant_tables stage;
+
+      int qi;  /* quality index */
+      int qri; /* range iterator */
+      
+      for(qi=0,qri=0; qri<=_qinfo->qi_ranges[qti][pli].nranges; qri++){
+	th_quant_base base;
+	
+	ogg_uint32_t      q;
+	int               qi_start;
+	int               qi_end;
+	int               ci;
+	memcpy(base,_qinfo->qi_ranges[qti][pli].base_matrices[qri],
+	       sizeof(base));
+
+	qi_start=qi;
+	if(qri==_qinfo->qi_ranges[qti][pli].nranges)
+	  qi_end=qi+1;
+	else 
+	  qi_end=qi+_qinfo->qi_ranges[qti][pli].sizes[qri];
+	
+	/* Iterate over quality indicies in this range */
+	for(;;){
+	  
+	  /*In the original VP3.2 code, the rounding offset and the size of the
+	    dead zone around 0 were controlled by a "sharpness" parameter.
+	    The size of our dead zone is now controlled by the per-coefficient
+	    quality thresholds returned by our HVS module.
+	    We round down from a more accurate value when the quality of the
+	    reconstruction does not fall below our threshold and it saves bits.
+	    Hence, all of that VP3.2 code is gone from here, and the remaining
+	    floating point code has been implemented as equivalent integer code
+	    with exact precision.*/
+
+	  /* for postprocess, not dequant */
+	  if(_pp_dc_scale!=NULL)
+	    _pp_dc_scale[qi]=(int)((ogg_uint32_t)_qinfo->dc_scale[qi]*base[0]/160);
+
+	  /*Scale DC the coefficient from the proper table.*/
+	  q=((ogg_uint32_t)_qinfo->dc_scale[qi]*base[0]/100)<<2;
+	  q=OC_CLAMPI(OC_DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
+	  stage[qi][0]=(ogg_uint16_t)q;
+	  
+	  /*Now scale AC coefficients from the proper table.*/
+	  for(ci=1;ci<64;ci++){
+	    q=((ogg_uint32_t)_qinfo->ac_scale[qi]*base[ci]/100)<<2;
+	    q=OC_CLAMPI(OC_AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
+	    stage[qi][ci]=(ogg_uint16_t)q;
+	  }
+	  
+	  if(++qi>=qi_end)break;
+	  
+	  /*Interpolate the next base matrix.*/
+	  for(ci=0;ci<64;ci++){
+	    base[ci]=(unsigned char)
+	      ((2*((qi_end-qi)*_qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
+		   (qi-qi_start)*_qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
+		+_qinfo->qi_ranges[qti][pli].sizes[qri])/
+	       (2*_qinfo->qi_ranges[qti][pli].sizes[qri]));
+	  }
+	}
+      }
+
+      /* Staging matricies complete; commit to memory only if this
+	 isn't a duplicate of a preceeding plane. This simple check
+	 helps us improve cache coherency later.*/
+      {
+	int dupe = 0;
+	int i,j;
+	for(i=0;i<=qti;i++){
+	  for(j=0;j<(i<qti?3:pli);j++){
+	    if(!memcmp(stage,_dequant[i][j],sizeof(stage))){
+	      dupe = 1;
+	      break;
+	    }
+	  }
+	  if(dupe)break;
+	}
+	if(dupe){
+	  _dequant[qti][pli]=_dequant[i][j];
+	}else{
+	  memcpy(_dequant[qti][pli],stage,sizeof(stage));
+	}
+      }
+    }
+  }
+
+#ifdef _TH_DEBUG_
+  int i, j, k, l;
+  /* dump the calculated quantizer tables */
+  for(i=0;i<2;i++){
+    for(j=0;j<3;j++){
+      for(k=0;k<64;k++){
+	TH_DEBUG("quantizer table [%s][%s][Q%d] = {",
+		 (i==0?"intra":"inter"),(j==0?"Y":(j==1?"U":"V")),k);
+	for(l=0;l<64;l++){
+	  if((l&7)==0)
+	    TH_DEBUG("\n   ");
+	  TH_DEBUG("%4d ",_dequant[i][j][k][l]);
+	}
+	TH_DEBUG("}\n");
+      }
+    }
+  }
+#endif
+
+}
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/quant.h
@@ -0,0 +1,46 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: quant.h 14059 2007-10-28 23:43:27Z xiphmont $
+
+ ********************************************************************/
+
+#if !defined(_quant_H)
+# define _quant_H (1)
+# include "theora/codec.h"
+# include "ocintrin.h"
+
+typedef ogg_uint16_t   oc_quant_table[64];
+typedef oc_quant_table oc_quant_tables[64];
+
+
+
+/*Maximum scaled quantizer value.*/
+#define OC_QUANT_MAX          (1024<<2)
+
+
+
+/*Minimum scaled DC coefficient frame quantizer value for intra and inter
+   modes.*/
+extern unsigned OC_DC_QUANT_MIN[2];
+/*Minimum scaled AC coefficient frame quantizer value for intra and inter
+   modes.*/
+extern unsigned OC_AC_QUANT_MIN[2];
+
+
+
+void oc_dequant_tables_init(oc_quant_table *_dequant[2][3],
+			    int _pp_dc_scale[64],
+			    const th_quant_info *_qinfo);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/libtheora/lib/dec/state.c
@@ -0,0 +1,1283 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+    last mod: $Id: state.c 14714 2008-04-12 01:04:43Z giles $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "../internal.h"
+#include "idct.h"
+#if defined(USE_ASM)
+#if defined(_MSC_VER)
+# include "x86_vc/x86int.h"
+#else
+# include "x86/x86int.h"
+#endif
+#endif
+#if defined(OC_DUMP_IMAGES)
+# include <stdio.h>
+# include "png.h"
+#endif
+
+void oc_restore_fpu(const oc_theora_state *_state){
+  _state->opt_vtable.restore_fpu();
+}
+
+void oc_restore_fpu_c(void){}
+
+/*Returns the fragment index of the top-left block in a macro block.
+  This can be used to test whether or not the whole macro block is coded.
+  _sb:    The super block.
+  _quadi: The quadrant number.
+  Return: The index of the fragment of the upper left block in the macro
+   block, or -1 if the block lies outside the coded frame.*/
+static int oc_sb_quad_top_left_frag(const oc_sb *_sb,int _quadi){
+  /*It so happens that under the Hilbert curve ordering described below, the
+     upper-left block in each macro block is at index 0, except in macro block
+     3, where it is at index 2.*/
+  return _sb->map[_quadi][_quadi&_quadi<<1];
+}
+
+/*Fills in the mapping from block positions to fragment numbers for a single
+   color plane.
+  This function also fills in the "valid" flag of each quadrant in a super
+   block.
+  _sbs:    The array of super blocks for the color plane.
+  _frag0:  The index of the first fragment in the plane.
+  _hfrags: The number of horizontal fragments in a coded frame.
+  _vfrags: The number of vertical fragments in a coded frame.*/
+static void oc_sb_create_plane_mapping(oc_sb _sbs[],int _frag0,int _hfrags,
+ int _vfrags){
+  /*Contains the (macro_block,block) indices for a 4x4 grid of
+     fragments.
+    The pattern is a 4x4 Hilbert space-filling curve.
+    A Hilbert curve has the nice property that as the curve grows larger, its
+     fractal dimension approaches 2.
+    The intuition is that nearby blocks in the curve are also close spatially,
+     with the previous element always an immediate neighbor, so that runs of
+     blocks should be well correlated.*/
+  static const int SB_MAP[4][4][2]={
+    {{0,0},{0,1},{3,2},{3,3}},
+    {{0,3},{0,2},{3,1},{3,0}},
+    {{1,0},{1,3},{2,0},{2,3}},
+    {{1,1},{1,2},{2,1},{2,2}}
+  };
+  oc_sb *sb;
+  int    yfrag;
+  int    y;
+  sb=_sbs;
+  yfrag=_frag0;
+  for(y=0;;y+=4){
+    int imax;
+    int x;
+    /*Figure out how many columns of blocks in this super block lie within the
+       image.*/
+    imax=_vfrags-y;
+    if(imax>4)imax=4;
+    else if(imax<=0)break;
+    for(x=0;;x+=4,sb++){
+      int    xfrag;
+      int    jmax;
+      int    quadi;
+      int    i;
+      /*Figure out how many rows of blocks in this super block lie within the
+         image.*/
+      jmax=_hfrags-x;
+      if(jmax>4)jmax=4;
+      else if(jmax<=0)break;
+      /*By default, set all fragment indices to -1.*/
+      memset(sb->map[0],0xFF,sizeof(sb->map));
+      /*Fill in the fragment map for this super block.*/
+      xfrag=yfrag+x;
+      for(i=0;i<imax;i++){
+        int j;
+        for(j=0;j<jmax;j++){
+          sb->map[SB_MAP[i][j][0]][SB_MAP[i][j][1]]=xfrag+j;
+        }
+        xfrag+=_hfrags;
+      }
+      /*Mark which quadrants of this super block lie within the image.*/
+      for(quadi=0;quadi<4;quadi++){
+        sb->quad_valid|=(oc_sb_quad_top_left_frag(sb,quadi)>=0)<<quadi;
+      }
+    }
+    yfrag+=_hfrags<<2;
+  }
+}
+
+/*Fills in the Y plane fragment map for a macro block given the fragment
+   coordinates of its upper-left hand corner.
+  _mb:     The macro block to fill.
+  _fplane: The description of the Y plane.
+  _x:      The X location of the upper-left hand fragment in the Y plane.
+  _y:      The Y location of the upper-left hand fragment in the Y plane.*/
+static void oc_mb_fill_ymapping(oc_mb *_mb,const oc_fragment_plane *_fplane,
+ int _x,int _y){
+  int i;
+  for(i=0;i<2;i++){
+    int j;
+    if(_y+i>=_fplane->nvfrags)break;
+    for(j=0;j<2;j++){
+      if(_x+j>=_fplane->nhfrags)break;
+      _mb->map[0][i<<1|j]=(_y+i)*_fplane->nhfrags+_x+j;
+    }
+  }
+}
+
+/*Fills in the chroma plane fragment maps for a macro block.
+  This version is for use with chroma decimated in the X and Y directions.
+  _mb:      The macro block to fill.
+  _fplanes: The descriptions of the fragment planes.
+  _x:       The X location of the upper-left hand fragment in the Y plane.
+  _y:       The Y location of the upper-left hand fragment in the Y plane.*/
+static void oc_mb_fill_cmapping00(oc_mb *_mb,
+ const oc_fragment_plane _fplanes[3],int _x,int _y){
+  int fragi;
+  _x>>=1;
+  _y>>=1;
+  fragi=_y*_fplanes[1].nhfrags+_x;
+  _mb->map[1][0]=fragi+_fplanes[1].froffset;
+  _mb->map[2][0]=fragi+_fplanes[2].froffset;
+}
+
+/*Fills in the chroma plane fragment maps for a macro block.
+  This version is for use with chroma decimated in the Y direction.
+  _mb:      The macro block to fill.
+  _fplanes: The descriptions of the fragment planes.
+  _x:       The X location of the upper-left hand fragment in the Y plane.
+  _y:       The Y location of the upper-left hand fragment in the Y plane.*/
+static void oc_mb_fill_cmapping01(oc_mb *_mb,
+ const oc_fragment_plane _fplanes[3],int _x,int _y){
+  int fragi;
+  int j;
+  _y>>=1;
+  fragi=_y*_fplanes[1].nhfrags+_x;
+  for(j=0;j<2;j++){
+    if(_x+j>=_fplanes[1].nhfrags)break;
+    _mb->map[1][j]=fragi+_fplanes[1].froffset;
+    _mb->map[2][j]=fragi+_fplanes[2].froffset;
+    fragi++;
+  }
+}
+
+/*Fills in the chroma plane fragment maps for a macro block.
+  This version is for use with chroma decimated in the X direction.
+  _mb:      The macro block to fill.
+  _fplanes: The descriptions of the fragment planes.
+  _x:       The X location of the upper-left hand fragment in the Y plane.
+  _y:       The Y location of the upper-left hand fragment in the Y plane.*/
+static void oc_mb_fill_cmapping10(oc_mb *_mb,
+ const oc_fragment_plane _fplanes[3],int _x,int _y){
+  int fragi;
+  int i;
+  _x>>=1;
+  fragi=_y*_fplanes[1].nhfrags+_x;
+  for(i=0;i<2;i++){
+    if(_y+i>=_fplanes[1].nvfrags)break;
+    _mb->map[1][i<<1]=fragi+_fplanes[1].froffset;
+    _mb->map[2][i<<1]=fragi+_fplanes[2].froffset;
+    fragi+=_fplanes[1].nhfrags;
+  }
+}
+
+/*Fills in the chroma plane fragment maps for a macro block.
+  This version is for use with no chroma decimation.
+  This uses the already filled-in Y plane values.
+  _mb:      The macro block to fill.
+  _fplanes: The descriptions of the fragment planes.*/
+static void oc_mb_fill_cmapping11(oc_mb *_mb,
+ const oc_fragment_plane _fplanes[3]){
+  int k;
+  for(k=0;k<4;k++){
+    if(_mb->map[0][k]>=0){
+      _mb->map[1][k]=_mb->map[0][k]+_fplanes[1].froffset;
+      _mb->map[2][k]=_mb->map[0][k]+_fplanes[2].froffset;
+    }
+  }
+}
+
+/*The function type used to fill in the chroma plane fragment maps for a
+   macro block.
+  _mb:      The macro block to fill.
+  _fplanes: The descriptions of the fragment planes.
+  _x:       The X location of the upper-left hand fragment in the Y plane.
+  _y:       The Y location of the upper-left hand fragment in the Y plane.*/
+typedef void (*oc_mb_fill_cmapping_func)(oc_mb *_mb,
+ const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0);
+
+/*A table of functions used to fill in the chroma plane fragment maps for a
+   macro block for each type of chrominance decimation.*/
+static const oc_mb_fill_cmapping_func OC_MB_FILL_CMAPPING_TABLE[4]={
+  oc_mb_fill_cmapping00,
+  oc_mb_fill_cmapping01,
+  oc_mb_fill_cmapping10,
+  (oc_mb_fill_cmapping_func)oc_mb_fill_cmapping11
+};
+
+/*Fills in the mapping from macro blocks to their corresponding fragment
+   numbers in each plane.
+  _mbs:     The array of macro blocks.
+  _fplanes: The descriptions of the fragment planes.
+  _ctype:   The chroma decimation type.*/
+static void oc_mb_create_mapping(oc_mb _mbs[],
+ const oc_fragment_plane _fplanes[3],int _ctype){
+  oc_mb_fill_cmapping_func  mb_fill_cmapping;
+  oc_mb                    *mb0;
+  int                       y;
+  mb0=_mbs;
+  mb_fill_cmapping=OC_MB_FILL_CMAPPING_TABLE[_ctype];
+  /*Loop through the Y plane super blocks.*/
+  for(y=0;y<_fplanes[0].nvfrags;y+=4){
+    int x;
+    for(x=0;x<_fplanes[0].nhfrags;x+=4,mb0+=4){
+      int ymb;
+      /*Loop through the macro blocks in each super block in display order.*/
+      for(ymb=0;ymb<2;ymb++){
+        int xmb;
+        for(xmb=0;xmb<2;xmb++){
+          oc_mb *mb;
+          int    mbx;
+          int    mby;
+          mb=mb0+OC_MB_MAP[ymb][xmb];
+          mbx=x|xmb<<1;
+          mby=y|ymb<<1;
+          mb->x=mbx<<3;
+          mb->y=mby<<3;
+          /*Initialize fragment indexes to -1.*/
+          memset(mb->map,0xFF,sizeof(mb->map));
+          /*Make sure this macro block is within the encoded region.*/
+          if(mbx>=_fplanes[0].nhfrags||mby>=_fplanes[0].nvfrags){
+            mb->mode=OC_MODE_INVALID;
+            continue;
+          }
+          /*Fill in the fragment indices for the Y plane.*/
+          oc_mb_fill_ymapping(mb,_fplanes,mbx,mby);
+          /*Fill in the fragment indices for the chroma planes.*/
+          (*mb_fill_cmapping)(mb,_fplanes,mbx,mby);
+        }
+      }
+    }
+  }
+}
+
+/*Marks the fragments which fall all or partially outside the displayable
+   region of the frame.
+  _state: The Theora state containing the fragments to be marked.*/
+static void oc_state_border_init(oc_theora_state *_state){
+  typedef struct{
+    int x0;
+    int y0;
+    int xf;
+    int yf;
+  }oc_crop_rect;
+  oc_fragment       *frag;
+  oc_fragment       *yfrag_end;
+  oc_fragment       *xfrag_end;
+  oc_fragment_plane *fplane;
+  oc_crop_rect      *crop;
+  oc_crop_rect       crop_rects[3];
+  int                pli;
+  int                y;
+  int                x;
+  /*The method we use here is slow, but the code is dead simple and handles
+     all the special cases easily.
+    We only ever need to do it once.*/
+  /*Loop through the fragments, marking those completely outside the
+     displayable region and constructing a border mask for those that straddle
+     the border.*/
+  _state->nborders=0;
+  yfrag_end=frag=_state->frags;
+  for(pli=0;pli<3;pli++){
+    fplane=_state->fplanes+pli;
+    crop=crop_rects+pli;
+    /*Set up the cropping rectangle for this plane.*/
+    crop->x0=_state->info.pic_x;
+    crop->xf=_state->info.pic_x+_state->info.pic_width;
+    crop->y0=_state->info.pic_y;
+    crop->yf=_state->info.pic_y+_state->info.pic_height;
+    if(pli>0){
+      if(!(_state->info.pixel_fmt&1)){
+        crop->x0=crop->x0>>1;
+        crop->xf=crop->xf+1>>1;
+      }
+      if(!(_state->info.pixel_fmt&2)){
+        crop->y0=crop->y0>>1;
+        crop->yf=crop->yf+1>>1;
+      }
+    }
+    y=0;
+    for(yfrag_end+=fplane->nfrags;frag<yfrag_end;y+=8){
+      x=0;
+      for(xfrag_end=frag+fplane->nhfrags;frag<xfrag_end;frag++,x+=8){
+        /*First check to see if this fragment is completely outside the
+           displayable region.*/
+        /*Note the special checks for an empty cropping rectangle.
+          This guarantees that if we count a fragment as straddling the
+           border below, at least one pixel in the fragment will be inside
+           the displayable region.*/
+        if(x+8<=crop->x0||crop->xf<=x||y+8<=crop->y0||crop->yf<=y||
+         crop->x0>=crop->xf||crop->y0>=crop->yf){
+          frag->invalid=1;
+        }
+        /*Otherwise, check to see if it straddles the border.*/
+        else if(x<crop->x0&&crop->x0<x+8||x<crop->xf&&crop->xf<x+8||
+         y<crop->y0&&crop->y0<y+8||y<crop->yf&&crop->yf<y+8){
+          ogg_int64_t mask;
+          int         npixels;
+          int         i;
+          mask=npixels=0;
+          for(i=0;i<8;i++){
+            int j;
+            for(j=0;j<8;j++){
+              if(x+j>=crop->x0&&x+j<crop->xf&&y+i>=crop->y0&&y+i<crop->yf){
+                mask|=(ogg_int64_t)1<<(i<<3|j);
+                npixels++;
+              }
+            }
+          }
+          /*Search the fragment array for border info with the same pattern.
+            In general, there will be at most 8 different patterns (per
+            plane).*/
+          for(i=0;;i++){
+            if(i>=_state->nborders){
+              _state->nborders++;
+              _state->borders[i].mask=mask;
+              _state->borders[i].npixels=npixels;
+            }
+            else if(_state->borders[i].mask!=mask)continue;
+            frag->border=_state->borders+i;
+            break;
+          }
+        }
+      }
+    }
+  }
+}
+
+static void oc_state_frarray_init(oc_theora_state *_state){
+  int yhfrags;
+  int yvfrags;
+  int chfrags;
+  int cvfrags;
+  int yfrags;
+  int cfrags;
+  int nfrags;
+  int yhsbs;
+  int yvsbs;
+  int chsbs;
+  int cvsbs;
+  int ysbs;
+  int csbs;
+  int nsbs;
+  int nmbs;
+  int hdec;
+  int vdec;
+  int pli;
+  /*Figure out the number of fragments in each plane.*/
+  /*These parameters have already been validated to be multiples of 16.*/
+  yhfrags=_state->info.frame_width>>3;
+  yvfrags=_state->info.frame_height>>3;
+  hdec=!(_state->info.pixel_fmt&1);
+  vdec=!(_state->info.pixel_fmt&2);
+  chfrags=yhfrags+hdec>>hdec;
+  cvfrags=yvfrags+vdec>>vdec;
+  yfrags=yhfrags*yvfrags;
+  cfrags=chfrags*cvfrags;
+  nfrags=yfrags+2*cfrags;
+  /*Figure out the number of super blocks in each plane.*/
+  yhsbs=yhfrags+3>>2;
+  yvsbs=yvfrags+3>>2;
+  chsbs=chfrags+3>>2;
+  cvsbs=cvfrags+3>>2;
+  ysbs=yhsbs*yvsbs;
+  csbs=chsbs*cvsbs;
+  nsbs=ysbs+2*csbs;
+  nmbs=ysbs<<2;
+  /*Initialize the fragment array.*/
+  _state->fplanes[0].nhfrags=yhfrags;
+  _state->fplanes[0].nvfrags=yvfrags;
+  _state->fplanes[0].froffset=0;
+  _state->fplanes[0].nfrags=yfrags;
+  _state->fplanes[0].nhsbs=yhsbs;
+  _state->fplanes[0].nvsbs=yvsbs;
+  _state->fplanes[0].sboffset=0;
+  _state->fplanes[0].nsbs=ysbs;
+  _state->fplanes[1].nhfrags=_state->fplanes[2].nhfrags=chfrags;
+  _state->fplanes[1].nvfrags=_state->fplanes[2].nvfrags=cvfrags;
+  _state->fplanes[1].froffset=yfrags;
+  _state->fplanes[2].froffset=yfrags+cfrags;
+  _state->fplanes[1].nfrags=_state->fplanes[2].nfrags=cfrags;
+  _state->fplanes[1].nhsbs=_state->fplanes[2].nhsbs=chsbs;
+  _state->fplanes[1].nvsbs=_state->fplanes[2].nvsbs=cvsbs;
+  _state->fplanes[1].sboffset=ysbs;
+  _state->fplanes[2].sboffset=ysbs+csbs;
+  _state->fplanes[1].nsbs=_state->fplanes[2].nsbs=csbs;
+  _state->nfrags=nfrags;
+  _state->frags=_ogg_calloc(nfrags,sizeof(oc_fragment));
+  _state->nsbs=nsbs;
+  _state->sbs=_ogg_calloc(nsbs,sizeof(oc_sb));
+  _state->nhmbs=yhsbs<<1;
+  _state->nvmbs=yvsbs<<1;
+  _state->nmbs=nmbs;
+  _state->mbs=_ogg_calloc(nmbs,sizeof(oc_mb));
+  _state->coded_fragis=_ogg_malloc(nfrags*sizeof(_state->coded_fragis[0]));
+  _state->uncoded_fragis=_state->coded_fragis+nfrags;
+  _state->coded_mbis=_ogg_malloc(nmbs*sizeof(_state->coded_mbis[0]));
+  /*Create the mapping from super blocks to fragments.*/
+  for(pli=0;pli<3;pli++){
+    oc_fragment_plane *fplane;
+    fplane=_state->fplanes+pli;
+    oc_sb_create_plane_mapping(_state->sbs+fplane->sboffset,
+     fplane->froffset,fplane->nhfrags,fplane->nvfrags);
+  }
+  /*Create the mapping from macro blocks to fragments.*/
+  oc_mb_create_mapping(_state->mbs,_state->fplanes,_state->info.pixel_fmt);
+  /*Initialize the invalid and border fields of each fragment.*/
+  oc_state_border_init(_state);
+}
+
+static void oc_state_frarray_clear(oc_theora_state *_state){
+  _ogg_free(_state->coded_mbis);
+  _ogg_free(_state->coded_fragis);
+  _ogg_free(_state->mbs);
+  _ogg_free(_state->sbs);
+  _ogg_free(_state->frags);
+}
+
+
+/*Initializes the buffers used for reconstructed frames.
+  These buffers are padded with 16 extra pixels on each side, to allow
+   unrestricted motion vectors without special casing the boundary.
+  If chroma is decimated in either direction, the padding is reduced by a
+   factor of 2 on the appropriate sides.
+  _enc: The encoding context to store the buffers in.*/
+static void oc_state_ref_bufs_init(oc_theora_state *_state){
+  th_info   *info;
+  unsigned char *ref_frame_data;
+  size_t         yplane_sz;
+  size_t         cplane_sz;
+  int            yhstride;
+  int            yvstride;
+  int            chstride;
+  int            cvstride;
+  int            yoffset;
+  int            coffset;
+  int            rfi;
+  info=&_state->info;
+  /*Compute the image buffer parameters for each plane.*/
+  yhstride=info->frame_width+2*OC_UMV_PADDING;
+  yvstride=info->frame_height+2*OC_UMV_PADDING;
+  chstride=yhstride>>!(info->pixel_fmt&1);
+  cvstride=yvstride>>!(info->pixel_fmt&2);
+  yplane_sz=(size_t)yhstride*yvstride;
+  cplane_sz=(size_t)chstride*cvstride;
+  yoffset=OC_UMV_PADDING+OC_UMV_PADDING*yhstride;
+  coffset=(OC_UMV_PADDING>>!(info->pixel_fmt&1))+
+   (OC_UMV_PADDING>>!(info->pixel_fmt&2))*chstride;
+  _state->ref_frame_data=ref_frame_data=_ogg_malloc(3*(yplane_sz+2*cplane_sz));
+  /*Set up the width, height and stride for the image buffers.*/
+  _state->ref_frame_bufs[0][0].width=info->frame_width;
+  _state->ref_frame_bufs[0][0].height=info->frame_height;
+  _state->ref_frame_bufs[0][0].stride=yhstride;
+  _state->ref_frame_bufs[0][1].width=_state->ref_frame_bufs[0][2].width=
+   info->frame_width>>!(info->pixel_fmt&1);
+  _state->ref_frame_bufs[0][1].height=_state->ref_frame_bufs[0][2].height=
+   info->frame_height>>!(info->pixel_fmt&2);
+  _state->ref_frame_bufs[0][1].stride=_state->ref_frame_bufs[0][2].stride=
+   chstride;
+  memcpy(_state->ref_frame_bufs[1],_state->ref_frame_bufs[0],
+   sizeof(_state->ref_frame_bufs[0]));
+  memcpy(_state->ref_frame_bufs[2],_state->ref_frame_bufs[0],
+   sizeof(_state->ref_frame_bufs[0]));
+  /*Set up the data pointers for the image buffers.*/
+  for(rfi=0;rfi<3;rfi++){
+    _state->ref_frame_bufs[rfi][0].data=ref_frame_data+yoffset;
+    ref_frame_data+=yplane_sz;
+    _state->ref_frame_bufs[rfi][1].data=ref_frame_data+coffset;
+    ref_frame_data+=cplane_sz;
+    _state->ref_frame_bufs[rfi][2].data=ref_frame_data+coffset;
+    ref_frame_data+=cplane_sz;
+    /*Flip the buffer upside down.*/
+    oc_ycbcr_buffer_flip(_state->ref_frame_bufs[rfi],
+     _state->ref_frame_bufs[rfi]);
+    /*Initialize the fragment pointers into this buffer.*/
+    oc_state_fill_buffer_ptrs(_state,rfi,_state->ref_frame_bufs[rfi]);
+  }
+  /*Initialize the reference frame indexes.*/
+  _state->ref_frame_idx[OC_FRAME_GOLD]=
+   _state->ref_frame_idx[OC_FRAME_PREV]=
+   _state->ref_frame_idx[OC_FRAME_SELF]=-1;
+}
+
+static void oc_state_ref_bufs_clear(oc_theora_state *_state){
+  _ogg_free(_state->ref_frame_data);
+}
+
+
+void oc_state_vtable_init_c(oc_theora_state *_state){
+  _state->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c;
+  _state->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c;
+  _state->opt_vtable.frag_recon_inter2=oc_frag_recon_inter2_c;
+  _state->opt_vtable.state_frag_copy=oc_state_frag_copy_c;
+  _state->opt_vtable.state_frag_recon=oc_state_frag_recon_c;
+  _state->opt_vtable.state_loop_filter_frag_rows=
+   oc_state_loop_filter_frag_rows_c;
+  _state->opt_vtable.restore_fpu=oc_restore_fpu_c;
+}
+
+/*Initialize the accelerated function pointers.*/
+void oc_state_vtable_init(oc_theora_state *_state){
+#if defined(USE_ASM)
+  oc_state_vtable_init_x86(_state);
+#else
+  oc_state_vtable_init_c(_state);
+#endif
+}
+
+
+int oc_state_init(oc_theora_state *_state,const th_info *_info){
+  int old_granpos;
+  /*First validate the parameters.*/
+  if(_info==NULL)return TH_EFAULT;
+  /*The width and height of the encoded frame must be multiples of 16.
+    They must also, when divided by 16, fit into a 16-bit unsigned integer.
+    The displayable frame offset coordinates must fit into an 8-bit unsigned
+     integer.
+    Note that the offset Y in the API is specified on the opposite side from
+     how it is specified in the bitstream, because the Y axis is flipped in
+     the bitstream.
+    The displayable frame must fit inside the encoded frame.
+    The color space must be one known by the encoder.*/
+  if((_info->frame_width&0xF)||(_info->frame_height&0xF)||
+   _info->frame_width>=0x100000||_info->frame_height>=0x100000||
+   _info->pic_x+_info->pic_width>_info->frame_width||
+   _info->pic_y+_info->pic_height>_info->frame_height||
+   _info->pic_x>255||
+   _info->frame_height-_info->pic_height-_info->pic_y>255||
+   _info->colorspace<0||_info->colorspace>=TH_CS_NSPACES||
+   _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS){
+    return TH_EINVAL;
+  }
+  memset(_state,0,sizeof(*_state));
+  memcpy(&_state->info,_info,sizeof(*_info));
+  /*Invert the sense of pic_y to match Theora's right-handed coordinate
+     system.*/
+  _state->info.pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
+  _state->frame_type=OC_UNKWN_FRAME;
+  oc_state_vtable_init(_state);
+  oc_state_frarray_init(_state);
+  oc_state_ref_bufs_init(_state);
+  /*If the keyframe_granule_shift is out of range, use the maximum allowable
+     value.*/
+  if(_info->keyframe_granule_shift<0||_info->keyframe_granule_shift>31){
+    _state->info.keyframe_granule_shift=31;
+  }
+  _state->keyframe_num=1;
+  _state->curframe_num=0;
+  /*3.2.0 streams mark the frame index instead of the frame count.
+    This was changed with stream version 3.2.1 to conform to other Ogg
+     codecs.
+    We subtract an extra one from the frame number for old streams.*/
+  old_granpos=!TH_VERSION_CHECK(_info,3,2,1);
+  _state->curframe_num-=old_granpos;
+  _state->keyframe_num-=old_granpos;
+  return 0;
+}
+
+void oc_state_clear(oc_theora_state *_state){
+  oc_state_ref_bufs_clear(_state);
+  oc_state_frarray_clear(_state);
+}
+
+
+/*Duplicates the pixels on the border of the image plane out into the
+   surrounding padding for use by unrestricted motion vectors.
+  This function only adds the left and right borders, and only for the fragment
+   rows specified.
+  _refi: The index of the reference buffer to pad.
+  _pli:  The color plane.
+  _y0:   The Y coordinate of the first row to pad.
+  _yend: The Y coordinate of the row to stop padding at.*/
+void oc_state_borders_fill_rows(oc_theora_state *_state,int _refi,int _pli,
+ int _y0,int _yend){
+  th_img_plane *iplane;
+  unsigned char    *apix;
+  unsigned char    *bpix;
+  unsigned char    *epix;
+  int               hpadding;
+  hpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&1));
+  iplane=_state->ref_frame_bufs[_refi]+_pli;
+  apix=iplane->data+_y0*iplane->stride;
+  bpix=apix+iplane->width-1;
+  epix=iplane->data+_yend*iplane->stride;
+  /*Note the use of != instead of <, which allows ystride to be negative.*/
+  while(apix!=epix){
+    memset(apix-hpadding,apix[0],hpadding);
+    memset(bpix+1,bpix[0],hpadding);
+    apix+=iplane->stride;
+    bpix+=iplane->stride;
+  }
+}
+
+/*Duplicates the pixels on the border of the image plane out into the
+   surrounding padding for use by unrestricted motion vectors.
+  This function only adds the top and bottom borders, and must be called after
+   the left and right borders are added.
+  _refi:      The index of the reference buffer to pad.
+  _pli:       The color plane.*/
+void oc_state_borders_fill_caps(oc_theora_state *_state,int _refi,int _pli){
+  th_img_plane *iplane;
+  unsigned char    *apix;
+  unsigned char    *bpix;
+  unsigned char    *epix;
+  int               hpadding;
+  int               vpadding;
+  int               fullw;
+  hpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&1));
+  vpadding=OC_UMV_PADDING>>(_pli!=0&&!(_state->info.pixel_fmt&2));
+  iplane=_state->ref_frame_bufs[_refi]+_pli;
+  fullw=iplane->width+(hpadding<<1);
+  apix=iplane->data-hpadding;
+  bpix=iplane->data+(iplane->height-1)*iplane->stride-hpadding;
+  epix=apix-iplane->stride*vpadding;
+  while(apix!=epix){
+    memcpy(apix-iplane->stride,apix,fullw);
+    memcpy(bpix+iplane->stride,bpix,fullw);
+    apix-=iplane->stride;
+    bpix+=iplane->stride;
+  }
+}
+
+/*Duplicates the pixels on the border of the given reference image out into
+   the surrounding padding for use by unrestricted motion vectors.
+  _state: The context containing the reference buffers.
+  _refi:  The index of the reference buffer to pad.*/
+void oc_state_borders_fill(oc_theora_state *_state,int _refi){
+  int pli;
+  for(pli=0;pli<3;pli++){
+    oc_state_borders_fill_rows(_state,_refi,pli,0,
+     _state->ref_frame_bufs[_refi][pli].height);
+    oc_state_borders_fill_caps(_state,_refi,pli);
+  }
+}
+
+/*Sets the buffer pointer in each fragment to point to the portion of the
+   image buffer which it corresponds to.
+  _state:   The Theora state to fill.
+  _buf_idx: The index of the buffer pointer to fill.
+            The first three correspond to our reconstructed frame buffers,
+             while the last corresponds to the input image.
+  _img:     The image buffer to fill the fragments with.*/
+void oc_state_fill_buffer_ptrs(oc_theora_state *_state,int _buf_idx,
+ th_ycbcr_buffer _img){
+  int pli;
+  /*Special handling for the input image to give us the opportunity to skip
+     some updates.
+    The other buffers do not change throughout the encoding process.*/
+  if(_buf_idx==OC_FRAME_IO){
+     if(memcmp(_state->input,_img,sizeof(th_ycbcr_buffer))==0)return;
+     memcpy(_state->input,_img,sizeof(th_ycbcr_buffer));
+  }
+  for(pli=0;pli<3;pli++){
+    th_img_plane  *iplane;
+    oc_fragment_plane *fplane;
+    oc_fragment       *frag;
+    oc_fragment       *vfrag_end;
+    unsigned char     *vpix;
+    iplane=&_img[pli];
+    fplane=&_state->fplanes[pli];
+    vpix=iplane->data;
+    frag=_state->frags+fplane->froffset;
+    vfrag_end=frag+fplane->nfrags;
+    while(frag<vfrag_end){
+      oc_fragment   *hfrag_end;
+      unsigned char *hpix;
+      hpix=vpix;
+      for(hfrag_end=frag+fplane->nhfrags;frag<hfrag_end;frag++){
+        frag->buffer[_buf_idx]=hpix;
+        hpix+=8;
+      }
+      vpix+=iplane->stride<<3;
+    }
+  }
+}
+
+/*Returns the macro block index of the macro block in the given position.
+  _state: The Theora state the macro block is contained in.
+  _mbx:   The X coordinate of the macro block (in macro blocks, not pixels).
+  _mby:   The Y coordinate of the macro block (in macro blocks, not pixels).
+  Return: The index of the macro block in the given position.*/
+int oc_state_mbi_for_pos(oc_theora_state *_state,int _mbx,int _mby){
+  return ((_mbx&~1)<<1)+(_mby&~1)*_state->nhmbs+OC_MB_MAP[_mby&1][_mbx&1];
+}
+
+/*Determines the offsets in an image buffer to use for motion compensation.
+  _state:   The Theora state the offsets are to be computed with.
+  _offsets: Returns the offset for the buffer(s).
+            _offsets[0] is always set.
+            _offsets[1] is set if the motion vector has non-zero fractional
+             components.
+  _dx:      The X component of the motion vector.
+  _dy:      The Y component of the motion vector.
+  _ystride: The Y stride in the buffer the motion vector points into.
+  _pli:     The color plane index.
+  Return: The number of offsets returned: 1 or 2.*/
+int oc_state_get_mv_offsets(oc_theora_state *_state,int _offsets[2],
+ int _dx,int _dy,int _ystride,int _pli){
+  int xprec;
+  int yprec;
+  int xfrac;
+  int yfrac;
+  /*Here is a brief description of how Theora handles motion vectors:
+    Motion vector components are specified to half-pixel accuracy in
+     undecimated directions of each plane, and quarter-pixel accuracy in
+     decimated directions.
+    Integer parts are extracted by dividing (not shifting) by the
+     appropriate amount, with truncation towards zero.
+    These integer values are used to calculate the first offset.
+
+    If either of the fractional parts are non-zero, then a second offset is
+     computed.
+    No third or fourth offsets are computed, even if both components have
+     non-zero fractional parts.
+    The second offset is computed by dividing (not shifting) by the
+     appropriate amount, always truncating _away_ from zero.*/
+  /*These two variables decide whether we are in half- or quarter-pixel
+     precision in each component.*/
+  xprec=1+(!(_state->info.pixel_fmt&1)&&_pli);
+  yprec=1+(!(_state->info.pixel_fmt&2)&&_pli);
+  /*These two variables are either 0 if all the fractional bits are 0 or 1 if
+     any of them are non-zero.*/
+  xfrac=!!(_dx&(1<<xprec)-1);
+  yfrac=!!(_dy&(1<<yprec)-1);
+  _offsets[0]=(_dx>>xprec)+(_dy>>yprec)*_ystride;
+  if(xfrac||yfrac){
+    /*This branchless code is equivalent to:
+    if(_dx<0)_offests[0]=-(-_dx>>xprec);
+    else _offsets[0]=(_dx>>xprec);
+    if(_dy<0)_offsets[0]-=(-_dy>>yprec)*_ystride;
+    else _offsets[0]+=(_dy>>yprec)*_ystride;
+    _offsets[1]=_offsets[0];
+    if(xfrac){
+      if(_dx<0)_offsets[1]++;
+      else _offsets[1]--;
+    }
+    if(yfrac){
+      if(_dy<0)_offsets[1]+=_ystride;
+      else _offsets[1]-=_ystride;
+    }*/
+    _offsets[1]=_offsets[0];
+    _offsets[_dx>=0]+=xfrac;
+    _offsets[_dy>=0]+=_ystride&-yfrac;
+    return 2;
+  }
+  else return 1;
+}
+
+void oc_state_frag_recon(oc_theora_state *_state,oc_fragment *_frag,
+ int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
+ ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]){
+  _state->opt_vtable.state_frag_recon(_state,_frag,_pli,_dct_coeffs,
+   _last_zzi,_ncoefs,_dc_iquant,_ac_iquant);
+}
+
+void oc_state_frag_recon_c(oc_theora_state *_state,oc_fragment *_frag,
+ int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
+ ogg_uint16_t _dc_iquant, const ogg_uint16_t _ac_iquant[64]){
+  ogg_int16_t dct_buf[64];
+  ogg_int16_t res_buf[64];
+  int dst_framei;
+  int dst_ystride;
+  int zzi;
+  int ci;
+  /*_last_zzi is subtly different from an actual count of the number of
+     coefficients we decoded for this block.
+    It contains the value of zzi BEFORE the final token in the block was
+     decoded.
+    In most cases this is an EOB token (the continuation of an EOB run from a
+     previous block counts), and so this is the same as the coefficient count.
+    However, in the case that the last token was NOT an EOB token, but filled
+     the block up with exactly 64 coefficients, _last_zzi will be less than 64.
+    Provided the last token was not a pure zero run, the minimum value it can
+     be is 46, and so that doesn't affect any of the cases in this routine.
+    However, if the last token WAS a pure zero run of length 63, then _last_zzi
+     will be 1 while the number of coefficients decoded is 64.
+    Thus, we will trigger the following special case, where the real
+     coefficient count would not.
+    Note also that a zero run of length 64 will give _last_zzi a value of 0,
+     but we still process the DC coefficient, which might have a non-zero value
+     due to DC prediction.
+    Although convoluted, this is arguably the correct behavior: it allows us to
+     dequantize fewer coefficients and use a smaller transform when the block
+     ends with a long zero run instead of a normal EOB token.
+    It could be smarter... multiple separate zero runs at the end of a block
+     will fool it, but an encoder that generates these really deserves what it
+     gets.
+    Needless to say we inherited this approach from VP3.*/
+  /*Special case only having a DC component.*/
+  if(_last_zzi<2){
+    ogg_int16_t p;
+    /*Why is the iquant product rounded in this case and no others?
+      Who knows.*/
+
+    p=(ogg_int16_t)((ogg_int32_t)_frag->dc*_dc_iquant+15>>5);
+    /*LOOP VECTORIZES.*/
+    for(ci=0;ci<64;ci++)res_buf[ci]=p;
+
+#ifdef _TH_DEBUG_
+    {
+      int i;
+      _frag->freq[0] = _frag->dc*_dc_iquant;
+      _frag->time[0] = p;
+      for(i=1;i<64;i++){
+	_frag->quant[i] = 0;
+	_frag->freq[i] = 0;
+	_frag->time[i] = p;
+      }
+    }
+#endif
+
+  }
+  else{
+
+#ifdef _TH_DEBUG_
+    {
+      int i;
+      for(i=1;i<_ncoefs;i++)
+	_frag->quant[i] = _dct_coeffs[i];
+      for(;i<64;i++)
+	_frag->quant[i] = 0;
+    }
+#endif
+
+    /*First, dequantize the coefficients.*/
+    dct_buf[0]=(ogg_int16_t)((ogg_int32_t)_frag->dc*_dc_iquant);
+    for(zzi=1;zzi<_ncoefs;zzi++){
+      int ci;
+      ci=OC_FZIG_ZAG[zzi];
+      dct_buf[ci]=(ogg_int16_t)((ogg_int32_t)_dct_coeffs[zzi]*_ac_iquant[ci]);
+    }
+
+#ifdef _TH_DEBUG_
+    for(;zzi<64;zzi++){
+      int ci;
+      ci=OC_FZIG_ZAG[zzi];
+      dct_buf[ci]=0;
+    }
+
+    {
+      int i;
+      for(i=0;i<64;i++)
+	_frag->freq[i] = dct_buf[i];
+    }
+#endif
+
+    /*Then, fill in the remainder of the coefficients with 0's, and perform
+       the iDCT.*/
+    if(_last_zzi<10){
+      for(;zzi<10;zzi++)dct_buf[OC_FZIG_ZAG[zzi]]=0;
+      oc_idct8x8_10_c(res_buf,dct_buf);
+    }
+    else{
+      for(;zzi<64;zzi++)dct_buf[OC_FZIG_ZAG[zzi]]=0;
+      oc_idct8x8_c(res_buf,dct_buf);
+    }
+
+#ifdef _TH_DEBUG_
+    {
+      int i;
+      for(i=0;i<64;i++)
+	_frag->time[i] = res_buf[i];
+    }
+#endif
+
+  }
+  /*Fill in the target buffer.*/
+  dst_framei=_state->ref_frame_idx[OC_FRAME_SELF];
+  dst_ystride=_state->ref_frame_bufs[dst_framei][_pli].stride;
+  /*For now ystride values in all ref frames assumed to be equal.*/
+  if(_frag->mbmode==OC_MODE_INTRA){
+    oc_frag_recon_intra(_state,_frag->buffer[dst_framei],dst_ystride,res_buf);
+  }
+  else{
+    int ref_framei;
+    int ref_ystride;
+    int mvoffsets[2];
+    ref_framei=_state->ref_frame_idx[OC_FRAME_FOR_MODE[_frag->mbmode]];
+    ref_ystride=_state->ref_frame_bufs[ref_framei][_pli].stride;
+    if(oc_state_get_mv_offsets(_state,mvoffsets,_frag->mv[0],_frag->mv[1],
+     ref_ystride,_pli)>1){
+      oc_frag_recon_inter2(_state,_frag->buffer[dst_framei],dst_ystride,
+       _frag->buffer[ref_framei]+mvoffsets[0],ref_ystride,
+       _frag->buffer[ref_framei]+mvoffsets[1],ref_ystride,res_buf);
+    }
+    else{
+      oc_frag_recon_inter(_state,_frag->buffer[dst_framei],dst_ystride,
+       _frag->buffer[ref_framei]+mvoffsets[0],ref_ystride,res_buf);
+    }
+  }
+  oc_restore_fpu(_state);
+}
+
+/*Copies the fragments specified by the lists of fragment indices from one
+   frame to another.
+  _fragis:    A pointer to a list of fragment indices.
+  _nfragis:   The number of fragment indices to copy.
+  _dst_frame: The reference frame to copy to.
+  _src_frame: The reference frame to copy from.
+  _pli:       The color plane the fragments lie in.*/
+void oc_state_frag_copy(const oc_theora_state *_state,const int *_fragis,
+ int _nfragis,int _dst_frame,int _src_frame,int _pli){
+  _state->opt_vtable.state_frag_copy(_state,_fragis,_nfragis,_dst_frame,
+   _src_frame,_pli);
+}
+
+void oc_state_frag_copy_c(const oc_theora_state *_state,const int *_fragis,
+ int _nfragis,int _dst_frame,int _src_frame,int _pli){
+  const int *fragi;
+  const int *fragi_end;
+  int        dst_framei;
+  int        dst_ystride;
+  int        src_framei;
+  int        src_ystride;
+  dst_framei=_state->ref_frame_idx[_dst_frame];
+  src_framei=_state->ref_frame_idx[_src_frame];
+  dst_ystride=_state->ref_frame_bufs[dst_framei][_pli].stride;
+  src_ystride=_state->ref_frame_bufs[src_framei][_pli].stride;
+  fragi_end=_fragis+_nfragis;
+  for(fragi=_fragis;fragi<fragi_end;fragi++){
+    oc_fragment   *frag;
+    unsigned char *dst;
+    unsigned char *src;
+    int            j;
+    frag=_state->frags+*fragi;
+    dst=frag->buffer[dst_framei];
+    src=frag->buffer[src_framei];
+    for(j=0;j<8;j++){
+      memcpy(dst,src,sizeof(dst[0])*8);
+      dst+=dst_ystride;
+      src+=src_ystride;
+    }
+  }
+}
+
+static void loop_filter_h(unsigned char *_pix,int _ystride,int *_bv){
+  int y;
+  _pix-=2;
+  for(y=0;y<8;y++){
+    int f;
+    f=_pix[0]-_pix[3]+3*(_pix[2]-_pix[1]);
+    /*The _bv array is used to compute the function
+      f=OC_CLAMPI(OC_MINI(-_2flimit-f,0),f,OC_MAXI(_2flimit-f,0));
+      where _2flimit=_state->loop_filter_limits[_state->qis[0]]<<1;*/
+    f=*(_bv+(f+4>>3));
+    _pix[1]=OC_CLAMP255(_pix[1]+f);
+    _pix[2]=OC_CLAMP255(_pix[2]-f);
+    _pix+=_ystride;
+  }
+}
+
+static void loop_filter_v(unsigned char *_pix,int _ystride,int *_bv){
+  int y;
+  _pix-=_ystride*2;
+  for(y=0;y<8;y++){
+    int f;
+    f=_pix[0]-_pix[_ystride*3]+3*(_pix[_ystride*2]-_pix[_ystride]);
+    /*The _bv array is used to compute the function
+      f=OC_CLAMPI(OC_MINI(-_2flimit-f,0),f,OC_MAXI(_2flimit-f,0));
+      where _2flimit=_state->loop_filter_limits[_state->qis[0]]<<1;*/
+    f=*(_bv+(f+4>>3));
+    _pix[_ystride]=OC_CLAMP255(_pix[_ystride]+f);
+    _pix[_ystride*2]=OC_CLAMP255(_pix[_ystride*2]-f);
+    _pix++;
+  }
+}
+
+/*Initialize the bounding values array used by the loop filter.
+  _bv: Storage for the array.
+  Return: 0 on success, or a non-zero value if no filtering need be applied.*/
+int oc_state_loop_filter_init(oc_theora_state *_state,int *_bv){
+  int flimit;
+  int i;
+  flimit=_state->loop_filter_limits[_state->qis[0]];
+  if(flimit==0)return 1;
+  memset(_bv,0,sizeof(_bv[0])*256);
+  for(i=0;i<flimit;i++){
+    if(127-i-flimit>=0)_bv[127-i-flimit]=i-flimit;
+    _bv[127-i]=-i;
+    _bv[127+i]=i;
+    if(127+i+flimit<256)_bv[127+i+flimit]=flimit-i;
+  }
+  return 0;
+}
+
+/*Apply the loop filter to a given set of fragment rows in the given plane.
+  The filter may be run on the bottom edge, affecting pixels in the next row of
+   fragments, so this row also needs to be available.
+  _bv:        The bounding values array.
+  _refi:      The index of the frame buffer to filter.
+  _pli:       The color plane to filter.
+  _fragy0:    The Y coordinate of the first fragment row to filter.
+  _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/
+void oc_state_loop_filter_frag_rows(oc_theora_state *_state,int *_bv,
+ int _refi,int _pli,int _fragy0,int _fragy_end){
+  _state->opt_vtable.state_loop_filter_frag_rows(_state,_bv,_refi,_pli,
+   _fragy0,_fragy_end);
+}
+
+void oc_state_loop_filter_frag_rows_c(oc_theora_state *_state,int *_bv,
+ int _refi,int _pli,int _fragy0,int _fragy_end){  
+  th_img_plane      *iplane;
+  oc_fragment_plane *fplane;
+  oc_fragment       *frag_top;
+  oc_fragment       *frag0;
+  oc_fragment       *frag;
+  oc_fragment       *frag_end;
+  oc_fragment       *frag0_end;
+  oc_fragment       *frag_bot;
+  _bv+=127;
+  iplane=_state->ref_frame_bufs[_refi]+_pli;
+  fplane=_state->fplanes+_pli;
+
+  /*The following loops are constructed somewhat non-intuitively on purpose.
+    The main idea is: if a block boundary has at least one coded fragment on
+     it, the filter is applied to it.
+    However, the order that the filters are applied in matters, and VP3 chose
+     the somewhat strange ordering used below.*/
+  frag_top=_state->frags+fplane->froffset;
+  frag0=frag_top+_fragy0*fplane->nhfrags;
+  frag0_end=frag0+(_fragy_end-_fragy0)*fplane->nhfrags;
+  frag_bot=_state->frags+fplane->froffset+fplane->nfrags;
+  while(frag0<frag0_end){
+    frag=frag0;
+    frag_end=frag+fplane->nhfrags;
+    while(frag<frag_end){
+      if(frag->coded){
+        if(frag>frag0){
+          loop_filter_h(frag->buffer[_refi],iplane->stride,_bv);
+        }
+        if(frag0>frag_top){
+          loop_filter_v(frag->buffer[_refi],iplane->stride,_bv);
+        }
+        if(frag+1<frag_end&&!(frag+1)->coded){
+          loop_filter_h(frag->buffer[_refi]+8,iplane->stride,_bv);
+        }
+        if(frag+fplane->nhfrags<frag_bot&&!(frag+fplane->nhfrags)->coded){
+          loop_filter_v((frag+fplane->nhfrags)->buffer[_refi],
+           iplane->stride,_bv);
+        }
+      }
+
+
+#ifdef _TH_DEBUG_
+      {
+	int i,j,k,l;
+	unsigned char *src;
+	
+	for(l=0;l<5;l++){
+	  oc_fragment *f;
+	  switch(l){
+	  case 0: 
+	    f = frag;
+	    break;
+	  case 1: /* left */
+	    if(frag == frag0)continue;