mirror of
https://github.com/love2d/megasource.git
synced 2026-08-12 08:30:59 +02:00
Added libtheora.
This commit is contained in:
@@ -126,6 +126,8 @@ elseif(MSVC12)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
set(MEGA_ZLIB_VER "1.2.8")
|
||||
set(MEGA_PHYSFS_VER "2.0.3")
|
||||
set(MEGA_LUA51_VER "5.1.5")
|
||||
@@ -134,6 +136,7 @@ set(MEGA_LIBPNG_VER "166")
|
||||
set(MEGA_JPEG_TURBO_VER "1.3.1")
|
||||
set(MEGA_LIBOGG_VER "1.3.1")
|
||||
set(MEGA_LIBVORBIS_VER "1.3.3")
|
||||
set(MEGA_LIBTHEORA_VER "1.1")
|
||||
set(MEGA_MPG123_VER "1.15.3")
|
||||
set(MEGA_FREETYPE_VER "2.5.0.1")
|
||||
set(MEGA_SDL2_VER "2.0.3-1c0f6952e65e")
|
||||
@@ -195,6 +198,12 @@ add_subdirectory("libs/libvorbis-${MEGA_LIBVORBIS_VER}" ${CMAKE_BINARY_DIR}/libv
|
||||
set(MEGA_LIBVORBIS vorbis-static)
|
||||
set(MEGA_LIBVORBISFILE vorbisfile-static)
|
||||
|
||||
message(STATUS "-----------------------------------------------------")
|
||||
message(STATUS "Configuring: libtheora ${MEGA_LIBTHEORA_VER}")
|
||||
message(STATUS "-----------------------------------------------------")
|
||||
add_subdirectory("libs/libtheora-${MEGA_LIBTHEORA_VER}" ${CMAKE_BINARY_DIR}/libtheora)
|
||||
set(MEGA_LIBTHEORA theora-static)
|
||||
|
||||
message(STATUS "-----------------------------------------------------")
|
||||
message(STATUS "Configuring: mpg123 ${MEGA_MPG123_VER}")
|
||||
message(STATUS "-----------------------------------------------------")
|
||||
@@ -293,6 +302,7 @@ set(MEGA_3P
|
||||
${MEGA_LIBOGG}
|
||||
${MEGA_LIBVORBIS}
|
||||
${MEGA_LIBVORBISFILE}
|
||||
${MEGA_LIBTHEORA}
|
||||
${MEGA_MPEG123}
|
||||
${MEGA_FREETYPE}
|
||||
${MEGA_SDL2}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
Monty <monty@xiph.org>
|
||||
- Original VP3 port
|
||||
|
||||
Ralph Giles
|
||||
Timothy B. Terriberry
|
||||
Monty
|
||||
- Ongoing development
|
||||
|
||||
Dan B. Miller
|
||||
- Pre alpha3 development
|
||||
|
||||
Rudolf Marek
|
||||
Wim Tayman
|
||||
Dan Lenski
|
||||
Nils Pipenbrinck
|
||||
Monty
|
||||
- MMX optimized functions
|
||||
|
||||
Aaron Colwell
|
||||
Thomas Vander Stichele
|
||||
Jan Gerber
|
||||
Conrad Parker
|
||||
Cristian Adam
|
||||
Sebastian Pippin
|
||||
Simon Hosie
|
||||
- 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
|
||||
Chris Cheney
|
||||
Brendan Cully
|
||||
Edward Hervey
|
||||
Adam Moss
|
||||
Colin Ward
|
||||
Jeremy C. Reed
|
||||
Arc Riley
|
||||
Rodolphe Ortalo
|
||||
- Bug fixes
|
||||
|
||||
|
||||
and other Xiph.org contributors
|
||||
@@ -0,0 +1,243 @@
|
||||
libtheora 1.1.2 (unreleased snapshot)
|
||||
|
||||
- Fix Huffman table decoding with OC_HUFF_SLUSH is set to 0
|
||||
- Fix a frame size bug in player_example
|
||||
- Add support for passing a buffer the size of the picture
|
||||
region, rather than a full padded frame to th_encode_ycbcr_in()
|
||||
as was possible with the legacy pre-1.0 API.
|
||||
- 4:4:4 support in player_example using software yuv->rgb
|
||||
- Better rgb->yuv conversion in png2theora
|
||||
- Clean up warnings and local variables
|
||||
- Build and documentation fixes
|
||||
|
||||
libtheora 1.1.1 (2009 October 1)
|
||||
|
||||
- Fix problems with MSVC inline assembly
|
||||
- Add the missing encoder_disabled.c to the distribution
|
||||
- build updates: autogen.sh should work better after switching systems
|
||||
and the MSVC project now defaults to the dynamic runtime library
|
||||
- Namespace some variables to avoid conflicts on wince.
|
||||
|
||||
libtheora 1.1.0 (2009 September 24)
|
||||
|
||||
- Fix various small issues with the example and telemetry code
|
||||
- Fix handing a zero-byte packet as the first frame
|
||||
- Documentation cleanup
|
||||
- Two minor build fixes
|
||||
|
||||
libtheora 1.1beta3 (2009 August 22)
|
||||
|
||||
- Rate control fixes to smooth quality
|
||||
- MSVC build now exports all of the 1.0 api
|
||||
- Assorted small bug fixes
|
||||
|
||||
libtheora 1.1beta2 (2009 August 12)
|
||||
|
||||
- Fix a rate control problem with difficult input
|
||||
- Build fixes for OpenBSD and Apple Xcode
|
||||
- Examples now all use the 1.0 api
|
||||
- TH_ENCCTL_SET_SPLEVEL works again
|
||||
- Various bug fixes and source tree rearrangement
|
||||
|
||||
libtheora 1.1beta1 (2009 August 5)
|
||||
|
||||
- Support for two-pass encoding
|
||||
- Performance optimization of both encoder and decoder
|
||||
- Encoder supports dynamic adjustment of quality and
|
||||
bitrate targets
|
||||
- Encoder is generally more configurable, and all
|
||||
rate control modes perform better
|
||||
- Encoder now accepts 4:2:2 and 4:4:4 chroma sampling
|
||||
- Decoder telemetry output shows quantization choice
|
||||
and a breakdown of bitrate usage in the frame
|
||||
- MSVC assembly optimizations up to date and functional
|
||||
|
||||
libtheora 1.1alpha2 (2009 May 26)
|
||||
|
||||
- Reduce lambda for small quantizers.
|
||||
- New encoder fDCT does better on smooth gradients
|
||||
- Use SATD for mode decisions (1-2% bitrate reduction)
|
||||
- Assembly rewrite for new features and general speed up
|
||||
- Share code between the encoder and decoder for performance
|
||||
- Fix 4:2:2 decoding and telemetry
|
||||
- MSVC project files updated, but assembly is disabled.
|
||||
- New configure option --disable-spec to work around toolchain
|
||||
detection failures.
|
||||
- Limit symbol exports on MacOS X.
|
||||
- Port remaining unit tests from the 1.0 release.
|
||||
|
||||
libtheora 1.1alpha1 (2009 March 27)
|
||||
|
||||
- Encoder rewrite with much improved vbr quality/bitrate and
|
||||
better tracking of the target rate in cbr mode.
|
||||
- MSVC project files do not work in this release.
|
||||
|
||||
libtheora 1.0 (2008 November 3)
|
||||
|
||||
- Merge x86 assembly for forward DCT from Thusnelda branch.
|
||||
- Update 32 bit MMX with loop filter fix.
|
||||
- Check for an uninitialized state before dereferencing in propagating
|
||||
decode calls.
|
||||
- Remove all TH_DEBUG statements.
|
||||
- Rename the bitpacker source files copied from libogg to avoid
|
||||
confusing simple build systems using both libraries.
|
||||
- Declare bitfield entries to be explicitly signed for Solaris cc.
|
||||
- Set quantization parameters to default values when an empty buffer is
|
||||
passed with TH_ENCCTL_SET_QUANT_PARAMS.
|
||||
- Split encoder and decoder tests depending on configure settings.
|
||||
- Return lstylex.sty to the distribution.
|
||||
- Disable inline assembly on gcc versions prior to 3.1.
|
||||
- Remove extern references for OC_*_QUANT_MIN.
|
||||
- Make various data tables static const so they can be read-only.
|
||||
- Remove ENCCTL codes from the old encoder API.
|
||||
- Implement TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE ctl.
|
||||
- Fix segfault when exactly one of the width or height is not a multiple
|
||||
of 16, but the other is.
|
||||
- Compute the correct vertical offset for chroma.
|
||||
- cpuid assembly fix for MSVC.
|
||||
- Add VS2008 project files.
|
||||
- Build updates for 64-bit platforms, Mingw32, VS and XCode.
|
||||
- Do not clobber the cropping rectangle.
|
||||
- Declare ourselves 1.0final to pkg-config to sort after beta releases.
|
||||
- Fix the scons build to include asm in libtheoradec/enc.
|
||||
|
||||
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 noticeable 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
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(theora)
|
||||
|
||||
option(THEORA_BUILD_SHARED "Build shared libtheora" OFF)
|
||||
option(THEORA_BUILD_STATIC "Build static libtheora" ON)
|
||||
|
||||
set(THEORA_SRC
|
||||
lib/analyze.c
|
||||
lib/apiwrapper.c
|
||||
lib/bitpack.c
|
||||
lib/cpu.c
|
||||
lib/decapiwrapper.c
|
||||
lib/decinfo.c
|
||||
lib/decode.c
|
||||
lib/dequant.c
|
||||
lib/encapiwrapper.c
|
||||
lib/encfrag.c
|
||||
lib/encinfo.c
|
||||
lib/encode.c
|
||||
lib/encoder_disabled.c
|
||||
lib/enquant.c
|
||||
lib/fdct.c
|
||||
lib/fragment.c
|
||||
lib/huffdec.c
|
||||
lib/huffenc.c
|
||||
lib/idct.c
|
||||
lib/info.c
|
||||
lib/internal.c
|
||||
lib/mathops.c
|
||||
lib/mcenc.c
|
||||
lib/quant.c
|
||||
lib/rate.c
|
||||
lib/state.c
|
||||
lib/tokenize.c
|
||||
)
|
||||
|
||||
if(THEORA_BUILD_STATIC)
|
||||
add_library(theora-static STATIC ${THEORA_SRC})
|
||||
target_include_directories(theora-static PUBLIC include lib)
|
||||
target_link_libraries(theora-static ${OGG_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(THEORA_BUILD_SHARED)
|
||||
add_library(theora SHARED ${THEORA_SRC} lib/theora.def)
|
||||
target_include_directories(theora PUBLIC include lib)
|
||||
target_link_libraries(theora ${OGG_LIBRARY})
|
||||
endif()
|
||||
@@ -0,0 +1,28 @@
|
||||
Copyright (C) 2002-2009 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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,35 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign 1.11 dist-zip dist-xz
|
||||
|
||||
if THEORA_ENABLE_EXAMPLES
|
||||
EXAMPLES_DIR = examples
|
||||
else
|
||||
EXAMPLES_DIR =
|
||||
endif
|
||||
|
||||
SUBDIRS = lib include doc tests m4 $(EXAMPLES_DIR)
|
||||
|
||||
|
||||
# we include the whole debian/ dir in EXTRA_DIST because there's a problem
|
||||
# with autotools and HFS+ MacOSX file systems that caused debian/Makefile.am
|
||||
# to pick up on the lowercase changelog file and add ChangeLog to DIST_COMMON
|
||||
# because of it, breaking make dist. This works just as well.
|
||||
EXTRA_DIST = \
|
||||
README CHANGES COPYING LICENSE \
|
||||
autogen.sh win32 macosx symbian SConstruct \
|
||||
libtheora.spec libtheora.spec.in \
|
||||
theora-uninstalled.pc.in
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = theora.pc theoradec.pc theoraenc.pc
|
||||
|
||||
# Remove the .svn folders included in the tarball
|
||||
dist-hook:
|
||||
find $(distdir) -type d -name '.svn' | xargs rm -rf
|
||||
|
||||
debug:
|
||||
$(MAKE) all CFLAGS="@DEBUG@"
|
||||
|
||||
profile:
|
||||
$(MAKE) all CFLAGS="@PROFILE@"
|
||||
@@ -0,0 +1,152 @@
|
||||
-------------------------------------------------------------------------
|
||||
The Xiph.org Foundation's libtheora 1.1
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
*** 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, adds new features
|
||||
while allow it a longer useful lifetime as an competitive codec.
|
||||
|
||||
The 1.0 release decoder supported all the new features, but the
|
||||
encoder is nearly identical to the VP3 code.
|
||||
|
||||
The 1.1 release features a completely rewritten encoder, offering
|
||||
better performance and compression, and making more complete use
|
||||
of the format's feature set. Files produced by both encoders can
|
||||
be decoded by either release.
|
||||
|
||||
*** 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.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
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 creating a source distribution package:
|
||||
|
||||
as above,
|
||||
|
||||
Doxygen to build the API documentation,
|
||||
pdflatex and fig2dev to build the format specification
|
||||
(transfig package in Ubuntu).
|
||||
|
||||
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.
|
||||
|
||||
Windows build support is included in the win32 directory.
|
||||
|
||||
Project files for Apple XCode are included in the macosx 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
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
# see http://www.scons.org if you do not have this tool
|
||||
from os.path import join
|
||||
import SCons
|
||||
|
||||
# TODO: should use lamda and map to work on python 1.5
|
||||
def path(prefix, list): return [join(prefix, x) for x in list]
|
||||
|
||||
encoder_sources = """
|
||||
apiwrapper.c
|
||||
fragment.c
|
||||
idct.c
|
||||
internal.c
|
||||
state.c
|
||||
quant.c
|
||||
analyze.c
|
||||
encfrag.c
|
||||
encapiwrapper.c
|
||||
encinfo.c
|
||||
encode.c
|
||||
enquant.c
|
||||
fdct.c
|
||||
huffenc.c
|
||||
mathops.c
|
||||
mcenc.c
|
||||
rate.c
|
||||
tokenize.c
|
||||
"""
|
||||
|
||||
decoder_sources = """
|
||||
apiwrapper.c
|
||||
bitpack.c
|
||||
decapiwrapper.c
|
||||
decinfo.c
|
||||
decode.c
|
||||
dequant.c
|
||||
fragment.c
|
||||
huffdec.c
|
||||
idct.c
|
||||
info.c
|
||||
internal.c
|
||||
quant.c
|
||||
state.c
|
||||
"""
|
||||
|
||||
env = Environment()
|
||||
if env['CC'] == 'gcc':
|
||||
env.Append(CCFLAGS=["-g", "-O2", "-Wall", "-Wno-parentheses"])
|
||||
|
||||
def CheckPKGConfig(context, version):
|
||||
context.Message( 'Checking for pkg-config... ' )
|
||||
ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0]
|
||||
context.Result( ret )
|
||||
return ret
|
||||
|
||||
def CheckPKG(context, name):
|
||||
context.Message( 'Checking for %s... ' % name )
|
||||
ret = context.TryAction('pkg-config --exists %s' % name)[0]
|
||||
context.Result( ret )
|
||||
return ret
|
||||
|
||||
def CheckSDL(context):
|
||||
name = "sdl-config"
|
||||
context.Message( 'Checking for %s... ' % name )
|
||||
ret = SCons.Util.WhereIs('sdl-config')
|
||||
context.Result( ret )
|
||||
return ret
|
||||
|
||||
# check for appropriate inline asm support
|
||||
host_x86_32_test = """
|
||||
int main(int argc, char **argv) {
|
||||
#if !defined(__i386__)
|
||||
#error not an x86 host: preprocessor macro __i386__ not defined
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
def CheckHost_x86_32(context):
|
||||
context.Message('Checking for an x86 host...')
|
||||
result = context.TryCompile(host_x86_32_test, '.c')
|
||||
context.Result(result)
|
||||
return result
|
||||
|
||||
host_x86_64_test = """
|
||||
int main(int argc, char **argv) {
|
||||
#if !defined(__x86_64__)
|
||||
#error not an x86_64 host: preprocessor macro __x86_64__ not defined
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
def CheckHost_x86_64(context):
|
||||
context.Message('Checking for an x86_64 host...')
|
||||
result = context.TryCompile(host_x86_64_test, '.c')
|
||||
context.Result(result)
|
||||
return result
|
||||
|
||||
conf = Configure(env, custom_tests = {
|
||||
'CheckPKGConfig' : CheckPKGConfig,
|
||||
'CheckPKG' : CheckPKG,
|
||||
'CheckSDL' : CheckSDL,
|
||||
'CheckHost_x86_32' : CheckHost_x86_32,
|
||||
'CheckHost_x86_64' : CheckHost_x86_64,
|
||||
})
|
||||
|
||||
if not conf.CheckPKGConfig('0.15.0'):
|
||||
print 'pkg-config >= 0.15.0 not found.'
|
||||
Exit(1)
|
||||
|
||||
if not conf.CheckPKG('ogg'):
|
||||
print 'libogg not found.'
|
||||
Exit(1)
|
||||
|
||||
if conf.CheckPKG('vorbis vorbisenc'):
|
||||
have_vorbis=True
|
||||
else:
|
||||
have_vorbis=False
|
||||
|
||||
if conf.CheckPKG('libpng'):
|
||||
have_libpng=True
|
||||
else:
|
||||
have_libpng=False
|
||||
|
||||
build_player_example=True
|
||||
if not conf.CheckHeader('sys/soundcard.h'):
|
||||
build_player_example=False
|
||||
if build_player_example and not conf.CheckSDL():
|
||||
build_player_example=False
|
||||
|
||||
if conf.CheckHost_x86_32():
|
||||
env.Append(CPPDEFINES='OC_X86_ASM')
|
||||
decoder_sources += """
|
||||
x86/mmxidct.c
|
||||
x86/mmxfrag.c
|
||||
x86/mmxstate.c
|
||||
x86/x86state.c
|
||||
"""
|
||||
encoder_sources += """
|
||||
x86/mmxencfrag.c
|
||||
x86/mmxfdct.c
|
||||
x86/x86enc.c
|
||||
x86/mmxfrag.c
|
||||
x86/mmxidct.c
|
||||
x86/mmxstate.c
|
||||
x86/x86state.c
|
||||
"""
|
||||
elif conf.CheckHost_x86_64():
|
||||
env.Append(CPPDEFINES=['OC_X86_ASM', 'OC_X86_64_ASM'])
|
||||
decoder_sources += """
|
||||
x86/mmxidct.c
|
||||
x86/mmxfrag.c
|
||||
x86/mmxstate.c
|
||||
x86/x86state.c
|
||||
"""
|
||||
encoder_sources += """
|
||||
x86/mmxencfrag.c
|
||||
x86/mmxfdct.c
|
||||
x86/x86enc.c
|
||||
x86/sse2fdct.c
|
||||
x86/mmxfrag.c
|
||||
x86/mmxidct.c
|
||||
x86/mmxstate.c
|
||||
x86/x86state.c
|
||||
"""
|
||||
|
||||
env = conf.Finish()
|
||||
|
||||
env.Append(CPPPATH=['include'])
|
||||
env.ParseConfig('pkg-config --cflags --libs ogg')
|
||||
|
||||
libtheoradec_Sources = Split(decoder_sources)
|
||||
libtheoraenc_Sources = Split(encoder_sources)
|
||||
|
||||
libtheoradec_a = env.Library('lib/theoradec',
|
||||
path('lib', libtheoradec_Sources))
|
||||
libtheoradec_so = env.SharedLibrary('lib/theoradec',
|
||||
path('lib', libtheoradec_Sources))
|
||||
|
||||
libtheoraenc_a = env.Library('lib/theoraenc',
|
||||
path('lib', libtheoraenc_Sources))
|
||||
libtheoraenc_so = env.SharedLibrary('lib/theoraenc',
|
||||
path('lib', libtheoraenc_Sources) + [libtheoradec_so])
|
||||
|
||||
#installing
|
||||
prefix='/usr'
|
||||
lib_dir = prefix + '/lib'
|
||||
env.Alias('install', prefix)
|
||||
env.Install(lib_dir, [libtheoradec_a, libtheoradec_so])
|
||||
env.Install(lib_dir, [libtheoraenc_a, libtheoraenc_so])
|
||||
|
||||
# example programs
|
||||
dump_video = env.Clone()
|
||||
dump_video_Sources = Split("""dump_video.c ../lib/libtheoradec.a""")
|
||||
dump_video.Program('examples/dump_video', path('examples', dump_video_Sources))
|
||||
|
||||
dump_psnr = env.Clone()
|
||||
dump_psnr.Append(LIBS='m')
|
||||
dump_psnr_Sources = Split("""dump_psnr.c ../lib/libtheoradec.a""")
|
||||
dump_psnr.Program('examples/dump_psnr', path('examples', dump_psnr_Sources))
|
||||
|
||||
if have_vorbis:
|
||||
encex = dump_video.Clone()
|
||||
encex.ParseConfig('pkg-config --cflags --libs vorbisenc vorbis')
|
||||
encex_Sources = Split("""
|
||||
encoder_example.c
|
||||
../lib/libtheoraenc.a
|
||||
../lib/libtheoradec.a
|
||||
""")
|
||||
encex.Program('examples/encoder_example', path('examples', encex_Sources))
|
||||
|
||||
if build_player_example:
|
||||
plyex = encex.Clone()
|
||||
plyex_Sources = Split("""
|
||||
player_example.c
|
||||
../lib/libtheoradec.a
|
||||
""")
|
||||
plyex.ParseConfig('sdl-config --cflags --libs')
|
||||
plyex.Program('examples/player_example', path('examples', plyex_Sources))
|
||||
|
||||
png2theora = env.Clone()
|
||||
png2theora_Sources = Split("""png2theora.c
|
||||
../lib/libtheoraenc.a
|
||||
../lib/libtheoradec.a
|
||||
""")
|
||||
png2theora.ParseConfig('pkg-config --cflags --libs libpng')
|
||||
png2theora.Program('examples/png2theora', path('examples', png2theora_Sources))
|
||||
@@ -0,0 +1,130 @@
|
||||
#!/bin/sh
|
||||
# Run this to set up the build system: configure, makefiles, etc.
|
||||
# (based on the version in enlightenment's cvs)
|
||||
|
||||
package="theora"
|
||||
|
||||
ACLOCAL_FLAGS="-I m4"
|
||||
|
||||
olddir=`pwd`
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
cd "$srcdir"
|
||||
DIE=0
|
||||
|
||||
/bin/echo "checking for autoconf... "
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have autoconf installed to compile $package."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/"
|
||||
VERSIONMKMAJ="sed -e s/\([0-9][0-9]*\)[^0-9].*/\\1/"
|
||||
VERSIONMKMIN="sed -e s/.*[0-9][0-9]*\.//"
|
||||
|
||||
# do we need automake?
|
||||
if test -r Makefile.am; then
|
||||
AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am`
|
||||
AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP`
|
||||
if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then
|
||||
AM_NEEDED=""
|
||||
fi
|
||||
if test -z $AM_NEEDED; then
|
||||
/bin/echo -n "checking for automake... "
|
||||
AUTOMAKE=automake
|
||||
ACLOCAL=aclocal
|
||||
if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then
|
||||
/bin/echo "yes"
|
||||
else
|
||||
/bin/echo "no"
|
||||
AUTOMAKE=
|
||||
fi
|
||||
else
|
||||
/bin/echo -n "checking for automake $AM_NEEDED or later... "
|
||||
majneeded=`echo $AM_NEEDED | $VERSIONMKMAJ`
|
||||
minneeded=`echo $AM_NEEDED | $VERSIONMKMIN`
|
||||
for am in automake-$AM_NEEDED automake$AM_NEEDED \
|
||||
automake automake-1.7 automake-1.8 automake-1.9 \
|
||||
automake-1.10 automake-1.11; do
|
||||
($am --version < /dev/null > /dev/null 2>&1) || continue
|
||||
ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP`
|
||||
maj=`echo $ver | $VERSIONMKMAJ`
|
||||
min=`echo $ver | $VERSIONMKMIN`
|
||||
if test $maj -eq $majneeded -a $min -ge $minneeded; then
|
||||
AUTOMAKE=$am
|
||||
/bin/echo $AUTOMAKE
|
||||
break
|
||||
fi
|
||||
done
|
||||
test -z $AUTOMAKE && /bin/echo "no"
|
||||
/bin/echo -n "checking for aclocal $AM_NEEDED or later... "
|
||||
for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED \
|
||||
aclocal aclocal-1.7 aclocal-1.8 aclocal-1.9 aclocal-1.10 aclocal-1.11; do
|
||||
($ac --version < /dev/null > /dev/null 2>&1) || continue
|
||||
ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP`
|
||||
maj=`echo $ver | $VERSIONMKMAJ`
|
||||
min=`echo $ver | $VERSIONMKMIN`
|
||||
if test $maj -eq $majneeded -a $min -ge $minneeded; then
|
||||
ACLOCAL=$ac
|
||||
/bin/echo $ACLOCAL
|
||||
break
|
||||
fi
|
||||
done
|
||||
test -z $ACLOCAL && /bin/echo "no"
|
||||
fi
|
||||
test -z $AUTOMAKE || test -z $ACLOCAL && {
|
||||
echo
|
||||
echo "You must have automake installed to compile $package."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
/bin/echo -n "checking for libtool... "
|
||||
for LIBTOOLIZE in libtoolize glibtoolize nope; do
|
||||
($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break
|
||||
done
|
||||
if test x$LIBTOOLIZE = xnope; then
|
||||
/bin/echo "nope."
|
||||
LIBTOOLIZE=libtoolize
|
||||
else
|
||||
/bin/echo $LIBTOOLIZE
|
||||
fi
|
||||
($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have libtool installed to compile $package."
|
||||
echo "Download the appropriate package for your system,"
|
||||
echo "or get the source from one of the GNU ftp sites"
|
||||
echo "listed in http://www.gnu.org/order/ftp.html"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "I am going to run ./configure with no arguments - if you wish "
|
||||
echo "to pass any to it, please specify them on the $0 command line."
|
||||
fi
|
||||
|
||||
/bin/echo "Generating configuration files for $package, please wait...."
|
||||
|
||||
/bin/echo " $ACLOCAL $ACLOCAL_FLAGS"
|
||||
$ACLOCAL $ACLOCAL_FLAGS || exit 1
|
||||
/bin/echo " $LIBTOOLIZE --automake --force"
|
||||
$LIBTOOLIZE --automake --force || exit 1
|
||||
/bin/echo " autoheader"
|
||||
autoheader || exit 1
|
||||
/bin/echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
|
||||
$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
|
||||
/bin/echo " autoconf"
|
||||
autoconf || exit 1
|
||||
|
||||
cd $olddir
|
||||
$srcdir/configure --enable-maintainer-mode "$@" && /bin/echo
|
||||
@@ -0,0 +1,531 @@
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
|
||||
dnl ------------------------------------------------
|
||||
dnl Initialization and Versioning
|
||||
dnl ------------------------------------------------
|
||||
|
||||
AC_INIT(libtheora,[1.1.1+svn])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_SRCDIR([lib/fdct.c])
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl Library versioning
|
||||
dnl CURRENT, REVISION, AGE
|
||||
dnl - library source changed -> increment REVISION
|
||||
dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0
|
||||
dnl - interfaces added -> increment AGE
|
||||
dnl - interfaces removed -> AGE = 0
|
||||
|
||||
TH_LIB_CURRENT=3
|
||||
TH_LIB_REVISION=10
|
||||
TH_LIB_AGE=3
|
||||
AC_SUBST(TH_LIB_CURRENT)
|
||||
AC_SUBST(TH_LIB_REVISION)
|
||||
AC_SUBST(TH_LIB_AGE)
|
||||
|
||||
THDEC_LIB_CURRENT=2
|
||||
THDEC_LIB_REVISION=4
|
||||
THDEC_LIB_AGE=1
|
||||
AC_SUBST(THDEC_LIB_CURRENT)
|
||||
AC_SUBST(THDEC_LIB_REVISION)
|
||||
AC_SUBST(THDEC_LIB_AGE)
|
||||
|
||||
THENC_LIB_CURRENT=2
|
||||
THENC_LIB_REVISION=2
|
||||
THENC_LIB_AGE=1
|
||||
AC_SUBST(THENC_LIB_CURRENT)
|
||||
AC_SUBST(THENC_LIB_REVISION)
|
||||
AC_SUBST(THENC_LIB_AGE)
|
||||
|
||||
dnl Extra linker options (for version script)
|
||||
THEORA_LDFLAGS=""
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Check for programs
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl save $CFLAGS since AC_PROG_CC likes to insert "-g -O2"
|
||||
dnl if $CFLAGS is blank
|
||||
cflags_save="$CFLAGS"
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
CFLAGS="$cflags_save"
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
dnl Add parameters for aclocal
|
||||
AC_SUBST(ACLOCAL_AMFLAGS, "-I m4")
|
||||
|
||||
dnl Check for doxygen
|
||||
AC_ARG_ENABLE([doc],
|
||||
AS_HELP_STRING([--enable-doc], [Build API documentation]),
|
||||
[ac_enable_doc=$enableval], [ac_enable_doc=auto])
|
||||
|
||||
if test "x$ac_enable_doc" != "xno"; then
|
||||
AC_CHECK_PROG(HAVE_DOXYGEN, doxygen, true, false)
|
||||
|
||||
if test "x$HAVE_DOXYGEN" = "xfalse" -a "x$ac_enable_doc" = "xyes"; then
|
||||
AC_MSG_ERROR([*** API documentation explicitly requested but Doxygen not found])
|
||||
fi
|
||||
else
|
||||
HAVE_DOXYGEN=false
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_DOXYGEN,$HAVE_DOXYGEN)
|
||||
if test $HAVE_DOXYGEN = "false"; then
|
||||
AC_MSG_WARN([*** doxygen not found, API documentation will not be built])
|
||||
fi
|
||||
|
||||
dnl Check for tools used to build the format specification
|
||||
BUILD_SPEC="false"
|
||||
ac_build_spec=no
|
||||
AC_ARG_ENABLE(spec,
|
||||
AS_HELP_STRING([--enable-spec], [(re)build the specification document]),
|
||||
[
|
||||
if test "x$enableval" = "xyes"; then
|
||||
ac_build_spec=$enableval
|
||||
fi
|
||||
], [
|
||||
ac_build_spec=no
|
||||
] )
|
||||
if test "x$ac_build_spec" = "xyes"; then
|
||||
AC_CHECK_PROG(HAVE_PDFLATEX, pdflatex, yes)
|
||||
AC_CHECK_PROG(HAVE_BIBTEX, bibtex, yes)
|
||||
AC_CHECK_PROG(HAVE_TRANSFIG, fig2dev, yes)
|
||||
if test -r doc/spec/spec.tex; then
|
||||
if test "x$HAVE_PDFLATEX" = "xyes"; then
|
||||
if test "x$HAVE_BIBTEX" = "xyes"; then
|
||||
if test "x$HAVE_TRANSFIG" = "xyes"; then
|
||||
tex_pkg_list=`fgrep usepackage doc/spec/spec.tex | grep \{ | grep -v ltablex`
|
||||
tex_pkg_ok="yes"
|
||||
for pkg_line in $tex_pkg_list; do
|
||||
pkg_name=`echo $pkg_line | sed -e 's/.*{\(.*\)}.*/\1/'`
|
||||
AC_MSG_CHECKING([for Tex package $pkg_name])
|
||||
cat >conftest.tex <<_ACEOF
|
||||
\\documentclass{book}
|
||||
$pkg_line
|
||||
\\begin{document}
|
||||
Hello World.
|
||||
\\end{document}
|
||||
_ACEOF
|
||||
if pdflatex -interaction batchmode -halt-on-error conftest < /dev/null > /dev/null 2>&1; then
|
||||
AC_MSG_RESULT([ok])
|
||||
else
|
||||
tex_pkg_ok="no"
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
done
|
||||
if test -w conftest.tex; then rm conftest.tex; fi
|
||||
if test -w conftest.tex; then rm conftest.aux; fi
|
||||
if test -w conftest.pdf; then rm conftest.pdf; fi
|
||||
if test "x$tex_pkg_ok" = "xyes"; then
|
||||
BUILD_SPEC="true"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_SPEC, $BUILD_SPEC)
|
||||
if test $BUILD_SPEC = "false"; then
|
||||
AC_MSG_WARN([*** Format Specification will not built.])
|
||||
fi
|
||||
|
||||
dnl Check for valgrind
|
||||
VALGRIND_ENVIRONMENT=""
|
||||
ac_enable_valgrind=no
|
||||
AC_ARG_ENABLE(valgrind-testing,
|
||||
AS_HELP_STRING([--enable-valgrind-testing], [Enable running of tests inside Valgrind]),
|
||||
[ ac_enable_valgrind=$enableval ], [ ac_enable_valgrind=no] )
|
||||
|
||||
if test "x${ac_enable_valgrind}" = xyes ; then
|
||||
if test "x${enable_shared}" = xyes ; then
|
||||
VALGRIND_ENVIRONMENT="libtool --mode=execute "
|
||||
fi
|
||||
|
||||
AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
|
||||
if test "x$HAVE_VALGRIND" = xyes ; then
|
||||
VALGRIND_ENVIRONMENT="$VALGRIND_ENVIRONMENT valgrind -q --leak-check=yes --show-reachable=yes --num-callers=100"
|
||||
AC_SUBST(VALGRIND_ENVIRONMENT)
|
||||
TESTS_INFO="Type 'make check' to run test suite. Tests will be run under:
|
||||
${VALGRIND_ENVIRONMENT}"
|
||||
else
|
||||
TESTS_INFO="Type 'make check' to run test suite (Valgrind not found)"
|
||||
fi
|
||||
else
|
||||
TESTS_INFO="Type 'make check' to run test suite (Valgrind testing not enabled)"
|
||||
fi
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Set build flags based on environment
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl Set some target options
|
||||
|
||||
cflags_save="$CFLAGS"
|
||||
if test -z "$GCC"; then
|
||||
case $host in
|
||||
*)
|
||||
DEBUG="-g -DDEBUG"
|
||||
CFLAGS="-O"
|
||||
PROFILE="-g -p -DDEBUG" ;;
|
||||
esac
|
||||
else
|
||||
|
||||
case $host in
|
||||
*)
|
||||
DEBUG="-g -Wall -Wno-parentheses -DDEBUG -D__NO_MATH_INLINES"
|
||||
CFLAGS="-Wall -Wno-parentheses -O3 -fforce-addr -fomit-frame-pointer -finline-functions -funroll-loops"
|
||||
PROFILE="-Wall -Wno-parentheses -pg -g -O3 -fno-inline-functions -DDEBUG";;
|
||||
esac
|
||||
fi
|
||||
CFLAGS="$CFLAGS $cflags_save"
|
||||
|
||||
cpu_x86_64=no
|
||||
cpu_x86_32=no
|
||||
AC_ARG_ENABLE(asm,
|
||||
AS_HELP_STRING([--disable-asm], [Disable assembly optimizations]),
|
||||
[ ac_enable_asm=$enableval ], [ ac_enable_asm=yes] )
|
||||
|
||||
if test "x${ac_enable_asm}" = xyes; then
|
||||
cpu_optimization="no optimization for your platform, please send a patch"
|
||||
case $target_cpu in
|
||||
i[[3456]]86)
|
||||
cpu_x86_32=yes
|
||||
cpu_optimization="32 bit x86"
|
||||
AC_DEFINE([OC_X86_ASM], [], [make use of x86 asm optimization])
|
||||
if test "x$target_vendor" = "xapple"; then
|
||||
THEORA_LDFLAGS="$THEORA_LDFLAGS -Wl,-read_only_relocs,suppress"
|
||||
fi
|
||||
;;
|
||||
x86_64)
|
||||
cpu_x86_64=yes
|
||||
cpu_optimization="64 bit x86"
|
||||
AC_DEFINE([OC_X86_ASM], [], [make use of x86 asm optimization])
|
||||
AC_DEFINE([OC_X86_64_ASM], [], [make use of x86_64 asm optimization])
|
||||
;;
|
||||
esac
|
||||
else
|
||||
cpu_optimization="disabled"
|
||||
fi
|
||||
AM_CONDITIONAL([CPU_x86_64], [test x$cpu_x86_64 = xyes])
|
||||
AM_CONDITIONAL([CPU_x86_32], [test x$cpu_x86_32 = xyes])
|
||||
|
||||
# Test whenever ld supports -version-script
|
||||
AC_PROG_LD
|
||||
AC_PROG_LD_GNU
|
||||
AC_MSG_CHECKING([how to control symbol export])
|
||||
|
||||
THDEC_VERSION_ARG=""
|
||||
THENC_VERSION_ARG=""
|
||||
TH_VERSION_ARG=""
|
||||
if test "x$lt_cv_prog_gnu_ld" = "xyes"; then
|
||||
case "$target_os" in
|
||||
*mingw*)
|
||||
THEORA_LDFLAGS="$THEORA_LDFLAGS -no-undefined"
|
||||
THDEC_VERSION_ARG="-export-symbols \$(top_srcdir)/win32/xmingw32/libtheoradec-all.def"
|
||||
THENC_VERSION_ARG="-export-symbols \$(top_srcdir)/win32/xmingw32/libtheoraenc-all.def"
|
||||
THENC_VERSION_ARG="$THENC_VERSION_ARG -ltheoradec"
|
||||
THC_VERSION_ARG="-export-symbols \$(top_srcdir)/win32/libtheora.def"
|
||||
AC_MSG_RESULT([-export-symbols])
|
||||
;;
|
||||
linux* | solaris* | gnu* | k*bsd*-gnu)
|
||||
THDEC_VERSION_ARG='-Wl,--version-script=$(srcdir)/Version_script-dec'
|
||||
THENC_VERSION_ARG='-Wl,--version-script=$(srcdir)/Version_script-enc'
|
||||
TH_VERSION_ARG='-Wl,--version-script=$(srcdir)/Version_script'
|
||||
AC_MSG_RESULT([--version-script])
|
||||
;;
|
||||
*)
|
||||
# build without versioning
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case "$target_os" in
|
||||
darwin*)
|
||||
THDEC_VERSION_ARG='-Wl,-exported_symbols_list,$(srcdir)/theoradec.exp'
|
||||
THENC_VERSION_ARG='-Wl,-exported_symbols_list,$(srcdir)/theoraenc.exp'
|
||||
TH_VERSION_ARG='-Wl,-exported_symbols_list,$(srcdir)/theora.exp'
|
||||
AC_MSG_RESULT([-exported_symbols_list])
|
||||
;;
|
||||
*)
|
||||
# build without versioning
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
THEORADEC_LDFLAGS="$THEORA_LDFLAGS $THDEC_VERSION_ARG"
|
||||
THEORAENC_LDFLAGS="$THEORA_LDFLAGS $THENC_VERSION_ARG"
|
||||
THEORA_LDFLAGS="$THEORA_LDFLAGS $TH_VERSION_ARG"
|
||||
AC_SUBST(THEORADEC_LDFLAGS)
|
||||
AC_SUBST(THEORAENC_LDFLAGS)
|
||||
AC_SUBST(THEORA_LDFLAGS)
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Checks for support libraries and headers
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl check for Ogg
|
||||
HAVE_OGG=no
|
||||
|
||||
dnl first check through pkg-config since it's more flexible
|
||||
|
||||
dnl check for pkg-config itself so we don't try the m4 macro without pkg-config
|
||||
AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes)
|
||||
if test "x$HAVE_PKG_CONFIG" = "xyes"
|
||||
then
|
||||
PKG_CHECK_MODULES(OGG, ogg >= 1.1, HAVE_OGG=yes, HAVE_OGG=no)
|
||||
fi
|
||||
if test "x$HAVE_OGG" = "xno"
|
||||
then
|
||||
dnl fall back to the old school test
|
||||
XIPH_PATH_OGG(, AC_MSG_ERROR([
|
||||
libogg is required to build this package!
|
||||
please see http://www.xiph.org/ for how to
|
||||
obtain a copy.
|
||||
]))
|
||||
cflags_save=$CFLAGS
|
||||
libs_save=$LIBS
|
||||
CFLAGS="$CFLAGS $OGG_CFLAGS"
|
||||
LIBS="$LIBS $OGG_LIBS"
|
||||
AC_CHECK_FUNC(oggpackB_read, , [
|
||||
AC_MSG_ERROR([newer libogg version (1.1 or later) required])
|
||||
])
|
||||
CFLAGS=$cflags_save
|
||||
LIBS=$libs_save
|
||||
fi
|
||||
|
||||
|
||||
dnl check for Vorbis
|
||||
HAVE_VORBIS=no
|
||||
|
||||
dnl first check through pkg-config since it's more flexible
|
||||
|
||||
if test "x$HAVE_PKG_CONFIG" = "xyes"
|
||||
then
|
||||
PKG_CHECK_MODULES(VORBIS, vorbis >= 1.0.1, HAVE_VORBIS=yes, HAVE_VORBIS=no)
|
||||
dnl also set VORBISENC_LIBS since an examples needs it
|
||||
dnl the old .m4 sets this to a value to use on top of VORBIS_LIBS,
|
||||
dnl so we do the same here.
|
||||
VORBISENC_LIBS="-lvorbisenc"
|
||||
AC_SUBST(VORBISENC_LIBS)
|
||||
fi
|
||||
if test "x$HAVE_VORBIS" = "xno"
|
||||
then
|
||||
dnl fall back to the old school test
|
||||
XIPH_PATH_VORBIS(HAVE_VORBIS=yes, HAVE_VORBIS=no)
|
||||
fi
|
||||
|
||||
dnl check for SDL
|
||||
HAVE_SDL=no
|
||||
|
||||
AM_PATH_SDL(,[
|
||||
HAVE_SDL=yes
|
||||
SDL_LIBS=`$SDL_CONFIG --libs`
|
||||
],AC_MSG_WARN([*** Unable to find SDL -- Not compiling example players ***]))
|
||||
|
||||
dnl check for OSS
|
||||
HAVE_OSS=no
|
||||
AC_CHECK_HEADERS([sys/soundcard.h soundcard.h machine/soundcard.h],[
|
||||
HAVE_OSS=yes
|
||||
break
|
||||
])
|
||||
if test x$HAVE_OSS != xyes; then
|
||||
AC_MSG_WARN([OSS audio support not found -- not compiling player_example])
|
||||
fi
|
||||
|
||||
dnl OpenBSD needs -lossaudio to use the oss interface
|
||||
OSS_LIBS=
|
||||
case "$target_os" in
|
||||
openbsd*)
|
||||
OSS_LIBS='-lossaudio'
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(OSS_LIBS)
|
||||
|
||||
dnl check for libpng
|
||||
HAVE_PNG=no
|
||||
if test "x$HAVE_PKG_CONFIG" = "xyes"
|
||||
then
|
||||
PKG_CHECK_MODULES(PNG, libpng, HAVE_PNG=yes, HAVE_PNG=no)
|
||||
fi
|
||||
AC_SUBST(PNG_CFLAGS)
|
||||
AC_SUBST(PNG_LIBS)
|
||||
|
||||
dnl check for libcairo
|
||||
HAVE_CAIRO=no
|
||||
AC_ARG_ENABLE(telemetry,
|
||||
AS_HELP_STRING([--enable-telemetry], [Enable debugging output controls]),
|
||||
[ ac_enable_telemetry=$enableval ], [ ac_enable_telemetry=no] )
|
||||
|
||||
if test "x${ac_enable_telemetry}" = xyes; then
|
||||
if test "x$HAVE_PKG_CONFIG" = "xyes"
|
||||
then
|
||||
PKG_CHECK_MODULES(CAIRO, cairo, HAVE_CAIRO=yes, HAVE_CAIRO=no)
|
||||
AC_DEFINE([HAVE_CAIRO], [], [libcairo is available for visual debugging output])
|
||||
fi
|
||||
if test x$HAVE_CAIRO != xyes; then
|
||||
AC_MSG_WARN([libcairo not found -- not compiling telemetry output support ])
|
||||
fi
|
||||
AC_SUBST(CAIRO_CFLAGS)
|
||||
AC_SUBST(CAIRO_LIBS)
|
||||
fi
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Overall build configuration options
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl Configuration option for building of floating point code.
|
||||
|
||||
ac_enable_float=yes
|
||||
AC_ARG_ENABLE(float,
|
||||
AS_HELP_STRING([--disable-float], [Disable use of floating point code]),
|
||||
[ ac_enable_float=$enableval ], [ ac_enable_float=yes] )
|
||||
|
||||
if test "x${ac_enable_float}" != xyes ; then
|
||||
AC_DEFINE([THEORA_DISABLE_FLOAT], [],
|
||||
[Define to exclude floating point code from the build])
|
||||
fi
|
||||
AM_CONDITIONAL(THEORA_DISABLE_FLOAT, [test "x${ac_enable_float}" != xyes])
|
||||
|
||||
dnl Configuration option for building of encoding support.
|
||||
|
||||
ac_enable_encode=yes
|
||||
AC_ARG_ENABLE(encode,
|
||||
AS_HELP_STRING([--disable-encode], [Disable encoding support]),
|
||||
[ ac_enable_encode=$enableval ], [ ac_enable_encode=yes] )
|
||||
|
||||
if test "x${ac_enable_encode}" != xyes ; then
|
||||
AC_DEFINE([THEORA_DISABLE_ENCODE], [],
|
||||
[Define to exclude encode support from the build])
|
||||
else
|
||||
if test x$HAVE_VORBIS = xyes; then
|
||||
BUILDABLE_EXAMPLES="$BUILDABLE_EXAMPLES encoder_example\$(EXEEXT)"
|
||||
else
|
||||
AC_MSG_NOTICE([Vorbis missing, cannot build example encoder])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(THEORA_DISABLE_ENCODE, [test "x${ac_enable_encode}" != xyes])
|
||||
|
||||
dnl Configuration option for examples
|
||||
|
||||
ac_enable_examples=yes
|
||||
AC_ARG_ENABLE(examples,
|
||||
AS_HELP_STRING([--disable-examples], [Disable examples]),
|
||||
[ ac_enable_examples=$enableval ], [ ac_enable_examples=yes] )
|
||||
AM_CONDITIONAL(THEORA_ENABLE_EXAMPLES, [test "x${ac_enable_examples}" != xno])
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Check for headers
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl none here
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Check for typedefs, structures, etc
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl none
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Check for library functions
|
||||
dnl --------------------------------------------------
|
||||
|
||||
dnl OpenBSD needs -lcompat for ftime() used by dump_video.c
|
||||
AC_SEARCH_LIBS([ftime], [compat])
|
||||
|
||||
dnl substitute the included getopt if the system doesn't support long options
|
||||
AC_CHECK_FUNC(getopt_long,
|
||||
[GETOPT_OBJS=''],
|
||||
[GETOPT_OBJS='getopt.$(OBJEXT) getopt1.$(OBJEXT)'])
|
||||
AC_SUBST(GETOPT_OBJS)
|
||||
|
||||
if test x$HAVE_SDL = xyes -a x$HAVE_OSS = xyes -a x$HAVE_VORBIS = xyes; then
|
||||
BUILDABLE_EXAMPLES="$BUILDABLE_EXAMPLES player_example\$(EXEEXT)"
|
||||
fi
|
||||
if test x$HAVE_PNG = xyes; then
|
||||
BUILDABLE_EXAMPLES="$BUILDABLE_EXAMPLES png2theora\$(EXEEXT)"
|
||||
fi
|
||||
AC_SUBST(BUILDABLE_EXAMPLES)
|
||||
|
||||
dnl --------------------------------------------------
|
||||
dnl Do substitutions
|
||||
dnl --------------------------------------------------
|
||||
|
||||
AC_SUBST(DEBUG)
|
||||
AC_SUBST(PROFILE)
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
lib/Makefile
|
||||
include/Makefile include/theora/Makefile
|
||||
examples/Makefile
|
||||
doc/Makefile doc/Doxyfile doc/spec/Makefile
|
||||
tests/Makefile
|
||||
m4/Makefile
|
||||
libtheora.spec
|
||||
theora.pc
|
||||
theora-uninstalled.pc
|
||||
theoradec.pc
|
||||
theoradec-uninstalled.pc
|
||||
theoraenc.pc
|
||||
theoraenc-uninstalled.pc
|
||||
])
|
||||
|
||||
AS_AC_EXPAND(LIBDIR, ${libdir})
|
||||
AS_AC_EXPAND(INCLUDEDIR, ${includedir})
|
||||
AS_AC_EXPAND(BINDIR, ${bindir})
|
||||
AS_AC_EXPAND(DOCDIR, ${docdir})
|
||||
|
||||
if test $HAVE_DOXYGEN = "false"; then
|
||||
doc_build="no"
|
||||
else
|
||||
doc_build="yes"
|
||||
fi
|
||||
if test $BUILD_SPEC = "false"; then
|
||||
spec_build="no"
|
||||
else
|
||||
spec_build="yes"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([
|
||||
------------------------------------------------------------------------
|
||||
$PACKAGE $VERSION: Automatic configuration OK.
|
||||
|
||||
General configuration:
|
||||
|
||||
Encoding support: ........... ${ac_enable_encode}
|
||||
Floating point support: ..... ${ac_enable_float}
|
||||
Assembly optimization: ...... ${cpu_optimization}
|
||||
Debugging telemetry: ........ ${ac_enable_telemetry}
|
||||
Build example code: ......... ${ac_enable_examples}
|
||||
API Documentation: .......... ${doc_build}
|
||||
Format Documentation: ....... ${spec_build}
|
||||
|
||||
Installation paths:
|
||||
|
||||
libtheora: ................... ${LIBDIR}
|
||||
C header files: .............. ${INCLUDEDIR}/theora
|
||||
Documentation: ............... ${DOCDIR}
|
||||
|
||||
Building:
|
||||
|
||||
Type 'make' to compile $PACKAGE.
|
||||
|
||||
Type 'make install' to install $PACKAGE.
|
||||
|
||||
${TESTS_INFO}
|
||||
|
||||
Example programs will be built but not installed.
|
||||
------------------------------------------------------------------------
|
||||
])
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
libtheora (0.0.0.alpha3-1) unstable; urgency=low
|
||||
|
||||
* Initial upload to Debian.
|
||||
|
||||
-- Christopher L Cheney <ccheney@debian.org> Tue, 29 Jun 2004 22:00:00 -0500
|
||||
|
||||
libtheora (0.0.0-0) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Christopher L Cheney <ccheney@debian.org> Wed, 25 Sep 2002 21:00:00 -0500
|
||||
|
||||
Local variables:
|
||||
mode: debian-changelog
|
||||
End:
|
||||
@@ -0,0 +1,24 @@
|
||||
Source: libtheora
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Maintainer: Christopher L Cheney <ccheney@debian.org>
|
||||
Build-Depends: cdbs, autotools-dev, debhelper (>> 4.0.0), devscripts, libogg-dev (>= 1.1.0), libvorbis-dev, python
|
||||
Standards-Version: 3.6.1.0
|
||||
|
||||
Package: libtheora0
|
||||
Architecture: any
|
||||
Section: libs
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: The Theora Video Compression Codec
|
||||
Ogg Theora
|
||||
|
||||
Package: libtheora-dev
|
||||
Architecture: any
|
||||
Section: libdevel
|
||||
Depends: libtheora0 (= ${Source-Version}), libogg-dev
|
||||
Description: The Theora Compression Codec (development files)
|
||||
Theora is a fully open, non-proprietary, patent-and-royalty-free,
|
||||
general-purpose compressed video format.
|
||||
.
|
||||
This package contains the header files and documentation needed to develop
|
||||
applications with libtheora.
|
||||
@@ -0,0 +1,38 @@
|
||||
This package was debianized by Christopher L Cheney <ccheney@debian.org> on
|
||||
Wed, 25 Sep 2002 21:00:00 -0500.
|
||||
|
||||
It was downloaded from http://svn.xiph.org/trunk/theora/
|
||||
|
||||
Upstream Authors: Xiph.Org Foundation
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (c) 2002-2009 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 REGENTS 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.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
debian/tmp/usr/include/theora/theora.h
|
||||
debian/tmp/usr/lib/libtheora.a
|
||||
debian/tmp/usr/lib/libtheora.la
|
||||
debian/tmp/usr/lib/libtheora.so
|
||||
debian/tmp/usr/lib/pkgconfig/theora.pc
|
||||
@@ -0,0 +1,2 @@
|
||||
debian/tmp/usr/lib/libtheora.so.0
|
||||
debian/tmp/usr/lib/libtheora.so.0.0.0
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/make -f
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
include /usr/share/cdbs/1/class/autotools.mk
|
||||
@@ -0,0 +1,3 @@
|
||||
version=2
|
||||
|
||||
http://downloads.xiph.org/releases/theora/libtheora-(.*)\.tar\.gz debian uupdate
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = spec
|
||||
|
||||
static_docs = vp3-format.txt color.html \
|
||||
draft-ietf-avt-rtp-theora-00.xml \
|
||||
draft-ietf-avt-rtp-theora-00.txt
|
||||
|
||||
doc_DATA = $(static_docs) doxygen-build.stamp
|
||||
|
||||
EXTRA_DIST = $(static_docs) Doxyfile.in
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
doxygen-build.stamp: Doxyfile $(top_srcdir)/include/theora/*.h
|
||||
doxygen
|
||||
touch doxygen-build.stamp
|
||||
else
|
||||
doxygen-build.stamp:
|
||||
echo "*** Warning: Doxygen not found; documentation will not be built."
|
||||
touch doxygen-build.stamp
|
||||
endif
|
||||
|
||||
dist_docdir = $(distdir)/libtheora
|
||||
|
||||
dist-hook:
|
||||
if test -d libtheora; then \
|
||||
mkdir $(dist_docdir); \
|
||||
echo -n "copying built documenation..."; \
|
||||
for dir in libtheora/*; do \
|
||||
b=`basename $$dir`; \
|
||||
if test $$b != ".svn"; then \
|
||||
if test -d $$dir; then \
|
||||
mkdir $(dist_docdir)/$$b; \
|
||||
for f in $$dir/*; do \
|
||||
cp -p $$f $(dist_docdir)/$$b; \
|
||||
done; \
|
||||
fi; \
|
||||
fi; \
|
||||
done; \
|
||||
echo "OK"; \
|
||||
fi
|
||||
for item in $(EXTRA_DIST); do \
|
||||
if test -d $$item; then \
|
||||
echo -n "cleaning $$item dir for distribution..."; \
|
||||
rm -rf `find $(distdir)/$$item -name .svn`; \
|
||||
echo "OK"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
|
||||
|
||||
install-data-local: doxygen-build.stamp
|
||||
$(mkinstalldirs) $(DESTDIR)$(docdir)
|
||||
if test -d libtheora; then \
|
||||
for dir in libtheora/*; do \
|
||||
if test -d $$dir; then \
|
||||
b=`basename $$dir`; \
|
||||
$(mkinstalldirs) $(DESTDIR)$(docdir)/$$b; \
|
||||
for f in $$dir/*; do \
|
||||
$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$b; \
|
||||
done \
|
||||
fi \
|
||||
done \
|
||||
fi
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(docdir)
|
||||
|
||||
clean-local:
|
||||
if test -d libtheora; then rm -rf libtheora; fi
|
||||
if test -f doxygen-build.stamp; then rm -f doxygen-build.stamp; fi
|
||||
|
||||
@@ -0,0 +1,602 @@
|
||||
<HTML>
|
||||
<HEAD><TITLE>xiph.org: Ogg Theora documentation</TITLE></HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF" TEXT="#202020" LINK="#006666" VLINK="#000000">
|
||||
<H1><FONT COLOR="#000070">
|
||||
Ogg Theora I specification: color space conventions
|
||||
</FONT></H1>
|
||||
<H1>Overview</H1>
|
||||
<P>
|
||||
There are a large number of different color standards used in digital video.
|
||||
Since Theora is a lossy codec, it restricts itself to only a few of them to
|
||||
simplify playback.
|
||||
Unlike the alternate method of describing all the parameters of the color
|
||||
model, this allows a few dedicated routines for color conversion to be written
|
||||
and heavily optimized in a decoder.
|
||||
More flexible conversion functions should instead be specified in an encoder,
|
||||
where additional computational complexity is more easily tolerated.
|
||||
The color spaces were selected to give a fair representation of color standards
|
||||
in use around the world today.
|
||||
Most of the standards that do not exactly match one of these can be converted
|
||||
to one fairly easily.
|
||||
</P>
|
||||
<P>
|
||||
The Theora codec identification header contains an 8-bit value that describes
|
||||
the color space.
|
||||
This merely selects one of the color spaces available from an enumerated list.
|
||||
Currently, only two color spaces are defined, with a third possibility that
|
||||
indicates the color space is "unknown".
|
||||
All of them are Y'C<SUB>b</SUB>C<SUB>r</SUB> color spaces with one luma channel
|
||||
and two chroma channels.
|
||||
Each channel contains 8-bit discrete values in the range 0-255, which represent
|
||||
non-linear gamma pre-corrected signals.
|
||||
</P>
|
||||
<H2>color space parameters</H2>
|
||||
<P>
|
||||
The parameters which describe each color space are listed below.
|
||||
These are the parameters needed to map colors from the encoded
|
||||
Y'C<SUB>b</SUB>C<SUB>r</SUB> representation to the device-independent color
|
||||
space CIE XYZ (1931).
|
||||
</P>
|
||||
<DL>
|
||||
<DT>Y'C<SUB>b</SUB>C<SUB>r</SUB> to Y'P<SUB>b</SUB>P<SUB>r</SUB></DT>
|
||||
<DD>
|
||||
<P>
|
||||
This conversion takes 8-bit discrete values in the range 0-255 and maps them to
|
||||
real values in the range [0,1] for Y and [-1/2,1/2] for P<SUB>b</SUB>
|
||||
and P<SUB>r</SUB>.
|
||||
Because some values may fall outside the offset and excursion defined for each
|
||||
channel in the Y'C<SUB>b</SUB>C<SUB>r</SUB> space, the results may fall
|
||||
outside these ranges in Y'P<SUB>b</SUB>P<SUB>r</SUB> space.
|
||||
No clamping should be done at this stage.
|
||||
</P>
|
||||
<P>
|
||||
Parameters: <EM>Offset<SUB>Y,C<SUB>b</SUB>,C<SUB>r</SUB></SUB></EM>,
|
||||
<EM>Excursion<SUB>Y,C<SUB>b</SUB>,C<SUB>r</SUB>,</SUB></EM>
|
||||
</P>
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">Y'<SUB>out</SUB></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
(Y'<SUB>in</SUB>-<EM>Offset<SUB>Y</SUB></EM>)/
|
||||
<EM>Excursion<SUB>Y</SUB></EM>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">P<SUB>b</SUB></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
(C<SUB>b</SUB>-<EM>Offset<SUB>C<SUB>b</SUB></SUB></EM>)/
|
||||
<EM>Excursion<SUB>C<SUB>b</SUB></SUB></EM>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">P<SUB>r</SUB></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
(C<SUB>r</SUB>-<EM>Offset<SUB>C<SUB>r</SUB></SUB></EM>)/
|
||||
<EM>Excursion<SUB>C<SUB>r</SUB></SUB></EM>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DD>
|
||||
<DT>Y'P<SUB>b</SUB>P<SUB>r</SUB> to R'G'B'</DT>
|
||||
<DD>
|
||||
<P>
|
||||
This conversion takes the one luma and two chroma channel representation and
|
||||
maps it to the non-linear R'G'B' space used to drive actual output devices.
|
||||
Values should be clamped into the range [0,1] after this stage.
|
||||
<P>
|
||||
Parameters: <EM>K<SUB>b</SUB></EM>, <EM>K<SUB>r</SUB></EM>
|
||||
</P>
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">R'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">Y' + 2(1-<EM>K<SUB>r</SUB></EM>)P<SUB>r</SUB></TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">G'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
Y' +
|
||||
2((<EM>K<SUB>b</SUB></EM>-1)<EM>K<SUB>b</SUB></EM>/
|
||||
(1-<EM>K<SUB>b</SUB></EM>-<EM>K<SUB>r</SUB></EM>))P<SUB>b</SUB> +
|
||||
2((<EM>K<SUB>r</SUB></EM>-1)<EM>K<SUB>r</SUB></EM>/
|
||||
(1-<EM>K<SUB>b</SUB></EM>-<EM>K<SUB>r</SUB></EM>))P<SUB>r</SUB>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">B'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">Y' + 2(1-<EM>K<SUB>b</SUB></EM>)P<SUB>b</SUB></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DD>
|
||||
<DT>R'G'B' to RGB (Output device gamma correction)</DT>
|
||||
<DD>
|
||||
<P>
|
||||
This conversion takes the non-linear R'G'B' voltage levels and maps it to the
|
||||
linear light levels produced by the actual output device.
|
||||
Note that this conversion is only that of the output device, and its inverse is
|
||||
<EM>not</EM> that used by the input device.
|
||||
Because a dim viewing environment is assumed in most television standards, the
|
||||
overall gamma between the input and output devices is usually around 1.1 to
|
||||
1.2, and not a strict 1.0.
|
||||
</P>
|
||||
<P>
|
||||
For calibration with actual output devices, the model
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">L</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">(E'+Δ)<SUP><EM>γ</EM></SUP></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
should be used, with Δ the free parameter and <EM>γ</EM> held
|
||||
fixed to the value specified in this document.
|
||||
The conversion function presented here is an idealized version with Δ=0.
|
||||
</P>
|
||||
<P>
|
||||
Parameters: <EM>γ</EM>
|
||||
</P>
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">R</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">R'<SUP><EM>γ</EM></SUP></TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">G</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">G'<SUP><EM>γ</EM></SUP></TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">B</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">B'<SUP><EM>γ</EM></SUP></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DD>
|
||||
<DT>RGB to R'G'B' (Input device gamma correction)</DT>
|
||||
<DD>
|
||||
<P>
|
||||
This conversion takes linear light levels and maps them to the non-linear
|
||||
voltage levels used to drive the actual output device.
|
||||
This information is merely informative.
|
||||
It is not required for building a decoder or for converting between the various
|
||||
formats and the actual output capabilities of a particular device.
|
||||
</P>
|
||||
<P>
|
||||
A linear segment is introduced on the low end to reduce noise in dark areas of
|
||||
the image.
|
||||
The rest of the scale is adjusted so that the power segment of the curve
|
||||
intersects the linear segment with the proper slope, and so that it still maps
|
||||
0 to 0 and 1 to 1.
|
||||
</P>
|
||||
<P>
|
||||
Parameters: <EM>β</EM>, <EM>α</EM>, <EM>δ</EM>,
|
||||
<EM>ε</EM>
|
||||
</P>
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">R'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
(1+<EM>ε</EM>)R<SUP>β</SUP>-<EM>ε</EM>
|
||||
</TD>
|
||||
<TD>for <EM>δ</EM> ≤ R ≤ 1</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">R'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT"><EM>α</EM>R</TD>
|
||||
<TD>for 0 ≤ R < <EM>δ</EM></TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">G'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
(1+<EM>ε</EM>)G<SUP>β</SUP>-<EM>ε</EM>
|
||||
</TD>
|
||||
<TD>for <EM>δ</EM> ≤ G ≤ 1</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">G'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT"><EM>α</EM>G</TD>
|
||||
<TD>for 0 ≤ G < <EM>δ</EM></TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">B'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">
|
||||
(1+<EM>ε</EM>)B<SUP>β</SUP>-<EM>ε</EM>
|
||||
</TD>
|
||||
<TD>for <EM>δ</EM> ≤ B ≤ 1</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">B'</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT"><EM>α</EM>B</TD>
|
||||
<TD>for 0 ≤ B < <EM>δ</EM></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DD>
|
||||
<DT>RGB to CIE XYZ (1931)</DT>
|
||||
<DD>
|
||||
<P>
|
||||
This conversion maps a device-dependent linear RGB space to the
|
||||
device-independent linear CIE XYZ space.
|
||||
The parameters are the CIE chromaticity coordinates of the three primaries,
|
||||
red, green, and blue, as well as the chromaticity coordinates of the white
|
||||
point of the device.
|
||||
This is how hardware manufacturers and standards typically describe a
|
||||
particular RGB space.
|
||||
The math required to convert these parameters into a useful transformation
|
||||
matrix is reproduced below.
|
||||
</P>
|
||||
<P>
|
||||
Parameters: <EM>x<SUB>r,g,b,w</SUB></EM>, <EM>y<SUB>r,g,b,w</SUB></EM>
|
||||
</P>
|
||||
<TABLE>
|
||||
<TR>
|
||||
<TD ALIGN="RIGHT">F</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT"><TABLE><TR>
|
||||
<TD><FONT SIZE="300%">(</FONT></TD>
|
||||
<TD><TABLE>
|
||||
<TR>
|
||||
<TD ALIGN="CENTER"><EM>x<SUB>r</SUB></EM>/<EM>y<SUB>r</SUB></EM></TD>
|
||||
<TD ALIGN="CENTER"><EM>x<SUB>g</SUB></EM>/<EM>y<SUB>g</SUB></EM></TD>
|
||||
<TD ALIGN="CENTER"><EM>x<SUB>b</SUB></EM>/<EM>y<SUB>b</SUB></EM></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN="CENTER">1</TD>
|
||||
<TD ALIGN="CENTER">1</TD>
|
||||
<TD ALIGN="CENTER">1</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN="CENTER">
|
||||
(1-<EM>x<SUB>r</SUB></EM>-<EM>y<SUB>r</SUB></EM>)/<EM>y<SUB>r</SUB></EM>
|
||||
</TD>
|
||||
<TD ALIGN="CENTER">
|
||||
(1-<EM>x<SUB>g</SUB></EM>-<EM>y<SUB>g</SUB></EM>)/<EM>y<SUB>g</SUB></EM>
|
||||
</TD>
|
||||
<TD ALIGN="CENTER">
|
||||
(1-<EM>x<SUB>b</SUB></EM>-<EM>y<SUB>b</SUB></EM>)/<EM>y<SUB>b</SUB></EM>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE></TD>
|
||||
<TD<FONT SIZE="300%">)</FONT></TD>
|
||||
</TR></TABLE></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN="RIGHT"><TABLE><TR>
|
||||
<TD><FONT SIZE="300%">(</FONT></TD>
|
||||
<TD><TABLE>
|
||||
<TR><TD ALIGN="CENTER">s<SUB>r</SUB></TD></TR>
|
||||
<TR><TD ALIGN="CENTER">s<SUB>g</SUB></TD></TR>
|
||||
<TR><TD ALIGN="CENTER">s<SUB>b</SUB></TD></TR>
|
||||
</TABLE></TD>
|
||||
<TD><FONT SIZE="300%">)</FONT></TD>
|
||||
</TR></TABLE></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT"><TABLE><TR>
|
||||
<TD>F<SUP>-1</SUP><FONT SIZE="300%">(</FONT></TD>
|
||||
<TD><TABLE>
|
||||
<TR><TD ALIGN="CENTER"><EM>x<SUB>w</SUB></EM>/<EM>y<SUB>w</SUB></EM></TD></TR>
|
||||
<TR><TD ALIGN="CENTER">1</TD></TR>
|
||||
<TR><TD ALIGN="CENTER">
|
||||
(1-<EM>x<SUB>w</SUB></EM>-<EM>y<SUB>w</SUB></EM>)/<EM>y<SUB>w</SUB></EM>
|
||||
</TD></TR>
|
||||
</TABLE></TD>
|
||||
<TD><FONT SIZE="300%">)</FONT></TD>
|
||||
</TR></TABLE></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD ALIGN="RIGHT"><TABLE><TR>
|
||||
<TD><FONT SIZE="300%">(</FONT></TD>
|
||||
<TD><TABLE>
|
||||
<TR><TD ALIGN="CENTER">X</TD></TR>
|
||||
<TR><TD ALIGN="CENTER">Y</TD></TR>
|
||||
<TR><TD ALIGN="CENTER">Z</TD></TR>
|
||||
</TABLE></TD>
|
||||
<TD><FONT SIZE="300%">)</FONT></TD>
|
||||
</TR></TABLE></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT"><TABLE><TR>
|
||||
<TD>F<FONT SIZE="300%">(</FONT></TD>
|
||||
<TD><TABLE>
|
||||
<TR><TD ALIGN="CENTER">s<SUB>r</SUB>R</TD></TR>
|
||||
<TR><TD ALIGN="CENTER">s<SUB>g</SUB>G</TD></TR>
|
||||
<TR><TD ALIGN="CENTER">s<SUB>b</SUB>B</TD></TR>
|
||||
</TABLE></TD>
|
||||
<TD><FONT SIZE="300%">)</FONT></TD>
|
||||
</TR></TABLE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DD>
|
||||
</DL>
|
||||
<H2>available color spaces</H2>
|
||||
<P>
|
||||
These are the color spaces currently defined for use by Ogg Theora video.
|
||||
Each one has a short name, with which it is referred to in this document, and
|
||||
a more detailed specification of the standards from which its parameters are
|
||||
derived.
|
||||
Some standards do not specify all the parameters necessary.
|
||||
For these unspecified parameters, this document serves as the definition of
|
||||
what should be used when encoding or decoding Ogg Theora video.
|
||||
<H3>Rec 470M (Rec. ITU-R BT.470-6 System M/NTSC with Rec. ITU-R BT.601-5)</H3>
|
||||
<P>
|
||||
This color space is used by broadcast television and DVDs in much of the
|
||||
Americas, Japan, Korea, and the Union of Myanmar
|
||||
[<A HREF="#Rec470">Rec470</A>].
|
||||
This color space may also be used for System M/PAL (Brazil), with an
|
||||
appropriate conversion supplied by the encoder to compensate for the
|
||||
different gamma value.
|
||||
See the Rec 470BG section for an appropriate gamma value to assume for M/PAL
|
||||
input.
|
||||
</P>
|
||||
<P>
|
||||
In the US, studio monitors are adjusted to a D65 white point
|
||||
(<EM>x<SUB>w</SUB></EM>,<EM>y<SUB>w</SUB></EM>=0.313,0.329).
|
||||
In Japan, studio monitors are adjusted to a D white of 9300K
|
||||
(<EM>x<SUB>w</SUB></EM>,<EM>y<SUB>w</SUB></EM>=0.285,0.293).
|
||||
</P>
|
||||
<P>
|
||||
Rec 470 does not specify a digital encoding of the color signals.
|
||||
For Ogg Theora, Rec. ITU-R BT.601-5 is used, starting from the R'G'B' signals
|
||||
specified by Rec 470 [<A HREF="#Rec601">Rec601</A>].
|
||||
</P>
|
||||
<P>
|
||||
<P>
|
||||
Rec 470 does not specify an input gamma function.
|
||||
For Ogg Theora, the Rec 709 input function is used.
|
||||
This is the same as that specified by SMPTE 170M, which claims to reflect
|
||||
modern practice in the creation of NTSC signals (c. 1994)
|
||||
[<A HREF="#SMPTE170M">SMPTE170M</A>].
|
||||
</P>
|
||||
<H4>parameters</H4>
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>Offset<SUB>Y,C<SUB>b</SUB>,C<SUB>r</SUB></SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">(16,128,128)</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">
|
||||
<EM>Excursion<SUB>Y,C<SUB>b</SUB>,C<SUB>r</SUB></SUB></EM>
|
||||
</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">(219,224,224)</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>K<SUB>b</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">0.114</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>K<SUB>r</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">0.299</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>γ</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">2.2</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>β</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">0.45</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>α</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">4.5</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>δ</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">0.018</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>ε</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">0.099</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>x<SUB>r</SUB></EM>,<EM>y<SUB>r</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.67,</TD>
|
||||
<TD>0.33</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>x<SUB>g</SUB></EM>,<EM>y<SUB>g</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.21,</TD>
|
||||
<TD>0.71</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>x<SUB>b</SUB></EM>,<EM>y<SUB>b</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.14,</TD>
|
||||
<TD>0.08</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">
|
||||
(Illuminant C) <EM>x<SUB>w</SUB></EM>,<EM>y<SUB>w</SUB></EM>
|
||||
</TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.310,</TD>
|
||||
<TD>0.316</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<H3>
|
||||
Rec 470BG (Rec. ITU-R BT.470-6 Systems B and G with Rec. ITU-R BT.601-5)
|
||||
</H3>
|
||||
<P>
|
||||
This color space is used by the PAL and SECAM systems in much of the rest of
|
||||
the world [<A HREF="#Rec470">Rec470</A>].
|
||||
This can be used directly by systems (B, B1, D, D1, G, H, I, K, N)/PAL and (B,
|
||||
D, G, H, K, K1, L)/SECAM.
|
||||
</P>
|
||||
<P>
|
||||
Note that the Rec 470BG chromaticity values are different from those specified
|
||||
in Rec 470M.
|
||||
When PAL and SECAM systems were first designed, they were based upon the same
|
||||
primaries as NTSC.
|
||||
However, as methods of making color picture tubes have changed, the primaries
|
||||
used have changed as well.
|
||||
The US recommends using correction circuitry to approximate the existing,
|
||||
standard NTSC primaries.
|
||||
Current PAL and SECAM systems have standardized on primaries in accord with
|
||||
more recent technology.
|
||||
</P>
|
||||
<P>
|
||||
Rec 470 provisionally permits the use of the NTSC chromaticity values (given
|
||||
above) with legacy PAL and SECAM equipment.
|
||||
In Ogg Theora, material must be decoded assuming the new PAL and SECAM
|
||||
primaries.
|
||||
Material intended for display on old legacy devices should be converted by the
|
||||
decoder.
|
||||
</P>
|
||||
<P>
|
||||
The official Rec 470BG specifies a gamma value of <EM>γ</EM>=2.8.
|
||||
However, in practice this value is unrealistically high
|
||||
[<A HREF="#RefPoy97">Poy97</A>].
|
||||
Rec 470BG states that the overall system gamma should be approximately
|
||||
<EM>γ</EM>/<EM>β</EM>=1.2.
|
||||
However, most cameras pre-correct with a gamma value of <EM>β</EM>=0.45,
|
||||
which suggests an output device gamma of approximately <EM>γ</EM>=2.67.
|
||||
This is the value recommended for use with PAL systems in Ogg Theora.
|
||||
</P>
|
||||
<P>
|
||||
Rec 470 does not specify a digital encoding of the color signals.
|
||||
For Ogg Theora, Rec. ITU-R BT.601-5 is used, starting from the R'G'B' signals
|
||||
specified by Rec 470 [<A HREF="#Rec601">Rec601</A>].
|
||||
</P>
|
||||
<P>
|
||||
Rec 470 does not specify an input gamma function.
|
||||
For Ogg Theora, the Rec 709 input function is used.
|
||||
</P>
|
||||
<H4>parameters</H4>
|
||||
<TABLE>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>Offset<SUB>Y,C<SUB>b</SUB>,C<SUB>r</SUB></SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">(16,128,128)</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">
|
||||
<EM>Excursion<SUB>Y,C<SUB>b</SUB>,C<SUB>r</SUB></SUB></EM>
|
||||
</TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">(219,224,224)</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>K<SUB>b</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">0.114</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>K<SUB>r</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT" COLSPAN="2">0.299</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>γ</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">2.67</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>β</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">0.45</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>α</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">4.5</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>δ</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">0.018</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>ε</EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD ALIGN="LEFT">0.099</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>x<SUB>r</SUB></EM>,<EM>y<SUB>r</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.64,</TD>
|
||||
<TD>0.33</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>x<SUB>g</SUB></EM>,<EM>y<SUB>g</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.29,</TD>
|
||||
<TD>0.60</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT"><EM>x<SUB>b</SUB></EM>,<EM>y<SUB>b</SUB></EM></TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.15,</TD>
|
||||
<TD>0.06</TD>
|
||||
</TR>
|
||||
<TR VALIGN="BOTTOM">
|
||||
<TD ALIGN="RIGHT">
|
||||
(D65) <EM>x<SUB>w</SUB></EM>,<EM>y<SUB>w</SUB></EM>
|
||||
</TD>
|
||||
<TD>=</TD>
|
||||
<TD>0.313,</TD>
|
||||
<TD>0.329</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<H2>references</H2>
|
||||
<DL>
|
||||
<DT>[<A NAME="Poy97">Poy97</A>]</DT>
|
||||
<DD>
|
||||
Poynton, Charles, <I>Frequently-Asked Questions about Gamma</I>.
|
||||
<A HREF="http://www.poynton.com/GammaFAQ.html">http://www.poynton.com/GammaFAQ/html</A>,
|
||||
Feb. 1997.
|
||||
</DD>
|
||||
<DT>[<A NAME="Rec470">Rec470</A>]</DT>
|
||||
<DD>
|
||||
Recommendation ITU-R BT.470-6, <I>Conventional Television Systems</I>
|
||||
(1970, revised 1998). International Telecommunications Union, 1211 Geneva 20,
|
||||
Switzerland.
|
||||
</DD>
|
||||
<DT>[<A NAME="Rec601">Rec601</A>]</DT>
|
||||
<DD>
|
||||
Recommendation ITU-R BT.601-5, <I>Studio Encoding Parameters of
|
||||
Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect Ratios</I>
|
||||
(1982, revised 1995). International Telecommunications Union, 1211 Geneva 20,
|
||||
Switzerland.
|
||||
</DD>
|
||||
<DT>[<A NAME="Rec709">Rec709</A>]</DT>
|
||||
<DD>
|
||||
Recommendation ITU-R BT.709-5, <I>Parameter values for the
|
||||
HDTV standards for production and international programme exchange</I>
|
||||
(1990, revised 2002). International Telecommunications Union, 1211 Geneva 20,
|
||||
Switzerland.
|
||||
</DD>
|
||||
<DT>[<A NAME="SMPTE170M">SMPTE170M</A>]</DT>
|
||||
<DD>
|
||||
Society of Motion Picture and Television Engineers, <I>Television —
|
||||
Composite Analog Video Signal — NTSC for Studio Applications</I>.
|
||||
SMPTE-170M, 1994
|
||||
</DD>
|
||||
<DT>[<A NAME="SMPTE240M">SMPTE240M</A>]</DT>
|
||||
<DD>
|
||||
Society of Motion Picture and Television Engineers, <I>Television —
|
||||
Signal Parameters — 1125-Line High-Definition Production</I>.
|
||||
SMPTE-240M, 1999.
|
||||
</DD>
|
||||
</DL>
|
||||
</BODY>
|
||||
</HTML>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# makefile to generate the spec document from sources
|
||||
# requires transfig and pdflatex
|
||||
|
||||
built_docs = Theora.pdf
|
||||
|
||||
if BUILD_SPEC
|
||||
doc_DATA = $(built_docs)
|
||||
endif
|
||||
|
||||
SPEC_SRCS = spec.tex spec.bib
|
||||
|
||||
FIG_SRCS = pic-frame.fig hilbert-mb.fig hilbert-block.fig xifish.fig \
|
||||
superblock.fig macroblock.fig raster-block.fig reference-frames.fig \
|
||||
pixel444.fig pixel422.fig pixel420.fig idct.fig fdct.fig \
|
||||
pic_even.fig pic_even_odd.fig pic_odd.fig pic_odd_even.fig \
|
||||
lflim.fig
|
||||
|
||||
FIG_TEXS = $(FIG_SRCS:.fig=.tex)
|
||||
FIG_AUXS = $(FIG_SRCS:.fig=.aux)
|
||||
FIG_PDFS = $(FIG_SRCS:.fig=.pdf)
|
||||
|
||||
# add any native-pdf figures here
|
||||
FIG_OBJS = $(FIG_PDFS)
|
||||
|
||||
EXTRA_DIST = $(built_docs) $(SPEC_SRCS) $(FIG_SRCS) ltablex.sty
|
||||
|
||||
if BUILD_SPEC
|
||||
# latex three times is the charm with references
|
||||
# long tables require the .aux file to start from scratch
|
||||
Theora.pdf : $(SPEC_SRCS) $(FIG_OBJS) vp3huff.tex
|
||||
-$(RM) spec.aux
|
||||
pdflatex -interaction nonstopmode spec.tex
|
||||
bibtex spec.aux
|
||||
pdflatex -interaction nonstopmode spec.tex
|
||||
pdflatex -interaction nonstopmode spec.tex
|
||||
mv spec.pdf $@
|
||||
else
|
||||
Theora.pdf :
|
||||
echo "*** Warning: Missing tools; $@ will not be built."
|
||||
endif
|
||||
|
||||
vp3huff.tex : vp3huff
|
||||
./vp3huff > $@
|
||||
|
||||
noinst_PROGRAMS = vp3huff
|
||||
vp3huff_SOURCES = vp3huff.c
|
||||
|
||||
figures : $(FIG_OBJS)
|
||||
|
||||
# rules to generate latex and pdf versions of the xfig figures
|
||||
.fig.tex:
|
||||
fig2dev -L latex $< $@
|
||||
|
||||
.fig.pdf:
|
||||
fig2dev -L pdf -p 0 $< $@
|
||||
|
||||
SUFFIXES = .fig .tex .pdf
|
||||
|
||||
# clean targets
|
||||
clean-local:
|
||||
-$(RM) $(FIG_TEXS)
|
||||
-$(RM) $(FIG_AUXS)
|
||||
-$(RM) $(FIG_PDFS)
|
||||
-$(RM) vp3huff
|
||||
-$(RM) vp3huff.tex
|
||||
-$(RM) vp3huff.aux
|
||||
-$(RM) spec.aux
|
||||
-$(RM) spec.log
|
||||
-$(RM) spec.lof
|
||||
-$(RM) spec.lot
|
||||
-$(RM) spec.out
|
||||
-$(RM) spec.bbl
|
||||
-$(RM) spec.blg
|
||||
-$(RM) spec.toc
|
||||
|
||||
maintainer-clean-local:
|
||||
-$(RM) $(built_docs)
|
||||
|
||||
maintainerclean: maintainer-clean
|
||||
@@ -0,0 +1,371 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 1350 4650 1650 4950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1500 4800 75 75 1500 4800 1500 4725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1450 4800 1550 4800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1500 4850 1500 4750
|
||||
-6
|
||||
6 1350 450 1650 750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1500 600 75 75 1500 600 1500 525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1450 600 1550 600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1500 650 1500 550
|
||||
-6
|
||||
6 1950 1050 2250 1350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 1200 75 75 2100 1200 2100 1125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 1200 2150 1200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 1250 2100 1150
|
||||
-6
|
||||
6 3150 2850 3450 3150
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3300 3000 75 75 3300 3000 3300 2925
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3250 3000 3350 3000
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3300 3050 3300 2950
|
||||
-6
|
||||
6 3150 2250 3450 2550
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3300 2400 75 75 3300 2400 3300 2325
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3250 2400 3350 2400
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3300 2450 3300 2350
|
||||
-6
|
||||
6 2550 3450 2850 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2700 3600 75 75 2700 3600 2700 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2650 3600 2750 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2700 3650 2700 3550
|
||||
-6
|
||||
6 2550 1650 2850 1950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2700 1800 75 75 2700 1800 2700 1725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2650 1800 2750 1800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2700 1850 2700 1750
|
||||
-6
|
||||
6 1950 4050 2250 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 4200 75 75 2100 4200 2100 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 4200 2150 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 4250 2100 4150
|
||||
-6
|
||||
6 2250 3600 2550 3900
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2400 3750 75 75 2400 3750 2400 3675
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 2400 3800 -\001
|
||||
-6
|
||||
6 1650 4200 1950 4500
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1800 4350 75 75 1800 4350 1800 4275
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 1800 4400 -\001
|
||||
-6
|
||||
6 1050 4800 1350 5100
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1200 4950 75 75 1200 4950 1200 4875
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 1200 5000 -\001
|
||||
-6
|
||||
6 2850 3000 3150 3300
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3000 3150 75 75 3000 3150 3000 3075
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 3000 3200 -\001
|
||||
-6
|
||||
6 4350 4050 4650 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4500 4200 75 75 4500 4200 4500 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4450 4200 4550 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4500 4250 4500 4150
|
||||
-6
|
||||
6 4350 3450 4650 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4500 3600 75 75 4500 3600 4500 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4450 3600 4550 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4500 3650 4500 3550
|
||||
-6
|
||||
6 4050 3300 4350 3600
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4200 3450 75 75 4200 3450 4200 3375
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 4200 3500 -\001
|
||||
-6
|
||||
6 4350 2250 4650 2550
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4500 2400 75 75 4500 2400 4500 2325
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4450 2400 4550 2400
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4500 2450 4500 2350
|
||||
-6
|
||||
6 4350 450 4650 750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4500 600 75 75 4500 600 4500 525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4450 600 4550 600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4500 650 4500 550
|
||||
-6
|
||||
6 4050 2400 4350 2700
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4200 2550 75 75 4200 2550 4200 2475
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 4200 2600 -\001
|
||||
-6
|
||||
6 4950 1050 5250 1350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 5100 1200 75 75 5100 1200 5100 1125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5050 1200 5150 1200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5100 1250 5100 1150
|
||||
-6
|
||||
6 4950 1650 5250 1950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 5100 1800 75 75 5100 1800 5100 1725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5050 1800 5150 1800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5100 1850 5100 1750
|
||||
-6
|
||||
6 4650 1800 4950 2100
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4800 1950 75 75 4800 1950 4800 1875
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 4800 2000 -\001
|
||||
-6
|
||||
6 4725 3525 4875 4275
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4800 4200 25 25 4800 4200 4800 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4800 3600 25 25 4800 3600 4800 3575
|
||||
-6
|
||||
6 6150 4650 6450 4950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 4800 75 75 6300 4800 6300 4725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 4800 6350 4800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 4850 6300 4750
|
||||
-6
|
||||
6 6150 4050 6450 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 4200 75 75 6300 4200 6300 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 4200 6350 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 4250 6300 4150
|
||||
-6
|
||||
6 5850 3900 6150 4200
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6000 4050 75 75 6000 4050 6000 3975
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 6000 4100 -\001
|
||||
-6
|
||||
6 6150 2850 6450 3150
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 3000 75 75 6300 3000 6300 2925
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 3000 6350 3000
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 3050 6300 2950
|
||||
-6
|
||||
6 6150 3450 6450 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 3600 75 75 6300 3600 6300 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 3600 6350 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 3650 6300 3550
|
||||
-6
|
||||
6 5850 3600 6150 3900
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6000 3750 75 75 6000 3750 6000 3675
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 6000 3800 -\001
|
||||
-6
|
||||
6 6150 1050 6450 1350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 1200 75 75 6300 1200 6300 1125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 1200 6350 1200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 1250 6300 1150
|
||||
-6
|
||||
6 6150 450 6450 750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 600 75 75 6300 600 6300 525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 600 6350 600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 650 6300 550
|
||||
-6
|
||||
6 6150 2250 6450 2550
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 2400 75 75 6300 2400 6300 2325
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 2400 6350 2400
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 2450 6300 2350
|
||||
-6
|
||||
6 6150 1650 6450 1950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 1800 75 75 6300 1800 6300 1725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 1800 6350 1800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 1850 6300 1750
|
||||
-6
|
||||
6 5850 1200 6150 1500
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6000 1350 75 75 6000 1350 6000 1275
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 6000 1400 -\001
|
||||
-6
|
||||
6 7350 4650 7650 4950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 7500 4800 75 75 7500 4800 7500 4725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7450 4800 7550 4800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7500 4850 7500 4750
|
||||
-6
|
||||
6 7350 2850 7650 3150
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 7500 3000 75 75 7500 3000 7500 2925
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7450 3000 7550 3000
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7500 3050 7500 2950
|
||||
-6
|
||||
6 7950 4050 8250 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 8100 4200 75 75 8100 4200 8100 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8050 4200 8150 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8100 4250 8100 4150
|
||||
-6
|
||||
6 7950 3450 8250 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 8100 3600 75 75 8100 3600 8100 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8050 3600 8150 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8100 3650 8100 3550
|
||||
-6
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 900 4800 25 25 900 4800 900 4775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 900 600 25 25 900 600 900 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 1200 25 25 1500 1200 1500 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2700 3000 25 25 2700 3000 2700 2975
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2700 2400 25 25 2700 2400 2700 2375
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2100 3600 25 25 2100 3600 2100 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 4200 25 25 1500 4200 1500 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3900 4200 25 25 3900 4200 3900 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3900 3600 25 25 3900 3600 3900 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3900 2400 25 25 3900 2400 3900 2375
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3900 600 25 25 3900 600 3900 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4500 1200 25 25 4500 1200 4500 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4500 1800 25 25 4500 1800 4500 1775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 4800 25 25 5700 4800 5700 4775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 4200 25 25 5700 4200 5700 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 3600 25 25 5700 3600 5700 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 3000 25 25 5700 3000 5700 2975
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 1200 25 25 5700 1200 5700 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 600 25 25 5700 600 5700 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 2400 25 25 5700 2400 5700 2375
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5725 1800 25 25 5725 1800 5725 1775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 6900 4800 25 25 6900 4800 6900 4775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 6900 3000 25 25 6900 3000 6900 2975
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 7500 4200 25 25 7500 4200 7500 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 7500 3600 25 25 7500 3600 7500 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 7500 1200 25 25 7500 1200 7500 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 7500 600 25 25 7500 600 7500 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2100 1800 25 25 2100 1800 2100 1775
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 600 8400 600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 2400 8400 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 3000 8400 3000
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 4800 8400 4800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 1200 8400 1200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 3600 8400 3600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 1800 8400 1800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 4200 8400 4200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
900 4800 1500 600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
900 600 1500 4800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
1500 1200 2100 4275
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
1500 4200 2100 1200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2100 3600 2700 1800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2700 2400 3300 3000
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2100 1800 2700 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2700 3000 3300 2400
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
3900 3600 4500 4200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
3900 4200 4500 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
3900 600 4500 2400
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
3900 2400 4500 600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 1800 5100 1200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 1200 5100 1800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
5700 4200 6300 4800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
5700 3600 6300 3000
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
5700 3000 6300 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
5700 4800 6300 4200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5700 1200 6300 600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5700 600 6300 1200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5700 1800 6300 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5700 2400 6300 1800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
6900 3000 7500 4800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
6900 4800 7500 3000
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7500 4200 8100 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7500 3600 8100 4200
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 4800 4125 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 4800 3525 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 6000 2350 C6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 255 6300 2275 -S6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 6000 1750 C6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 195 6300 2050 S6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 7200 2950 C7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 195 7500 3375 S7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 7200 4750 C7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 255 7500 4575 -S7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 7800 4150 C3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 255 8100 4075 -S3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 7800 3550 C3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 195 8100 3850 S3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 7500 1125 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 7500 525 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 675 0\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 1275 4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 1875 2\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 2475 6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 3675 5\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 4275 3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 4875 7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 3075 1\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 675 0\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 1275 1\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 1875 2\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 2475 3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 3075 4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 3675 5\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 4275 6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 4875 7\001
|
||||
@@ -0,0 +1,104 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5-alpha4
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 675 645 3825 3795
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 3660 0\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 3660 1\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 2760 2\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 2760 3\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 1860 4\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 960 5\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 960 6\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 1860 7\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 2700 1860 8\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 2700 960 9\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 210 3600 960 10\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 210 3600 1860 11\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 210 3600 2760 12\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 210 2700 2760 13\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 210 2700 3660 14\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 210 3600 3660 15\001
|
||||
-6
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1125 3600 1575 3600
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 3375 1800 2925
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1575 2700 1125 2700
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
900 2475 900 2025
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
900 1575 900 1125
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1125 900 1575 900
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 1125 1800 1575
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2025 1800 2475 1800
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2700 1575 2700 1125
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2925 900 3375 900
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3600 1125 3600 1575
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3600 2025 3600 2475
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3375 2700 2925 2700
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2700 2925 2700 3375
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2925 3600 3375 3600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 450 1350 450 1350 1350 450 1350 450 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 450 2250 450 2250 1350 1350 1350 1350 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 450 3150 450 3150 1350 2250 1350 2250 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 450 4050 450 4050 1350 3150 1350 3150 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 1350 1350 1350 1350 2250 450 2250 450 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2250 1350 2250 2250 1350 2250 1350 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 1350 3150 1350 3150 2250 2250 2250 2250 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 1350 4050 1350 4050 2250 3150 2250 3150 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 2250 1350 2250 1350 3150 450 3150 450 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 2250 2250 2250 2250 3150 1350 3150 1350 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 2250 3150 2250 3150 3150 2250 3150 2250 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 2250 4050 2250 4050 3150 3150 3150 3150 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 3150 1350 3150 1350 4050 450 4050 450 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 3150 2250 3150 2250 4050 1350 4050 1350 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 3150 3150 3150 3150 4050 2250 4050 2250 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 3150 4050 3150 4050 4050 3150 4050 3150 3150
|
||||
@@ -0,0 +1,32 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5-alpha4
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 810 810 1890 1890
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 1860 0\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 960 1\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 960 2\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 1860 3\001
|
||||
-6
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
900 1575 900 1125
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1125 900 1575 900
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1800 1125 1800 1575
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 450 1350 450 1350 1350 450 1350 450 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 450 2250 450 2250 1350 1350 1350 1350 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 1350 1350 1350 1350 2250 450 2250 450 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2250 1350 2250 2250 1350 2250 1350 1350
|
||||
@@ -0,0 +1,369 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 3150 4650 3450 4950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3300 4800 75 75 3300 4800 3300 4725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3250 4800 3350 4800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3300 4850 3300 4750
|
||||
-6
|
||||
6 3150 4050 3450 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3300 4200 75 75 3300 4200 3300 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3250 4200 3350 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3300 4250 3300 4150
|
||||
-6
|
||||
6 2850 3900 3150 4200
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3000 4050 75 75 3000 4050 3000 3975
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 3000 4100 -\001
|
||||
-6
|
||||
6 3150 2850 3450 3150
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3300 3000 75 75 3300 3000 3300 2925
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3250 3000 3350 3000
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3300 3050 3300 2950
|
||||
-6
|
||||
6 3150 3450 3450 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3300 3600 75 75 3300 3600 3300 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3250 3600 3350 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
3300 3650 3300 3550
|
||||
-6
|
||||
6 2850 3600 3150 3900
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 3000 3750 75 75 3000 3750 3000 3675
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 3000 3800 -\001
|
||||
-6
|
||||
6 1950 1050 2250 1350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 1200 75 75 2100 1200 2100 1125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 1200 2150 1200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 1250 2100 1150
|
||||
-6
|
||||
6 1950 450 2250 750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 600 75 75 2100 600 2100 525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 600 2150 600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 650 2100 550
|
||||
-6
|
||||
6 1950 2250 2250 2550
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 2400 75 75 2100 2400 2100 2325
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 2400 2150 2400
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 2450 2100 2350
|
||||
-6
|
||||
6 1950 1650 2250 1950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 1800 75 75 2100 1800 2100 1725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 1800 2150 1800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 1850 2100 1750
|
||||
-6
|
||||
6 1650 1200 1950 1500
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1800 1350 75 75 1800 1350 1800 1275
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 1800 1400 -\001
|
||||
-6
|
||||
6 6150 4650 6450 4950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 4800 75 75 6300 4800 6300 4725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 4800 6350 4800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 4850 6300 4750
|
||||
-6
|
||||
6 6150 450 6450 750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6300 600 75 75 6300 600 6300 525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6250 600 6350 600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6300 650 6300 550
|
||||
-6
|
||||
6 6750 1050 7050 1350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6900 1200 75 75 6900 1200 6900 1125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6850 1200 6950 1200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6900 1250 6900 1150
|
||||
-6
|
||||
6 7950 2850 8250 3150
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 8100 3000 75 75 8100 3000 8100 2925
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8050 3000 8150 3000
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8100 3050 8100 2950
|
||||
-6
|
||||
6 7950 2250 8250 2550
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 8100 2400 75 75 8100 2400 8100 2325
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8050 2400 8150 2400
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
8100 2450 8100 2350
|
||||
-6
|
||||
6 7350 3450 7650 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 7500 3600 75 75 7500 3600 7500 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7450 3600 7550 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7500 3650 7500 3550
|
||||
-6
|
||||
6 7350 1650 7650 1950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 7500 1800 75 75 7500 1800 7500 1725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7450 1800 7550 1800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
7500 1850 7500 1750
|
||||
-6
|
||||
6 6750 4050 7050 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6900 4200 75 75 6900 4200 6900 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6850 4200 6950 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
6900 4250 6900 4150
|
||||
-6
|
||||
6 7050 3600 7350 3900
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 7200 3750 75 75 7200 3750 7200 3675
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 7200 3800 -\001
|
||||
-6
|
||||
6 6450 4200 6750 4500
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6600 4350 75 75 6600 4350 6600 4275
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 6600 4400 -\001
|
||||
-6
|
||||
6 5850 4800 6150 5100
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 6000 4950 75 75 6000 4950 6000 4875
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 6000 5000 -\001
|
||||
-6
|
||||
6 7650 3000 7950 3300
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 7800 3150 75 75 7800 3150 7800 3075
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 7800 3200 -\001
|
||||
-6
|
||||
6 4950 4050 5250 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 5100 4200 75 75 5100 4200 5100 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5050 4200 5150 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5100 4250 5100 4150
|
||||
-6
|
||||
6 4950 3450 5250 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 5100 3600 75 75 5100 3600 5100 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5050 3600 5150 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5100 3650 5100 3550
|
||||
-6
|
||||
6 4650 3300 4950 3600
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4800 3450 75 75 4800 3450 4800 3375
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 4800 3500 -\001
|
||||
-6
|
||||
6 4350 2250 4650 2550
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4500 2400 75 75 4500 2400 4500 2325
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4450 2400 4550 2400
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4500 2450 4500 2350
|
||||
-6
|
||||
6 4350 450 4650 750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4500 600 75 75 4500 600 4500 525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4450 600 4550 600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
4500 650 4500 550
|
||||
-6
|
||||
6 4050 2400 4350 2700
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4200 2550 75 75 4200 2550 4200 2475
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 4200 2600 -\001
|
||||
-6
|
||||
6 4950 1050 5250 1350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 5100 1200 75 75 5100 1200 5100 1125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5050 1200 5150 1200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5100 1250 5100 1150
|
||||
-6
|
||||
6 4950 1650 5250 1950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 5100 1800 75 75 5100 1800 5100 1725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5050 1800 5150 1800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
5100 1850 5100 1750
|
||||
-6
|
||||
6 1950 4050 2250 4350
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 4200 75 75 2100 4200 2100 4125
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 4200 2150 4200
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 4250 2100 4150
|
||||
-6
|
||||
6 1950 3450 2250 3750
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 2100 3600 75 75 2100 3600 2100 3525
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2050 3600 2150 3600
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
2100 3650 2100 3550
|
||||
-6
|
||||
6 1350 4650 1650 4950
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1500 4800 75 75 1500 4800 1500 4725
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1450 4800 1550 4800
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1500 4850 1500 4750
|
||||
-6
|
||||
6 1350 2850 1650 3150
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 1500 3000 75 75 1500 3000 1500 2925
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1450 3000 1550 3000
|
||||
2 1 0 1 0 7 40 -1 20 4.000 0 0 7 0 0 2
|
||||
1500 3050 1500 2950
|
||||
-6
|
||||
6 4650 1800 4950 2100
|
||||
1 3 0 1 0 7 40 -1 20 4.000 1 0.0000 4800 1950 75 75 4800 1950 4800 1875
|
||||
4 1 0 40 -1 0 12 0.0000 4 15 60 4800 2000 -\001
|
||||
-6
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2700 4800 25 25 2700 4800 2700 4775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2700 4200 25 25 2700 4200 2700 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2700 3600 25 25 2700 3600 2700 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 2700 3000 25 25 2700 3000 2700 2975
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 1200 25 25 1500 1200 1500 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 600 25 25 1500 600 1500 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 2400 25 25 1500 2400 1500 2375
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1525 1800 25 25 1525 1800 1525 1775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3000 1200 25 25 3000 1200 3000 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3000 600 25 25 3000 600 3000 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 4800 25 25 5700 4800 5700 4775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 5700 600 25 25 5700 600 5700 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 6300 1200 25 25 6300 1200 6300 1175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 7500 3000 25 25 7500 3000 7500 2975
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 7500 2400 25 25 7500 2400 7500 2375
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 6900 3600 25 25 6900 3600 6900 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 6300 4200 25 25 6300 4200 6300 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4500 4200 25 25 4500 4200 4500 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4500 3600 25 25 4500 3600 4500 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4200 4200 25 25 4200 4200 4200 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4200 3600 25 25 4200 3600 4200 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 6900 1800 25 25 6900 1800 6900 1775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3900 2400 25 25 3900 2400 3900 2375
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 3900 600 25 25 3900 600 3900 575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 4200 25 25 1500 4200 1500 4175
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 1500 3600 25 25 1500 3600 1500 3575
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 900 4800 25 25 900 4800 900 4775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 900 3000 25 25 900 3000 900 2975
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4500 1800 25 25 4500 1800 4500 1775
|
||||
1 3 0 1 0 0 40 -1 20 4.000 1 0.0000 4500 1200 25 25 4500 1200 4500 1175
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 600 8400 600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 2400 8400 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 3000 8400 3000
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 4800 8400 4800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 1200 8400 1200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2700 4200 3300 4800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2700 3600 3300 3000
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2700 3000 3300 3600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 3600 8400 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
2700 4800 3300 4200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 1800 8400 1800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 4200 8400 4200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1500 1200 2100 600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1500 600 2100 1200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1500 1800 2100 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1500 2400 2100 1800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
5700 4800 6300 600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
5700 600 6300 4800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
6300 1200 6900 4275
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
6300 4200 6900 1200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
6900 3600 7500 1800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7500 2400 8100 3000
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
6900 1800 7500 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7500 3000 8100 2400
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 3600 5100 4200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 4200 5100 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
3900 2400 4500 600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
3900 600 4500 2400
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 1800 5100 1200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
4500 1200 5100 1800
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
1500 4200 2100 3600
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
1500 3600 2100 4200
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
900 4800 1500 3000
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2
|
||||
900 3000 1500 4800
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 675 0\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 1275 4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 1875 2\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 2475 6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 3675 5\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 4275 3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 4875 7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 300 3075 1\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 1800 2350 C6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 195 2100 2275 S6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 1800 1750 C6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 255 2100 2050 -S6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 3000 1125 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 3000 525 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 675 0\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 1275 1\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 1875 2\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 2475 3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 3075 4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 3675 5\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 4275 6\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 90 8700 4875 7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 4200 4125 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 4200 3525 C4\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 1800 4150 C3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 195 2100 4075 S3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 1800 3550 C3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 255 2100 3850 -S3\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 1200 2950 C7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 255 1500 3375 -S7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 210 1200 4750 C7\001
|
||||
4 1 0 40 -1 0 12 0.0000 4 135 195 1500 4575 S7\001
|
||||
@@ -0,0 +1,23 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
600 2400 5400 2400
|
||||
2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
3000 4200 3000 600
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 6
|
||||
600 2400 1200 2400 2100 3300 3900 1500 4800 2400 5400 2400
|
||||
4 1 0 50 -1 1 12 0.0000 0 195 615 1200 2325 (-2L,0)\001
|
||||
4 1 0 50 -1 1 12 0.0000 0 195 600 2100 3525 (-L,-L)\001
|
||||
4 0 0 50 -1 1 12 0.0000 0 150 360 3075 825 lflim\001
|
||||
4 1 0 50 -1 1 12 0.0000 0 195 480 3900 1425 (L,L)\001
|
||||
4 1 0 50 -1 1 12 0.0000 0 195 555 4800 2625 (2L,0)\001
|
||||
4 0 0 50 -1 1 12 0.0000 0 150 135 5250 2625 R\001
|
||||
@@ -0,0 +1,237 @@
|
||||
%%
|
||||
%% This is file ltablex.sty (v1.0, November 1995)
|
||||
%%
|
||||
%%
|
||||
%% Author: Anil K. Goel (akgoel@uwaterloo.ca)
|
||||
%%
|
||||
%%
|
||||
%% Copyright (C) QNX Software Systems Ltd. 1995
|
||||
%% All rights reserved.
|
||||
%% Please send any comments/suggetions to: latex@qnx.com
|
||||
%%
|
||||
%% This system is distributed in the hope that it will be useful
|
||||
%% to others, but WITHOUT ANY WARRANTY; without even the implied
|
||||
%% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
%%
|
||||
%%
|
||||
%% The file modifies the tabularx environment to
|
||||
%% combine the features of the tabularx package
|
||||
%% (auto-sized columns in a fixed width table)
|
||||
%% with those of the longtable package
|
||||
%% (multi-page tables).
|
||||
%%
|
||||
%% The tables are typeset using the tabularx environment
|
||||
%% and the longtable environment is used internally to
|
||||
%% handle multi-page tables. The \setlongtables feature
|
||||
%% is used, and, therefore, the document should be
|
||||
%% run through latex twice.
|
||||
%%
|
||||
%% Another feature that has been added is to treat the X
|
||||
%% columns like 'l' columns if the table contents would allow
|
||||
%% that to happen without exceeding the specified width of
|
||||
%% the table. In other words, the specified width is
|
||||
%% treated as the maximum allowed and not the exact width
|
||||
%% of the table. This feature is the default but can be
|
||||
%% disabled (or enabled) with \keepXColumns (or \convertXColumns).
|
||||
%%
|
||||
%% Caveats:
|
||||
%% . The document needs to be latexed a couple times in general.
|
||||
%% . In general, it is necessary to remove the .aux file before
|
||||
%% the first latex run on the document.
|
||||
%% . The table should not be larger than TeX's memory capacity
|
||||
%%
|
||||
%%
|
||||
%% Here is a a simple usage example:
|
||||
%%
|
||||
%%
|
||||
%% \documentclass{article}
|
||||
%%
|
||||
%% \usepackage{ltablex}
|
||||
%%
|
||||
%% \textheight=4in
|
||||
%%
|
||||
%% \begin{document}
|
||||
%%
|
||||
%% % we want a table that is \textwidth long, has 4 columns, columns 1
|
||||
%% % and 3 are auto sized with the 3rd columns being 3 times wider than
|
||||
%% % the first column.
|
||||
%% %
|
||||
%%
|
||||
%%
|
||||
%% \begin{tabularx}{\linewidth}%
|
||||
%% {|>{\setlength{\hsize}{.5\hsize}\raggedright\arraybackslash}X| % col 1; auto-sized ragged right
|
||||
%% c| % col 2; default centered
|
||||
%% >{\setlength{\hsize}{1.5\hsize}\raggedleft\arraybackslash}X|% col 3; auto-sized ragged left
|
||||
%% l|} % col 4; default left-justified
|
||||
%%
|
||||
%% \caption*{The Table Caption}\\
|
||||
%% \hline
|
||||
%% F-Head1 & F-Head2 & F-Head3 & F-Head4\\
|
||||
%% \hline
|
||||
%% \hline
|
||||
%% \endfirsthead
|
||||
%% \hline
|
||||
%% Head1 & Head2 & Head3 & Head4\\
|
||||
%% \hline
|
||||
%% \hline
|
||||
%% \endhead
|
||||
%%
|
||||
%% \hline
|
||||
%% \hline
|
||||
%% Foot1 & Foot2 & Foot3 & Foot4\\
|
||||
%% \hline
|
||||
%% \endfoot
|
||||
%%
|
||||
%%
|
||||
%% \hline
|
||||
%% \hline
|
||||
%% L-Foot1 & L-Foot2 & L-Foot3 & L-Foot4\\
|
||||
%% \hline
|
||||
%% \endlastfoot
|
||||
%%
|
||||
%% This is a very long sentence not likely to fit&
|
||||
%% not too long&
|
||||
%% This is another very long sentence not likely to fit&
|
||||
%% not long\\
|
||||
%%
|
||||
%% \hline
|
||||
%% filler & filler & filler & filler\\
|
||||
%%
|
||||
%% \hline
|
||||
%% This is a very long sentence not likely to fit&
|
||||
%% not too long&
|
||||
%% This is another very long sentence not likely to fit&
|
||||
%% not long\\
|
||||
%%
|
||||
%% \hline
|
||||
%% This is a very long sentence not likely to fit&
|
||||
%% not too long&
|
||||
%% This is another very long sentence not likely to fit&
|
||||
%% not long\\
|
||||
%%
|
||||
%% \hline
|
||||
%% This is a very long sentence not likely to fit&
|
||||
%% not too long&
|
||||
%% This is another very long sentence not likely to fit&
|
||||
%% not long\\
|
||||
%%
|
||||
%% \end{tabularx}
|
||||
%%
|
||||
%% \begin{tabularx}{\linewidth}{|c|X|c|}
|
||||
%% \hline
|
||||
%% a &convert X to l & b\\
|
||||
%% \hline
|
||||
%% \end{tabularx}
|
||||
%%
|
||||
%% \keepXColumns
|
||||
%% \begin{tabularx}{\linewidth}{|c|X|c|}
|
||||
%% \hline
|
||||
%% a &retain X & b\\
|
||||
%% \hline
|
||||
%% \end{tabularx}
|
||||
%%
|
||||
%% \convertXColumns
|
||||
%% \begin{tabularx}{\linewidth}{|c|X|c|}
|
||||
%% \hline
|
||||
%% a &convert X to l & b\\
|
||||
%% \hline
|
||||
%% \end{tabularx}
|
||||
%%
|
||||
%%
|
||||
%% \end{document}
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{ltablex}[1995/11/06 v1.0 Modified tabularx]
|
||||
|
||||
\RequirePackage{longtable}[1994/12/08]
|
||||
\RequirePackage{tabularx}[1994/02/03]
|
||||
|
||||
\newif\ifTX@convertX@
|
||||
\TX@convertX@true
|
||||
|
||||
\newcommand\keepXColumns{
|
||||
\TX@convertX@false
|
||||
}
|
||||
|
||||
\newcommand\convertXColumns{
|
||||
\TX@convertX@true
|
||||
}
|
||||
|
||||
\renewcommand\TX@endtabularx{%
|
||||
\expandafter\TX@newcol\expandafter{\tabularxcolumn{\TX@col@width}}%
|
||||
\let\verb\TX@verb
|
||||
\def\@elt##1{\global\value{##1}\the\value{##1}\relax}%
|
||||
\edef\TX@ckpt{\cl@@ckpt}%
|
||||
\let\@elt\relax
|
||||
\TX@old@table=\maxdimen
|
||||
\TX@col@width=\TX@target
|
||||
\global\TX@cols=\@ne
|
||||
\TX@typeout@
|
||||
{\@spaces Table Width\@spaces Column Width\@spaces X Columns}%
|
||||
|
||||
%
|
||||
% define \endhead, etc. to be \\ so that in this part
|
||||
% of the process they are just rows
|
||||
%
|
||||
\let\savecaption\caption
|
||||
\def\caption{\\}
|
||||
\let\saveendhead\endhead
|
||||
\def\endhead{\\}
|
||||
\let\saveendfirsthead\endfirsthead
|
||||
\def\endfirsthead{\\}
|
||||
\let\saveendfoot\endfoot
|
||||
\def\endfoot{\\}
|
||||
\let\saveendlastfoot\endlastfoot
|
||||
\def\endlastfoot{\\}
|
||||
%
|
||||
%
|
||||
\ifTX@convertX@
|
||||
\TX@trial{\def\NC@rewrite@X{\NC@find l}}
|
||||
\ifdim\wd\@tempboxa<\TX@target
|
||||
\TX@newcol{l}
|
||||
\else
|
||||
\TX@convertX@false
|
||||
\fi
|
||||
\fi
|
||||
|
||||
\ifTX@convertX@
|
||||
\relax
|
||||
\else
|
||||
\TX@trial{\def\NC@rewrite@X{%
|
||||
\global\advance\TX@cols\@ne\NC@find p{\TX@col@width}}}%
|
||||
\loop
|
||||
\TX@arith
|
||||
\ifTX@
|
||||
\TX@trial{}%
|
||||
\repeat
|
||||
\fi
|
||||
{\let\@footnotetext\TX@ftntext\let\@xfootnotenext\TX@xftntext
|
||||
% we may as well set \LTchunksize to be \maxdimen as the whole
|
||||
% thing is already in memory anyway so we may as well do it in one
|
||||
% chunk. if it is too big for one chunk we are already dead..
|
||||
\LTchunksize\maxdimen
|
||||
%
|
||||
% restore \endhead, etc.
|
||||
%
|
||||
\let\caption\savecaption
|
||||
\let\endhead\saveendhead
|
||||
\let\endfirsthead\saveendfirsthead
|
||||
\let\endfoot\saveendfoot
|
||||
\let\endlastfoot\saveendlastfoot
|
||||
%
|
||||
\expandafter\longtable
|
||||
\the\toks@
|
||||
\endlongtable
|
||||
}%
|
||||
\global\TX@ftn\expandafter{\expandafter}\the\TX@ftn
|
||||
\ifnum0=`{\fi}%
|
||||
\end{tabularx}
|
||||
}
|
||||
|
||||
|
||||
%
|
||||
% activate column width reading from the .aux file
|
||||
%
|
||||
|
||||
|
||||
\setlongtables
|
||||
@@ -0,0 +1,37 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5-alpha4
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
702 1540 4867 1540 4867 4828 702 4828 702 1540
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4828 928 4828 928 4610 710 4610 710 4828
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
914 4610 1133 4610 1133 4391 914 4391 914 4610
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
723 4385 1133 4385 1133 4828 723 4828 723 4385
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4610 928 4610 928 4391 710 4391 710 4610
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
914 4828 1133 4828 1133 4610 914 4610 914 4828
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2068 857 6233 857 6233 4145 2068 4145 2068 857
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
1385 1198 5550 1198 5550 4487 1385 4487 1385 1198
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2089 3702 2499 3702 2499 4145 2089 4145 2089 3702
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1406 4043 1816 4043 1816 4487 1406 4487 1406 4043
|
||||
4 0 0 50 -1 0 5 0.0000 4 79 182 613 4943 (0,0)\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 80 785 2055 833 Frame: chroma plane\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 57 467 894 4009 Macroblock\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 57 228 450 4521 Block\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 57 228 450 4760 Block\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 57 148 450 4863 8x8\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 80 785 1235 1175 Frame: chroma plane\001
|
||||
4 0 0 50 -1 0 5 0.0000 4 80 694 621 1516 Frame: luma plane\001
|
||||
@@ -0,0 +1,75 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
0 32 #7f7f7f
|
||||
6 250 236 5737 4724
|
||||
6 659 4520 1068 4724
|
||||
4 1 0 50 0 0 7 0.0000 0 75 450 864 4724 X Offset\001
|
||||
4 1 0 50 0 0 7 0.0000 0 90 375 864 4596 Picture\001
|
||||
-6
|
||||
6 250 3880 454 4290
|
||||
4 1 0 50 0 0 7 1.5708 0 90 375 327 4086 Picture\001
|
||||
4 1 0 50 0 0 7 1.5708 0 75 450 454 4086 Y Offset\001
|
||||
-6
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
608 301 608 454
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
5466 301 5466 454
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 34.09 68.18
|
||||
1 1 1.00 34.09 68.18
|
||||
608 378 5466 378
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
608 4392 608 4546
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
1119 4392 1119 4546
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 34.09 68.18
|
||||
1 1 1.00 34.09 68.18
|
||||
608 4468 1119 4468
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 34.09 68.18
|
||||
1 1 1.00 34.09 68.18
|
||||
1119 4468 5211 4468
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
5211 4392 5211 4546
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
404 4340 557 4340
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
404 3830 557 3830
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
404 761 557 761
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 34.09 68.18
|
||||
1 1 1.00 34.09 68.18
|
||||
480 3830 480 761
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
5517 4340 5671 4340
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
|
||||
5517 506 5671 506
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 34.09 68.18
|
||||
1 1 1.00 34.09 68.18
|
||||
5594 4340 5594 506
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 34.09 68.18
|
||||
1 1 1.00 34.09 68.18
|
||||
480 4340 480 3830
|
||||
2 2 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
|
||||
608 506 5466 506 5466 4340 608 4340 608 506
|
||||
2 2 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
|
||||
1119 761 5211 761 5211 3830 1119 3830 1119 761
|
||||
4 1 0 50 0 0 7 0.0000 0 90 720 3165 4596 Picture Width\001
|
||||
4 1 0 50 0 0 7 1.5708 0 105 690 5722 1912 Frame Height\001
|
||||
4 1 0 50 0 0 7 0.0000 0 90 660 2782 326 Frame Width\001
|
||||
4 1 0 50 0 0 7 1.5708 0 105 750 454 2295 Picture Height\001
|
||||
4 1 0 50 0 0 7 0.0000 0 75 315 2782 685 Frame\001
|
||||
4 1 0 50 0 0 7 0.0000 0 90 375 3165 2295 Picture\001
|
||||
4 0 0 50 0 0 7 0.0000 0 105 240 659 4290 (0,0)\001
|
||||
-6
|
||||
@@ -0,0 +1,102 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 724 2025 945 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2244 945 2244 945 2025 732 2025 732 2244
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2475 945 2475 945 2256 732 2256 732 2475
|
||||
-6
|
||||
6 1665 2070 1888 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2267 1888 2267 1888 2070 1673 2070 1673 2267
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2475 1888 2475 1888 2278 1673 2278 1673 2475
|
||||
-6
|
||||
6 724 900 945 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1119 945 1119 945 900 732 900 732 1119
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1350 945 1350 945 1131 732 1131 732 1350
|
||||
-6
|
||||
6 6300 2070 6795 2520
|
||||
6 6300 2070 6570 2295
|
||||
6 6300 2070 6570 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6335 2295 6553 2295 6553 2076 6335 2076 6335 2295
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6335 2520 6553 2520 6553 2301 6335 2301 6335 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2295 6778 2295 6778 2076 6560 2076 6560 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2520 6778 2520 6778 2301 6560 2301 6560 2520
|
||||
-6
|
||||
6 4455 2070 4950 2520
|
||||
6 4455 2070 4725 2295
|
||||
6 4455 2070 4725 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2295 4708 2295 4708 2076 4490 2076 4490 2295
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2520 4708 2520 4708 2301 4490 2301 4490 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 2295 4933 2295 4933 2076 4715 2076 4715 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 2520 4933 2520 4933 2301 4715 2301 4715 2520
|
||||
-6
|
||||
6 4455 945 4950 1395
|
||||
6 4455 945 4725 1170
|
||||
6 4455 945 4725 1170
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 1170 4708 1170 4708 951 4490 951 4490 1170
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 1395 4708 1395 4708 1176 4490 1176 4490 1395
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 1170 4933 1170 4933 951 4715 951 4715 1170
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 1395 4933 1395 4933 1176 4715 1176 4715 1395
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2249 1800 3736 1800 3736 2947 2249 2947 2249 1800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2385 1935 3600 1935 3600 2745 2385 2745 2385 1935
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2745 2610 2745 2610 2526 2397 2526 2397 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3375 2745 3590 2745 3590 2548 3375 2548 3375 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
724 900 1888 900 1888 2475 724 2475 724 900
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
473 675 2003 675 2003 2925 473 2925 473 675
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2154 2610 2154 2610 1935 2397 1935 2397 2154
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
4005 720 7020 720 7020 2970 4005 2970 4005 720
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2835 2655 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 1080 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 765 1665 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2430 2385 ...\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 450 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 2205 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 3943 3098 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 4545 2655 Pixels\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 5220 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 4680 1755 ...\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 2205 1665 Frame: chroma (4:2:0 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 450 585 Frame: chroma (4:2:2 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 75 615 4005 630 Frame: luma\001
|
||||
@@ -0,0 +1,88 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 724 2025 945 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2244 945 2244 945 2025 732 2025 732 2244
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2475 945 2475 945 2256 732 2256 732 2475
|
||||
-6
|
||||
6 1665 2070 1888 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2267 1888 2267 1888 2070 1673 2070 1673 2267
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2475 1888 2475 1888 2278 1673 2278 1673 2475
|
||||
-6
|
||||
6 4455 2070 4950 2520
|
||||
6 4455 2070 4725 2295
|
||||
6 4455 2070 4725 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2295 4708 2295 4708 2076 4490 2076 4490 2295
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2520 4708 2520 4708 2301 4490 2301 4490 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 2295 4933 2295 4933 2076 4715 2076 4715 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 2520 4933 2520 4933 2301 4715 2301 4715 2520
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2249 1800 3736 1800 3736 2947 2249 2947 2249 1800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2385 1935 3600 1935 3600 2745 2385 2745 2385 1935
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2745 2610 2745 2610 2526 2397 2526 2397 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3375 2745 3590 2745 3590 2548 3375 2548 3375 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
724 900 1888 900 1888 2475 724 2475 724 900
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
473 675 2003 675 2003 2925 473 2925 473 675
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2154 2610 2154 2610 1935 2397 1935 2397 2154
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
4005 720 7020 720 7020 2970 4005 2970 4005 720
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 1170 4708 1170 4708 951 4490 951 4490 1170
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4715 1170 4933 1170 4933 951 4715 951 4715 1170
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2520 6778 2520 6778 2301 6560 2301 6560 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2295 6778 2295 6778 2076 6560 2076 6560 2295
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4715 945 4933 945 4933 726 4715 726 4715 945
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4490 945 4708 945 4708 726 4490 726 4490 945
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
6785 2295 7003 2295 7003 2076 6785 2076 6785 2295
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
6785 2520 7003 2520 7003 2301 6785 2301 6785 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1125 945 1125 945 906 732 906 732 1125
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
732 894 945 894 945 675 732 675 732 894
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2835 2655 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 1080 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 765 1665 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2430 2385 ...\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 450 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 2205 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 3943 3098 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 4545 2655 Pixels\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 5220 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 4680 1755 ...\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 2205 1665 Frame: chroma (4:2:0 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 450 585 Frame: chroma (4:2:2 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 75 615 4005 630 Frame: luma\001
|
||||
@@ -0,0 +1,90 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 724 2025 945 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2244 945 2244 945 2025 732 2025 732 2244
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2475 945 2475 945 2256 732 2256 732 2475
|
||||
-6
|
||||
6 1665 2070 1888 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2267 1888 2267 1888 2070 1673 2070 1673 2267
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2475 1888 2475 1888 2278 1673 2278 1673 2475
|
||||
-6
|
||||
6 724 900 945 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1119 945 1119 945 900 732 900 732 1119
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1350 945 1350 945 1131 732 1131 732 1350
|
||||
-6
|
||||
6 6300 2070 6795 2520
|
||||
6 6300 2070 6570 2295
|
||||
6 6300 2070 6570 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6335 2295 6553 2295 6553 2076 6335 2076 6335 2295
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6335 2520 6553 2520 6553 2301 6335 2301 6335 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2295 6778 2295 6778 2076 6560 2076 6560 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2520 6778 2520 6778 2301 6560 2301 6560 2520
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2249 1800 3736 1800 3736 2947 2249 2947 2249 1800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2385 1935 3600 1935 3600 2745 2385 2745 2385 1935
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2745 2610 2745 2610 2526 2397 2526 2397 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3375 2745 3590 2745 3590 2548 3375 2548 3375 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
724 900 1888 900 1888 2475 724 2475 724 900
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
473 675 2003 675 2003 2925 473 2925 473 675
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2154 2610 2154 2610 1935 2397 1935 2397 2154
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
4005 720 7020 720 7020 2970 4005 2970 4005 720
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2295 4708 2295 4708 2076 4490 2076 4490 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2520 4708 2520 4708 2301 4490 2301 4490 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 1170 4708 1170 4708 951 4490 951 4490 1170
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 1395 4708 1395 4708 1176 4490 1176 4490 1395
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 1170 4483 1170 4483 951 4265 951 4265 1170
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 1395 4483 1395 4483 1176 4265 1176 4265 1395
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 2295 4483 2295 4483 2076 4265 2076 4265 2295
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 2520 4483 2520 4483 2301 4265 2301 4265 2520
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2835 2655 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 1080 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 765 1665 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2430 2385 ...\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 450 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 2205 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 3943 3098 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 4545 2655 Pixels\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 5220 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 4680 1755 ...\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 2205 1665 Frame: chroma (4:2:0 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 450 585 Frame: chroma (4:2:2 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 75 615 4005 630 Frame: luma\001
|
||||
@@ -0,0 +1,84 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 724 2025 945 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2244 945 2244 945 2025 732 2025 732 2244
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 2475 945 2475 945 2256 732 2256 732 2475
|
||||
-6
|
||||
6 1665 2070 1888 2475
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2267 1888 2267 1888 2070 1673 2070 1673 2267
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1673 2475 1888 2475 1888 2278 1673 2278 1673 2475
|
||||
-6
|
||||
6 724 900 945 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1119 945 1119 945 900 732 900 732 1119
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
732 1350 945 1350 945 1131 732 1131 732 1350
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2249 1800 3736 1800 3736 2947 2249 2947 2249 1800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2385 1935 3600 1935 3600 2745 2385 2745 2385 1935
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2745 2610 2745 2610 2526 2397 2526 2397 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3375 2745 3590 2745 3590 2548 3375 2548 3375 2745
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
724 900 1888 900 1888 2475 724 2475 724 900
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
473 675 2003 675 2003 2925 473 2925 473 675
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2397 2154 2610 2154 2610 1935 2397 1935 2397 2154
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
4005 720 7020 720 7020 2970 4005 2970 4005 720
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2295 4708 2295 4708 2076 4490 2076 4490 2295
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 2520 4708 2520 4708 2301 4490 2301 4490 2520
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 2295 4483 2295 4483 2076 4265 2076 4265 2295
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 2520 4483 2520 4483 2301 4265 2301 4265 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 945 6795 945 6795 2520 4500 2520 4500 945
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2520 6778 2520 6778 2301 6560 2301 6560 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6560 2295 6778 2295 6778 2076 6560 2076 6560 2295
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
6785 2295 7003 2295 7003 2076 6785 2076 6785 2295
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
6785 2520 7003 2520 7003 2301 6785 2301 6785 2520
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4490 1170 4708 1170 4708 951 4490 951 4490 1170
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 945 4483 945 4483 726 4265 726 4265 945
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4265 1170 4483 1170 4483 951 4265 951 4265 1170
|
||||
2 2 0 1 0 11 50 -1 43 0.000 0 0 -1 0 0 5
|
||||
4490 945 4708 945 4708 726 4490 726 4490 945
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2835 2655 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 1080 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 765 1665 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 2430 2385 ...\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 450 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 2205 3060 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 3943 3098 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 4545 2655 Pixels\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 5220 2295 ...\001
|
||||
4 0 0 50 -1 0 24 0.0000 4 30 270 4680 1755 ...\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 2205 1665 Frame: chroma (4:2:0 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 105 1335 450 585 Frame: chroma (4:2:2 case)\001
|
||||
4 0 0 50 -1 0 9 0.0000 4 75 615 4005 630 Frame: luma\001
|
||||
@@ -0,0 +1,56 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 675 4365 1170 4815
|
||||
6 675 4365 945 4590
|
||||
6 675 4365 945 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4590 928 4590 928 4371 710 4371 710 4590
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4815 928 4815 928 4596 710 4596 710 4815
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
935 4590 1153 4590 1153 4371 935 4371 935 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
935 4815 1153 4815 1153 4596 935 4596 935 4815
|
||||
-6
|
||||
6 1125 4365 1646 4815
|
||||
6 1125 4365 1420 4590
|
||||
6 1125 4365 1420 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1163 4590 1401 4590 1401 4371 1163 4371 1163 4590
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1163 4815 1401 4815 1401 4596 1163 4596 1163 4815
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1409 4590 1646 4590 1646 4371 1409 4371 1409 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1409 4815 1646 4815 1646 4596 1409 4596 1409 4815
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
1665 1350 4788 1350 4788 4153 1665 4153 1665 1350
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2700 900 5823 900 5823 3703 2700 3703 2700 900
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
702 2025 3825 2025 3825 4828 702 4828 702 2025
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1800 4005 2018 4005 2018 3786 1800 3786 1800 4005
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2160 4005 2378 4005 2378 3786 2160 3786 2160 4005
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2835 3555 3053 3555 3053 3336 2835 3336 2835 3555
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3195 3555 3413 3555 3413 3336 3195 3336 3195 3555
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1215 1485 1305 Frame: chroma plane Cb\001
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1200 2565 855 Frame: chroma plane Cr\001
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1035 540 1980 Frame: luma planeY'\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 765 4320 Pixels\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 613 4943 (0,0)\001
|
||||
@@ -0,0 +1,70 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 675 4365 1170 4815
|
||||
6 675 4365 945 4590
|
||||
6 675 4365 945 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4590 928 4590 928 4371 710 4371 710 4590
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4815 928 4815 928 4596 710 4596 710 4815
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
935 4590 1153 4590 1153 4371 935 4371 935 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
935 4815 1153 4815 1153 4596 935 4596 935 4815
|
||||
-6
|
||||
6 1125 4365 1646 4815
|
||||
6 1125 4365 1420 4590
|
||||
6 1125 4365 1420 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1163 4590 1401 4590 1401 4371 1163 4371 1163 4590
|
||||
-6
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1163 4815 1401 4815 1401 4596 1163 4596 1163 4815
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1409 4590 1646 4590 1646 4371 1409 4371 1409 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1409 4815 1646 4815 1646 4596 1409 4596 1409 4815
|
||||
-6
|
||||
6 1800 3690 2025 4140
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1807 3909 2025 3909 2025 3690 1807 3690 1807 3909
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1807 4140 2025 4140 2025 3921 1807 3921 1807 4140
|
||||
-6
|
||||
6 2160 3690 2385 4140
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2167 3909 2385 3909 2385 3690 2167 3690 2167 3909
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2167 4140 2385 4140 2385 3921 2167 3921 2167 4140
|
||||
-6
|
||||
6 3195 3240 3420 3690
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3202 3459 3420 3459 3420 3240 3202 3240 3202 3459
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3202 3690 3420 3690 3420 3471 3202 3471 3202 3690
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
1665 1350 4788 1350 4788 4153 1665 4153 1665 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2842 3459 3060 3459 3060 3240 2842 3240 2842 3459
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2700 900 5823 900 5823 3703 2700 3703 2700 900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2842 3690 3060 3690 3060 3471 2842 3471 2842 3690
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
702 2025 3825 2025 3825 4828 702 4828 702 2025
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1215 1485 1305 Frame: chroma plane Cb\001
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1200 2565 855 Frame: chroma plane Cr\001
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1035 540 1980 Frame: luma planeY'\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 765 4320 Pixels\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 613 4943 (0,0)\001
|
||||
@@ -0,0 +1,44 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
702 2025 3825 2025 3825 4828 702 4828 702 2025
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
1665 1350 4788 1350 4788 4153 1665 4153 1665 1350
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2700 900 5823 900 5823 3703 2700 3703 2700 900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4590 928 4590 928 4371 710 4371 710 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
935 4590 1153 4590 1153 4371 935 4371 935 4590
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
935 4815 1153 4815 1153 4596 935 4596 935 4815
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
710 4815 928 4815 928 4596 710 4596 710 4815
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1700 3915 1918 3915 1918 3696 1700 3696 1700 3915
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1925 3915 2143 3915 2143 3696 1925 3696 1925 3915
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1925 4140 2143 4140 2143 3921 1925 3921 1925 4140
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1700 4140 1918 4140 1918 3921 1700 3921 1700 4140
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2735 3465 2953 3465 2953 3246 2735 3246 2735 3465
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2960 3465 3178 3465 3178 3246 2960 3246 2960 3465
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2960 3690 3178 3690 3178 3471 2960 3471 2960 3690
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2735 3690 2953 3690 2953 3471 2735 3471 2735 3690
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1215 1485 1305 Frame: chroma plane Cb\001
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1200 2565 855 Frame: chroma plane Cr\001
|
||||
4 0 0 50 -1 0 8 0.0000 4 105 1035 540 1980 Frame: luma planeY'\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 75 285 765 4320 Pixels\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 90 210 613 4943 (0,0)\001
|
||||
@@ -0,0 +1,91 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5-alpha4
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1125 900 1575 900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 450 1350 450 1350 1350 450 1350 450 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 450 2250 450 2250 1350 1350 1350 1350 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 450 3150 450 3150 1350 2250 1350 2250 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 450 4050 450 4050 1350 3150 1350 3150 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 1350 1350 1350 1350 2250 450 2250 450 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1350 2250 1350 2250 2250 1350 2250 1350 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 1350 3150 1350 3150 2250 2250 2250 2250 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 1350 4050 1350 4050 2250 3150 2250 3150 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 2250 1350 2250 1350 3150 450 3150 450 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 2250 2250 2250 2250 3150 1350 3150 1350 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 2250 3150 2250 3150 3150 2250 3150 2250 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 2250 4050 2250 4050 3150 3150 3150 3150 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
450 3150 1350 3150 1350 4050 450 4050 450 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 3150 2250 3150 2250 4050 1350 4050 1350 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 3150 3150 3150 3150 4050 2250 4050 2250 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3150 3150 4050 3150 4050 4050 3150 4050 3150 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4050 450 4950 450 4950 1350 4050 1350 4050 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4050 1350 4950 1350 4950 2250 4050 2250 4050 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4050 2250 4950 2250 4950 3150 4050 3150 4050 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4050 3150 4950 3150 4950 4050 4050 4050 4050 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4950 3150 5850 3150 5850 4050 4950 4050 4950 3150
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4950 2250 5850 2250 5850 3150 4950 3150 4950 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4950 1350 5850 1350 5850 2250 4950 2250 4950 1350
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4950 450 5850 450 5850 1350 4950 1350 4950 450
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1125 3600 1575 3600
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2925 3600 3375 3600
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2025 3600 2475 3600
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1125 2655 1575 2655
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4770 3600 5220 3600
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5445 3510 900 2880
|
||||
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
5400 1800 855 1170
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 900 3660 0\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 1800 3660 1\001
|
||||
4 1 0 50 0 1 12 0.0000 0 150 105 2700 3660 2\001
|
||||
4 0 0 50 -1 0 20 0.0000 4 30 225 3555 3645 ...\001
|
||||
4 0 0 50 -1 0 20 0.0000 4 30 225 945 1845 ...\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 330 5310 3645 m-1\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 435 5175 2655 2m-1\001
|
||||
4 1 0 50 0 1 12 0.0000 0 105 165 900 2760 m\001
|
||||
4 1 0 50 0 1 12 0.0000 0 195 690 855 1035 (n-1)*m\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 540 5085 900 n*m-1\001
|
||||
@@ -0,0 +1,46 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5-alpha4
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 2 1 2 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
|
||||
1980 450 2430 450 2430 900 1980 900 1980 450
|
||||
2 2 1 2 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
|
||||
2520 450 2970 450 2970 900 2520 900 2520 450
|
||||
2 2 1 2 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
|
||||
4140 450 4590 450 4590 900 4140 900 4140 450
|
||||
2 2 1 2 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
|
||||
1440 450 1890 450 1890 900 1440 900 1440 450
|
||||
2 2 1 2 0 7 50 -1 15 4.000 0 0 -1 0 0 5
|
||||
3600 450 4050 450 4050 900 3600 900 3600 450
|
||||
2 2 1 2 0 7 50 -1 41 4.000 0 0 -1 0 0 5
|
||||
3060 450 3510 450 3510 900 3060 900 3060 450
|
||||
2 2 0 2 0 7 50 -1 41 0.000 0 0 -1 0 0 5
|
||||
900 450 1350 450 1350 900 900 900 900 450
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3780 990 3780 1395
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3240 990 3240 1395
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1125 990 1125 1395
|
||||
4 0 0 50 -1 0 20 0.0000 4 30 225 4770 675 ...\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 900 405 Intra\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 1440 405 Inter\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 1980 405 Inter\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 2520 405 Inter\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 3060 405 Inter\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 3600 405 Inter\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 420 4140 405 Inter\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 120 630 3690 1575 current\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 840 2745 1575 reference\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 510 2925 1755 frame\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 510 3690 1755 frame\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 195 570 855 1575 golden\001
|
||||
4 0 0 50 -1 0 12 0.0000 4 150 510 900 1800 frame\001
|
||||
@@ -0,0 +1,120 @@
|
||||
@MANUAL{rfc2044,
|
||||
author="Francois Yergeau",
|
||||
title="{RFC} 2044: {UTF}-8, a transformation format of Unicode and {ISO}
|
||||
10646",
|
||||
month=oct,
|
||||
year=1996,
|
||||
note="\url{http://www.ietf.org/rfc/rfc2044.txt}"
|
||||
}
|
||||
|
||||
@ARTICLE{CSF77,
|
||||
author="Wen-Hsiung Chen and C. Harrison Smith and S. C. Fralick",
|
||||
title="A Fast Computational Algorithm for the Discrete Cosine Transform",
|
||||
journal="{IEEE} Transactions on Communications",
|
||||
volume="COM-25",
|
||||
number=9,
|
||||
pages="1004--1011",
|
||||
month=sep,
|
||||
year=1977
|
||||
}
|
||||
|
||||
@MISC{Mel04,
|
||||
author="Mike Melanson",
|
||||
title="{VP3} Bitstream Format and Decoding Process",
|
||||
howpublished="\url{http://www.multimedia.cx/vp3-format.txt}",
|
||||
month=mar,
|
||||
year=2004
|
||||
}
|
||||
|
||||
@MISC{Poyn97,
|
||||
author="Charles Poynton",
|
||||
title="Frequently-Asked Questions about Gamma",
|
||||
howpublished="\url{http://www.poynton.com/GammaFAQ.html}",
|
||||
month=feb,
|
||||
year=1997
|
||||
}
|
||||
|
||||
@MANUAL{rec470,
|
||||
key="ITU470",
|
||||
title="Reccomendation {ITU-R} {BT}.470-6: Conventional Television Systems",
|
||||
edition="1970, revised",
|
||||
organization="International Telecommunications Union",
|
||||
address="1211 Geneva 20, Switzerland",
|
||||
year=1998
|
||||
}
|
||||
|
||||
@MANUAL{rec601,
|
||||
key="ITU601",
|
||||
title="Reccomendation {ITU-R} {BT}.601-5: Studio Encoding Parameters of
|
||||
Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect Ratios",
|
||||
edition="1982, revised",
|
||||
organization="International Telecommunications Union",
|
||||
address="1211 Geneva 20, Switzerland",
|
||||
year=1995
|
||||
}
|
||||
|
||||
@MANUAL{rec709,
|
||||
key="ITU709",
|
||||
title="Recommendation {ITU-R} {BT}.709-5: Parameter values for the {HDTV}
|
||||
standards for production and international programme exchange",
|
||||
edition="1990, revised",
|
||||
organization="International Telecommunications Union",
|
||||
address="1211 Geneva 20, Switzerland",
|
||||
year=2002
|
||||
}
|
||||
|
||||
@MANUAL{smpte170m,
|
||||
key="SMPTE170M",
|
||||
title="{SMPTE-170M}: Television --- Composite Analog Video Signal --- {NTSC}
|
||||
for Studio Applications",
|
||||
organization="Society of Motion Pciture and Television Engineers",
|
||||
year=1994
|
||||
}
|
||||
|
||||
@MANUAL{smpte240m,
|
||||
key="SMPTE240M",
|
||||
title="{SMPTE-240M}: Television --- Signal Parameters --- 1125-Line
|
||||
High-Definition Production",
|
||||
organization="Society of Motion Pciture and Television Engineers",
|
||||
year=1999
|
||||
}
|
||||
|
||||
@MANUAL{vorbis,
|
||||
title="{Vorbis~I} specification",
|
||||
organization="{Xiph.Org Foundation}",
|
||||
year=2002,
|
||||
note="\url{http://www.xiph.org/ogg/vorbis/doc/}"
|
||||
}
|
||||
|
||||
@MANUAL{rfc2119,
|
||||
author="Scott Bradner",
|
||||
title="{RFC} 2119: Key words for use in {RFC}s to Indicate Requirement
|
||||
Levels",
|
||||
month=mar,
|
||||
year=1997,
|
||||
note="\url{http://www.ietf.org/rfc/rfc2119.txt}"
|
||||
}
|
||||
|
||||
@MANUAL{rfc3533,
|
||||
author="Silvia Pfeiffer",
|
||||
title="{RFC} 3533: The {Ogg} Encapsulation Format Version 0",
|
||||
month=may,
|
||||
year=2003,
|
||||
note="\url{http://www.ietf.org/rfc/rfc3533.txt}"
|
||||
}
|
||||
|
||||
@MANUAL{rfc3534,
|
||||
author="Linus Walleij",
|
||||
title="{RFC} 3534: The {application/ogg} Media Type",
|
||||
month=may,
|
||||
year=2003,
|
||||
note="\url{http://www.ietf.org/rfc/rfc3534.txt}"
|
||||
}
|
||||
|
||||
@MANUAL{rfc3550,
|
||||
author="H. Schulzrinne, S. Casner, R. Frederick, V. Jacobson",
|
||||
title="RTP: A Transport Protocol for Real-Time Applications",
|
||||
month=jul,
|
||||
year=2003,
|
||||
note="\url{http://www.ietf.org/rfc/rfc3550.txt}"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5-alpha4
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 270 180 5905 4860
|
||||
6 387 3531 1542 4687
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 4687 675 4687 675 4397 387 4397 387 4687
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
675 4687 963 4687 963 4397 675 4397 675 4687
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
963 4687 1252 4687 1252 4397 963 4397 963 4687
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1252 4397 1542 4397 1542 4109 1252 4109 1252 4397
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 4397 675 4397 675 4109 387 4109 387 4397
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 4109 675 4109 675 3820 387 3820 387 4109
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
963 4109 1252 4109 1252 3820 963 3820 963 4109
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1252 4109 1542 4109 1542 3820 1252 3820 1252 4109
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1252 3820 1542 3820 1542 3531 1252 3531 1252 3820
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
675 3820 963 3820 963 3531 675 3531 675 3820
|
||||
-6
|
||||
6 387 3531 1542 4687
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1252 4687 1542 4687 1542 4397 1252 4397 1252 4687
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
963 4397 1252 4397 1252 4109 963 4109 963 4397
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
963 3820 1252 3820 1252 3531 963 3531 963 3820
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 3820 675 3820 675 3531 387 3531 387 3820
|
||||
-6
|
||||
6 357 3502 1570 4715
|
||||
6 675 3820 963 4397
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
675 4397 963 4397 963 4109 675 4109 675 4397
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
675 4109 963 4109 963 3820 675 3820 675 4109
|
||||
-6
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 3531 1542 3531 1542 4687 387 4687 387 3531
|
||||
-6
|
||||
2 2 1 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
387 353 5876 353 5876 4687 387 4687 387 353
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1542 3531 2697 3531 2697 4687 1542 4687 1542 3531
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2697 3531 3854 3531 3854 4687 2697 4687 2697 3531
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 2375 1542 2375 1542 3531 387 3531 387 2375
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1542 2375 2697 2375 2697 3531 1542 3531 1542 2375
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
387 1220 1542 1220 1542 2375 387 2375 387 1220
|
||||
4 0 0 50 -1 0 7 0.0000 4 125 270 270 4831 (0,0)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 96 367 473 297 Frame\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 125 1002 501 3474 Super Block (4x4)\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 96 203 415 4657 8x8\001
|
||||
4 0 0 50 -1 0 7 0.0000 4 96 318 357 4513 Block\001
|
||||
4 0 0 50 -1 0 13 0.0000 4 20 145 4085 4081 ...\001
|
||||
4 0 0 50 -1 0 13 4.7124 4 20 145 848 815 ...\001
|
||||
-6
|
||||
@@ -0,0 +1,918 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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: dump the VP3.1 huffman tables in a form suitable for
|
||||
inclusion in the spec.
|
||||
last mod: $Id: vp3huff.c 14078 2007-10-31 21:24:44Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
typedef struct{
|
||||
unsigned long pattern;
|
||||
int nbits;
|
||||
}theora_huff_code;
|
||||
|
||||
|
||||
|
||||
/*The default Huffman codes used for VP3.1.
|
||||
These tables were generated by /experimental/derf/theora-exp/tools/huffgen.c
|
||||
using the same algorithm and sampled frequency counts used by VP3.*/
|
||||
const theora_huff_code TH_VP31_HUFF_CODES[80][32]={
|
||||
{
|
||||
{0x002D, 6},{0x0026, 7},{0x0166, 9},{0x004E, 8},
|
||||
{0x02CE,10},{0x059E,11},{0x027D,11},{0x0008, 5},
|
||||
{0x04F9,12},{0x000F, 4},{0x000E, 4},{0x001B, 5},
|
||||
{0x0006, 4},{0x0008, 4},{0x0005, 4},{0x001A, 5},
|
||||
{0x0015, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3},
|
||||
{0x0000, 3},{0x0009, 4},{0x0017, 5},{0x0029, 6},
|
||||
{0x0028, 6},{0x00B2, 8},{0x04F8,12},{0x059F,11},
|
||||
{0x009E, 9},{0x013F,10},{0x0012, 6},{0x0058, 7}
|
||||
},
|
||||
{
|
||||
{0x0010, 5},{0x0047, 7},{0x01FF, 9},{0x008C, 8},
|
||||
{0x03FC,10},{0x046A,11},{0x0469,11},{0x0022, 6},
|
||||
{0x11A1,13},{0x000E, 4},{0x000D, 4},{0x0004, 4},
|
||||
{0x0005, 4},{0x0009, 4},{0x0006, 4},{0x001E, 5},
|
||||
{0x0016, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3},
|
||||
{0x0000, 3},{0x000A, 4},{0x0017, 5},{0x007D, 7},
|
||||
{0x007E, 7},{0x011B, 9},{0x08D1,12},{0x03FD,10},
|
||||
{0x046B,11},{0x11A0,13},{0x007C, 7},{0x00FE, 8}
|
||||
},
|
||||
{
|
||||
{0x0016, 5},{0x0020, 6},{0x0086, 8},{0x0087, 8},
|
||||
{0x0367,10},{0x06CC,11},{0x06CB,11},{0x006E, 7},
|
||||
{0x366D,14},{0x000F, 4},{0x000E, 4},{0x0004, 4},
|
||||
{0x0005, 4},{0x000A, 4},{0x0006, 4},{0x001A, 5},
|
||||
{0x0011, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3},
|
||||
{0x0000, 3},{0x0009, 4},{0x0017, 5},{0x006F, 7},
|
||||
{0x006D, 7},{0x0364,10},{0x0D9A,12},{0x06CA,11},
|
||||
{0x1B37,13},{0x366C,14},{0x0042, 7},{0x00D8, 8}
|
||||
},
|
||||
{
|
||||
{0x0000, 4},{0x002D, 6},{0x00F7, 8},{0x0058, 7},
|
||||
{0x0167, 9},{0x02CB,10},{0x02CA,10},{0x000E, 6},
|
||||
{0x1661,13},{0x0003, 3},{0x0002, 3},{0x0008, 4},
|
||||
{0x0009, 4},{0x000D, 4},{0x0002, 4},{0x001F, 5},
|
||||
{0x0017, 5},{0x0001, 4},{0x000C, 4},{0x000E, 4},
|
||||
{0x000A, 4},{0x0006, 5},{0x0078, 7},{0x000F, 6},
|
||||
{0x007A, 7},{0x0164, 9},{0x0599,11},{0x02CD,10},
|
||||
{0x0B31,12},{0x1660,13},{0x0079, 7},{0x00F6, 8}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x003C, 6},{0x000F, 7},{0x007A, 7},
|
||||
{0x001D, 8},{0x0020, 9},{0x0072,10},{0x0006, 6},
|
||||
{0x0399,13},{0x0004, 3},{0x0005, 3},{0x0005, 4},
|
||||
{0x0006, 4},{0x000E, 4},{0x0004, 4},{0x0000, 4},
|
||||
{0x0019, 5},{0x0002, 4},{0x000D, 4},{0x0007, 4},
|
||||
{0x001F, 5},{0x0030, 6},{0x0011, 8},{0x0031, 6},
|
||||
{0x0005, 6},{0x0021, 9},{0x00E7,11},{0x0038, 9},
|
||||
{0x01CD,12},{0x0398,13},{0x007B, 7},{0x0009, 7}
|
||||
},
|
||||
{
|
||||
{0x0009, 4},{0x0002, 5},{0x0074, 7},{0x0007, 6},
|
||||
{0x00EC, 8},{0x00D1, 9},{0x01A6,10},{0x0006, 6},
|
||||
{0x0D21,13},{0x0005, 3},{0x0006, 3},{0x0008, 4},
|
||||
{0x0007, 4},{0x000F, 4},{0x0004, 4},{0x0000, 4},
|
||||
{0x001C, 5},{0x0002, 4},{0x0005, 4},{0x0003, 4},
|
||||
{0x000C, 5},{0x0035, 7},{0x01A7,10},{0x001B, 6},
|
||||
{0x0077, 7},{0x01A5,10},{0x0349,11},{0x00D0, 9},
|
||||
{0x0691,12},{0x0D20,13},{0x0075, 7},{0x00ED, 8}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x000C, 5},{0x0012, 6},{0x001B, 6},
|
||||
{0x00B7, 8},{0x016C, 9},{0x0099, 9},{0x005A, 7},
|
||||
{0x16D8,13},{0x0007, 3},{0x0006, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0000, 3},{0x0005, 4},{0x0017, 5},
|
||||
{0x000E, 5},{0x0002, 4},{0x0003, 4},{0x000F, 5},
|
||||
{0x001A, 6},{0x004D, 8},{0x2DB3,14},{0x002C, 6},
|
||||
{0x0011, 6},{0x02DA,10},{0x05B7,11},{0x0098, 9},
|
||||
{0x0B6D,12},{0x2DB2,14},{0x0010, 6},{0x0027, 7}
|
||||
},
|
||||
{
|
||||
{0x000D, 4},{0x000F, 5},{0x001D, 6},{0x0008, 5},
|
||||
{0x0051, 7},{0x0056, 8},{0x00AF, 9},{0x002A, 7},
|
||||
{0x148A,13},{0x0007, 3},{0x0000, 2},{0x0008, 4},
|
||||
{0x0009, 4},{0x000C, 4},{0x0006, 4},{0x0017, 5},
|
||||
{0x000B, 5},{0x0016, 5},{0x0015, 5},{0x0009, 5},
|
||||
{0x0050, 7},{0x00AE, 9},{0x2917,14},{0x001C, 6},
|
||||
{0x0014, 6},{0x0290,10},{0x0523,11},{0x0149, 9},
|
||||
{0x0A44,12},{0x2916,14},{0x0053, 7},{0x00A5, 8}
|
||||
},
|
||||
{
|
||||
{0x0001, 4},{0x001D, 6},{0x00F5, 8},{0x00F4, 8},
|
||||
{0x024D,10},{0x0499,11},{0x0498,11},{0x0001, 5},
|
||||
{0x0021, 6},{0x0006, 3},{0x0005, 3},{0x0006, 4},
|
||||
{0x0005, 4},{0x0002, 4},{0x0007, 5},{0x0025, 6},
|
||||
{0x007B, 7},{0x001C, 6},{0x0020, 6},{0x000D, 6},
|
||||
{0x0048, 7},{0x0092, 8},{0x0127, 9},{0x000E, 4},
|
||||
{0x0004, 4},{0x0011, 5},{0x000C, 6},{0x003C, 6},
|
||||
{0x000F, 5},{0x0000, 5},{0x001F, 5},{0x0013, 5}
|
||||
},
|
||||
{
|
||||
{0x0005, 4},{0x003C, 6},{0x0040, 7},{0x000D, 7},
|
||||
{0x0031, 9},{0x0061,10},{0x0060,10},{0x0002, 5},
|
||||
{0x00F5, 8},{0x0006, 3},{0x0005, 3},{0x0007, 4},
|
||||
{0x0006, 4},{0x0002, 4},{0x0009, 5},{0x0025, 6},
|
||||
{0x0007, 6},{0x0021, 6},{0x0024, 6},{0x0010, 6},
|
||||
{0x0041, 7},{0x00F4, 8},{0x0019, 8},{0x000E, 4},
|
||||
{0x0003, 4},{0x0011, 5},{0x0011, 6},{0x003F, 6},
|
||||
{0x003E, 6},{0x007B, 7},{0x0000, 4},{0x0013, 5}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x0007, 5},{0x0001, 6},{0x0009, 6},
|
||||
{0x0131, 9},{0x0261,10},{0x0260,10},{0x0015, 6},
|
||||
{0x0001, 7},{0x0007, 3},{0x0006, 3},{0x0008, 4},
|
||||
{0x0007, 4},{0x0006, 4},{0x0012, 5},{0x002F, 6},
|
||||
{0x0014, 6},{0x0027, 6},{0x002D, 6},{0x0016, 6},
|
||||
{0x004D, 7},{0x0099, 8},{0x0000, 7},{0x0004, 4},
|
||||
{0x0001, 4},{0x0005, 5},{0x0017, 6},{0x002E, 6},
|
||||
{0x002C, 6},{0x0008, 6},{0x0006, 5},{0x0001, 5}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x000E, 5},{0x0017, 6},{0x002A, 6},
|
||||
{0x0010, 7},{0x00F9,10},{0x00F8,10},{0x001E, 7},
|
||||
{0x003F, 8},{0x0007, 3},{0x0006, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0006, 4},{0x000F, 5},{0x0005, 5},
|
||||
{0x0016, 6},{0x0029, 6},{0x002B, 6},{0x0015, 6},
|
||||
{0x0050, 7},{0x0011, 7},{0x007D, 9},{0x0004, 4},
|
||||
{0x0017, 5},{0x0006, 5},{0x0014, 6},{0x002C, 6},
|
||||
{0x002D, 6},{0x000E, 6},{0x0009, 6},{0x0051, 7}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0018, 5},{0x002F, 6},{0x000D, 5},
|
||||
{0x0053, 7},{0x0295,10},{0x0294,10},{0x00A4, 8},
|
||||
{0x007C, 8},{0x0000, 2},{0x0007, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x001B, 5},{0x000C, 5},{0x0028, 6},
|
||||
{0x006A, 7},{0x001E, 6},{0x001D, 6},{0x0069, 7},
|
||||
{0x00D7, 8},{0x007D, 8},{0x014B, 9},{0x0019, 5},
|
||||
{0x0016, 5},{0x002E, 6},{0x001C, 6},{0x002B, 6},
|
||||
{0x002A, 6},{0x0068, 7},{0x003F, 7},{0x00D6, 8}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x001B, 5},{0x000C, 5},{0x0018, 5},
|
||||
{0x0029, 6},{0x007F, 8},{0x02F0,10},{0x0198, 9},
|
||||
{0x0179, 9},{0x0000, 2},{0x0007, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x001A, 5},{0x000D, 5},{0x002A, 6},
|
||||
{0x0064, 7},{0x001E, 6},{0x0067, 7},{0x005F, 7},
|
||||
{0x00CD, 8},{0x007E, 8},{0x02F1,10},{0x0016, 5},
|
||||
{0x000E, 5},{0x002E, 6},{0x0065, 7},{0x002B, 6},
|
||||
{0x0028, 6},{0x003E, 7},{0x00BD, 8},{0x0199, 9}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0007, 4},{0x0016, 5},{0x0006, 4},
|
||||
{0x0036, 6},{0x005C, 7},{0x015D, 9},{0x015C, 9},
|
||||
{0x02BF,10},{0x0000, 2},{0x0007, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0018, 5},{0x0034, 6},{0x002A, 6},
|
||||
{0x005E, 7},{0x006A, 7},{0x0064, 7},{0x005D, 7},
|
||||
{0x00CB, 8},{0x00AD, 8},{0x02BE,10},{0x0014, 5},
|
||||
{0x0033, 6},{0x006E, 7},{0x005F, 7},{0x006F, 7},
|
||||
{0x006B, 7},{0x00CA, 8},{0x00AC, 8},{0x015E, 9}
|
||||
},
|
||||
{
|
||||
{0x000F, 4},{0x001D, 5},{0x0018, 5},{0x000B, 4},
|
||||
{0x0019, 5},{0x0029, 6},{0x00D6, 8},{0x0551,11},
|
||||
{0x0AA1,12},{0x0001, 2},{0x0000, 2},{0x0009, 4},
|
||||
{0x0008, 4},{0x001B, 5},{0x0038, 6},{0x0028, 6},
|
||||
{0x0057, 7},{0x006A, 7},{0x0068, 7},{0x0056, 7},
|
||||
{0x00E5, 8},{0x0155, 9},{0x0AA0,12},{0x0073, 7},
|
||||
{0x0069, 7},{0x00D7, 8},{0x00AB, 8},{0x00E4, 8},
|
||||
{0x00A9, 8},{0x0151, 9},{0x0150, 9},{0x02A9,10}
|
||||
},
|
||||
{
|
||||
{0x0008, 5},{0x0025, 7},{0x017A, 9},{0x02F7,10},
|
||||
{0x0BDB,12},{0x17B4,13},{0x2F6B,14},{0x001D, 5},
|
||||
{0x2F6A,14},{0x0008, 4},{0x0007, 4},{0x0001, 4},
|
||||
{0x0002, 4},{0x000A, 4},{0x0006, 4},{0x0000, 4},
|
||||
{0x001C, 5},{0x0009, 4},{0x000D, 4},{0x000F, 4},
|
||||
{0x000C, 4},{0x0003, 4},{0x000A, 5},{0x0016, 5},
|
||||
{0x0013, 6},{0x005D, 7},{0x0024, 7},{0x00BC, 8},
|
||||
{0x005C, 7},{0x05EC,11},{0x000B, 5},{0x005F, 7}
|
||||
},
|
||||
{
|
||||
{0x000F, 5},{0x0010, 6},{0x004B, 8},{0x00C6, 8},
|
||||
{0x031D,10},{0x0C71,12},{0x0C70,12},{0x0001, 4},
|
||||
{0x0C73,12},{0x0008, 4},{0x0009, 4},{0x0002, 4},
|
||||
{0x0003, 4},{0x000B, 4},{0x0006, 4},{0x0000, 4},
|
||||
{0x001C, 5},{0x0005, 4},{0x000D, 4},{0x000F, 4},
|
||||
{0x000A, 4},{0x0019, 5},{0x0013, 6},{0x001D, 5},
|
||||
{0x0030, 6},{0x0062, 7},{0x0024, 7},{0x004A, 8},
|
||||
{0x018F, 9},{0x0C72,12},{0x000E, 5},{0x0011, 6}
|
||||
},
|
||||
{
|
||||
{0x001B, 5},{0x0003, 6},{0x008D, 8},{0x0040, 7},
|
||||
{0x0239,10},{0x0471,11},{0x08E0,12},{0x0003, 4},
|
||||
{0x11C3,13},{0x000A, 4},{0x0009, 4},{0x0004, 4},
|
||||
{0x0005, 4},{0x000E, 4},{0x0007, 4},{0x0001, 4},
|
||||
{0x001E, 5},{0x0006, 4},{0x000C, 4},{0x000B, 4},
|
||||
{0x0002, 4},{0x0000, 5},{0x0041, 7},{0x001F, 5},
|
||||
{0x0022, 6},{0x0002, 6},{0x008F, 8},{0x008C, 8},
|
||||
{0x011D, 9},{0x11C2,13},{0x001A, 5},{0x0021, 6}
|
||||
},
|
||||
{
|
||||
{0x001F, 5},{0x0003, 6},{0x0003, 7},{0x0043, 7},
|
||||
{0x000B, 9},{0x0015,10},{0x0051,12},{0x0003, 4},
|
||||
{0x0050,12},{0x000D, 4},{0x000C, 4},{0x0004, 4},
|
||||
{0x0006, 4},{0x000E, 4},{0x000A, 4},{0x0001, 4},
|
||||
{0x001E, 5},{0x0005, 4},{0x0009, 4},{0x0007, 4},
|
||||
{0x0011, 5},{0x0002, 6},{0x0004, 8},{0x0002, 4},
|
||||
{0x002D, 6},{0x0020, 6},{0x0042, 7},{0x0001, 7},
|
||||
{0x0000, 7},{0x0029,11},{0x0017, 5},{0x002C, 6}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x001F, 6},{0x003A, 7},{0x005D, 7},
|
||||
{0x0173, 9},{0x02E4,10},{0x172D,13},{0x0004, 4},
|
||||
{0x172C,13},{0x000F, 4},{0x000E, 4},{0x0009, 4},
|
||||
{0x0008, 4},{0x000C, 4},{0x000A, 4},{0x0001, 4},
|
||||
{0x0016, 5},{0x0002, 4},{0x0005, 4},{0x001A, 5},
|
||||
{0x002F, 6},{0x0038, 7},{0x05CA,11},{0x0006, 4},
|
||||
{0x0037, 6},{0x001E, 6},{0x003B, 7},{0x0039, 7},
|
||||
{0x00B8, 8},{0x0B97,12},{0x0000, 4},{0x0036, 6}
|
||||
},
|
||||
{
|
||||
{0x0006, 4},{0x0037, 6},{0x005D, 7},{0x000C, 6},
|
||||
{0x00B9, 8},{0x02E3,10},{0x05C4,11},{0x0004, 4},
|
||||
{0x1715,13},{0x0000, 3},{0x000F, 4},{0x0008, 4},
|
||||
{0x0007, 4},{0x000C, 4},{0x0009, 4},{0x001D, 5},
|
||||
{0x0016, 5},{0x001C, 5},{0x001A, 5},{0x000B, 5},
|
||||
{0x005E, 7},{0x0170, 9},{0x1714,13},{0x000A, 4},
|
||||
{0x000A, 5},{0x0036, 6},{0x005F, 7},{0x001B, 7},
|
||||
{0x001A, 7},{0x0B8B,12},{0x0002, 4},{0x0007, 5}
|
||||
},
|
||||
{
|
||||
{0x000C, 4},{0x000B, 5},{0x0079, 7},{0x0022, 6},
|
||||
{0x00F0, 8},{0x0119, 9},{0x0230,10},{0x001D, 5},
|
||||
{0x08C4,12},{0x0001, 3},{0x0000, 3},{0x000A, 4},
|
||||
{0x0009, 4},{0x000B, 4},{0x0007, 4},{0x001C, 5},
|
||||
{0x003D, 6},{0x000D, 5},{0x0008, 5},{0x0015, 6},
|
||||
{0x008D, 8},{0x118B,13},{0x118A,13},{0x000D, 4},
|
||||
{0x0010, 5},{0x0009, 5},{0x0014, 6},{0x0047, 7},
|
||||
{0x00F1, 8},{0x0463,11},{0x001F, 5},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x001A, 5},{0x0033, 6},{0x000C, 5},
|
||||
{0x0046, 7},{0x01E3, 9},{0x03C5,10},{0x0017, 5},
|
||||
{0x1E21,13},{0x0002, 3},{0x0001, 3},{0x0009, 4},
|
||||
{0x000A, 4},{0x0007, 4},{0x001B, 5},{0x003D, 6},
|
||||
{0x001B, 6},{0x0022, 6},{0x0079, 7},{0x00F0, 8},
|
||||
{0x1E20,13},{0x1E23,13},{0x1E22,13},{0x000E, 4},
|
||||
{0x0016, 5},{0x0018, 5},{0x0032, 6},{0x001A, 6},
|
||||
{0x0047, 7},{0x0789,11},{0x001F, 5},{0x0010, 5}
|
||||
},
|
||||
{
|
||||
{0x001D, 5},{0x0061, 7},{0x004E, 8},{0x009E, 9},
|
||||
{0x027C,11},{0x09F5,13},{0x09F4,13},{0x0003, 4},
|
||||
{0x0060, 7},{0x0000, 3},{0x000F, 4},{0x000B, 4},
|
||||
{0x000A, 4},{0x0009, 4},{0x0005, 4},{0x000D, 5},
|
||||
{0x0031, 6},{0x0008, 5},{0x0038, 6},{0x0012, 6},
|
||||
{0x0026, 7},{0x013F,10},{0x04FB,12},{0x000D, 4},
|
||||
{0x0002, 4},{0x000C, 5},{0x0039, 6},{0x001C, 6},
|
||||
{0x000F, 5},{0x001D, 6},{0x0008, 4},{0x0019, 5}
|
||||
},
|
||||
{
|
||||
{0x0007, 4},{0x0019, 6},{0x00AB, 8},{0x00AA, 8},
|
||||
{0x0119,10},{0x0461,12},{0x0460,12},{0x001B, 5},
|
||||
{0x0047, 8},{0x0001, 3},{0x0000, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x0009, 4},{0x0005, 4},{0x000D, 5},
|
||||
{0x0035, 6},{0x003D, 6},{0x003C, 6},{0x0018, 6},
|
||||
{0x0022, 7},{0x008D, 9},{0x0231,11},{0x000E, 4},
|
||||
{0x001F, 5},{0x0009, 5},{0x002B, 6},{0x0010, 6},
|
||||
{0x0034, 6},{0x0054, 7},{0x0008, 4},{0x0014, 5}
|
||||
},
|
||||
{
|
||||
{0x000C, 4},{0x0005, 5},{0x0008, 6},{0x005B, 7},
|
||||
{0x004D, 9},{0x0131,11},{0x0261,12},{0x001A, 5},
|
||||
{0x0012, 7},{0x0000, 3},{0x000F, 4},{0x000A, 4},
|
||||
{0x0009, 4},{0x0006, 4},{0x001B, 5},{0x0006, 5},
|
||||
{0x001C, 6},{0x002C, 6},{0x0015, 6},{0x005A, 7},
|
||||
{0x0027, 8},{0x0099,10},{0x0260,12},{0x000E, 4},
|
||||
{0x0004, 4},{0x000F, 5},{0x0007, 5},{0x001D, 6},
|
||||
{0x000B, 5},{0x0014, 6},{0x0008, 4},{0x0017, 5}
|
||||
},
|
||||
{
|
||||
{0x000F, 4},{0x0013, 5},{0x0075, 7},{0x0024, 6},
|
||||
{0x0095, 8},{0x0251,10},{0x04A0,11},{0x0010, 5},
|
||||
{0x00C8, 8},{0x0002, 3},{0x0001, 3},{0x0001, 4},
|
||||
{0x0000, 4},{0x001A, 5},{0x0011, 5},{0x002C, 6},
|
||||
{0x0065, 7},{0x0074, 7},{0x004B, 7},{0x00C9, 8},
|
||||
{0x0129, 9},{0x0943,12},{0x0942,12},{0x0003, 3},
|
||||
{0x000A, 4},{0x001C, 5},{0x0018, 5},{0x0033, 6},
|
||||
{0x0017, 5},{0x002D, 6},{0x001B, 5},{0x003B, 6}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x001A, 5},{0x002D, 6},{0x0038, 6},
|
||||
{0x0028, 7},{0x0395,10},{0x0E51,12},{0x0037, 6},
|
||||
{0x00E4, 8},{0x0001, 3},{0x0000, 3},{0x001F, 5},
|
||||
{0x001E, 5},{0x0017, 5},{0x003A, 6},{0x0073, 7},
|
||||
{0x002A, 7},{0x002B, 7},{0x0029, 7},{0x01CB, 9},
|
||||
{0x0729,11},{0x1CA1,13},{0x1CA0,13},{0x0004, 3},
|
||||
{0x000A, 4},{0x0004, 4},{0x0018, 5},{0x0036, 6},
|
||||
{0x000B, 5},{0x002C, 6},{0x0019, 5},{0x003B, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0004, 4},{0x003F, 6},{0x0017, 5},
|
||||
{0x0075, 7},{0x01F5, 9},{0x07D1,11},{0x0017, 6},
|
||||
{0x01F6, 9},{0x0001, 3},{0x0000, 3},{0x001B, 5},
|
||||
{0x001A, 5},{0x000A, 5},{0x0032, 6},{0x0074, 7},
|
||||
{0x00F8, 8},{0x00F9, 8},{0x01F7, 9},{0x03E9,10},
|
||||
{0x0FA0,12},{0x1F43,13},{0x1F42,13},{0x0003, 3},
|
||||
{0x000A, 4},{0x001E, 5},{0x001C, 5},{0x003B, 6},
|
||||
{0x0018, 5},{0x0016, 6},{0x0016, 5},{0x0033, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0007, 4},{0x0018, 5},{0x001E, 5},
|
||||
{0x0036, 6},{0x0031, 7},{0x0177, 9},{0x0077, 7},
|
||||
{0x0176, 9},{0x0001, 3},{0x0000, 3},{0x001A, 5},
|
||||
{0x0019, 5},{0x003A, 6},{0x0019, 6},{0x005C, 7},
|
||||
{0x00BA, 8},{0x0061, 8},{0x00C1, 9},{0x0180,10},
|
||||
{0x0302,11},{0x0607,12},{0x0606,12},{0x0002, 3},
|
||||
{0x000A, 4},{0x001F, 5},{0x001C, 5},{0x0037, 6},
|
||||
{0x0016, 5},{0x0076, 7},{0x000D, 5},{0x002F, 6}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x000A, 4},{0x001A, 5},{0x000C, 4},
|
||||
{0x001D, 5},{0x0039, 6},{0x0078, 7},{0x005E, 7},
|
||||
{0x0393,11},{0x0002, 3},{0x0001, 3},{0x0016, 5},
|
||||
{0x000F, 5},{0x002E, 6},{0x005F, 7},{0x0073, 8},
|
||||
{0x00E5, 9},{0x01C8,10},{0x0E4A,13},{0x1C97,14},
|
||||
{0x1C96,14},{0x0E49,13},{0x0E48,13},{0x0004, 3},
|
||||
{0x0006, 4},{0x001F, 5},{0x001B, 5},{0x001D, 6},
|
||||
{0x0038, 6},{0x0038, 7},{0x003D, 6},{0x0079, 7}
|
||||
},
|
||||
{
|
||||
{0x000B, 5},{0x002B, 7},{0x0054, 8},{0x01B7, 9},
|
||||
{0x06D9,11},{0x0DB1,12},{0x0DB0,12},{0x0002, 4},
|
||||
{0x00AB, 9},{0x0009, 4},{0x000A, 4},{0x0007, 4},
|
||||
{0x0008, 4},{0x000F, 4},{0x000C, 4},{0x0003, 4},
|
||||
{0x001D, 5},{0x0004, 4},{0x000B, 4},{0x0006, 4},
|
||||
{0x001A, 5},{0x0003, 6},{0x00AA, 9},{0x0001, 4},
|
||||
{0x0000, 5},{0x0014, 6},{0x006C, 7},{0x00DA, 8},
|
||||
{0x0002, 6},{0x036D,10},{0x001C, 5},{0x0037, 6}
|
||||
},
|
||||
{
|
||||
{0x001D, 5},{0x0004, 6},{0x00B6, 8},{0x006A, 8},
|
||||
{0x05B9,11},{0x16E1,13},{0x16E0,13},{0x0007, 4},
|
||||
{0x016F, 9},{0x000C, 4},{0x000D, 4},{0x0009, 4},
|
||||
{0x0008, 4},{0x000F, 4},{0x000A, 4},{0x0003, 4},
|
||||
{0x0017, 5},{0x0002, 4},{0x0004, 4},{0x001C, 5},
|
||||
{0x002C, 6},{0x006B, 8},{0x0B71,12},{0x0005, 4},
|
||||
{0x0003, 5},{0x001B, 6},{0x005A, 7},{0x0034, 7},
|
||||
{0x0005, 6},{0x02DD,10},{0x0000, 4},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x007F, 7},{0x00A1, 8},{0x00A0, 8},
|
||||
{0x020C,10},{0x0834,12},{0x106B,13},{0x0007, 4},
|
||||
{0x0082, 8},{0x000E, 4},{0x000D, 4},{0x000B, 4},
|
||||
{0x000C, 4},{0x0000, 3},{0x0009, 4},{0x0002, 4},
|
||||
{0x0011, 5},{0x001E, 5},{0x0015, 5},{0x003E, 6},
|
||||
{0x0040, 7},{0x041B,11},{0x106A,13},{0x0006, 4},
|
||||
{0x000A, 5},{0x0029, 6},{0x007E, 7},{0x0051, 7},
|
||||
{0x0021, 6},{0x0107, 9},{0x0004, 4},{0x000B, 5}
|
||||
},
|
||||
{
|
||||
{0x0007, 4},{0x001B, 6},{0x00F6, 8},{0x00E9, 8},
|
||||
{0x03A1,10},{0x0740,11},{0x0E82,12},{0x001F, 5},
|
||||
{0x01EF, 9},{0x0001, 3},{0x0002, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x000D, 4},{0x0008, 4},{0x001C, 5},
|
||||
{0x0003, 5},{0x0012, 5},{0x0002, 5},{0x0075, 7},
|
||||
{0x01D1, 9},{0x1D07,13},{0x1D06,13},{0x000A, 4},
|
||||
{0x0013, 5},{0x003B, 6},{0x001A, 6},{0x007A, 7},
|
||||
{0x003C, 6},{0x01EE, 9},{0x0000, 4},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x000D, 4},{0x003D, 6},{0x0042, 7},{0x0037, 7},
|
||||
{0x00D9, 9},{0x0362,11},{0x06C6,12},{0x001F, 5},
|
||||
{0x0086, 8},{0x0001, 3},{0x0002, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x000A, 4},{0x0001, 4},{0x000F, 5},
|
||||
{0x0025, 6},{0x003C, 6},{0x001A, 6},{0x0087, 8},
|
||||
{0x01B0,10},{0x0D8F,13},{0x0D8E,13},{0x000E, 4},
|
||||
{0x0013, 5},{0x000C, 5},{0x0024, 6},{0x0020, 6},
|
||||
{0x0011, 5},{0x006D, 8},{0x0000, 4},{0x000E, 5}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x0012, 5},{0x0076, 7},{0x0077, 7},
|
||||
{0x014D, 9},{0x0533,11},{0x14C9,13},{0x0013, 5},
|
||||
{0x00A5, 8},{0x0002, 3},{0x0003, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x0008, 4},{0x001A, 5},{0x002B, 6},
|
||||
{0x0075, 7},{0x0074, 7},{0x00A7, 8},{0x0298,10},
|
||||
{0x14C8,13},{0x14CB,13},{0x14CA,13},{0x000F, 4},
|
||||
{0x001C, 5},{0x0007, 5},{0x002A, 6},{0x0028, 6},
|
||||
{0x001B, 5},{0x00A4, 8},{0x0002, 4},{0x0006, 5}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x001A, 5},{0x002B, 6},{0x003A, 6},
|
||||
{0x00ED, 8},{0x0283,10},{0x0A0A,12},{0x0004, 5},
|
||||
{0x00A1, 8},{0x0004, 3},{0x0003, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x001F, 5},{0x0006, 5},{0x0077, 7},
|
||||
{0x00A3, 8},{0x00A2, 8},{0x0140, 9},{0x1417,13},
|
||||
{0x1416,13},{0x0A09,12},{0x0A08,12},{0x0000, 3},
|
||||
{0x001E, 5},{0x0007, 5},{0x002A, 6},{0x0029, 6},
|
||||
{0x001C, 5},{0x00EC, 8},{0x001B, 5},{0x0005, 5}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0002, 4},{0x0018, 5},{0x001D, 5},
|
||||
{0x0035, 6},{0x00E4, 8},{0x01CF,11},{0x001D, 7},
|
||||
{0x0072, 9},{0x0004, 3},{0x0005, 3},{0x0006, 4},
|
||||
{0x0007, 4},{0x0006, 5},{0x0073, 7},{0x0038, 8},
|
||||
{0x01CE,11},{0x039B,12},{0x0398,12},{0x0733,13},
|
||||
{0x0732,13},{0x0735,13},{0x0734,13},{0x0000, 3},
|
||||
{0x001F, 5},{0x001B, 5},{0x0034, 6},{0x000F, 6},
|
||||
{0x001E, 5},{0x00E5, 8},{0x0019, 5},{0x0038, 6}
|
||||
},
|
||||
{
|
||||
{0x0016, 5},{0x0050, 7},{0x0172, 9},{0x02E7,10},
|
||||
{0x1732,13},{0x2E67,14},{0x2E66,14},{0x0006, 4},
|
||||
{0x0051, 7},{0x0001, 3},{0x0000, 3},{0x000D, 4},
|
||||
{0x000C, 4},{0x0009, 4},{0x001C, 5},{0x0009, 5},
|
||||
{0x001C, 6},{0x001D, 6},{0x005D, 7},{0x00B8, 8},
|
||||
{0x05CD,11},{0x1731,13},{0x1730,13},{0x000F, 4},
|
||||
{0x0005, 4},{0x000F, 5},{0x0008, 5},{0x0029, 6},
|
||||
{0x001D, 5},{0x002F, 6},{0x0008, 4},{0x0015, 5}
|
||||
},
|
||||
{
|
||||
{0x0009, 4},{0x0021, 6},{0x0040, 7},{0x00AD, 8},
|
||||
{0x02B0,10},{0x1589,13},{0x1588,13},{0x001C, 5},
|
||||
{0x005F, 7},{0x0000, 3},{0x000F, 4},{0x000D, 4},
|
||||
{0x000C, 4},{0x0006, 4},{0x0011, 5},{0x002A, 6},
|
||||
{0x0057, 7},{0x005E, 7},{0x0041, 7},{0x0159, 9},
|
||||
{0x0563,11},{0x158B,13},{0x158A,13},{0x0001, 3},
|
||||
{0x0005, 4},{0x0014, 5},{0x003B, 6},{0x002E, 6},
|
||||
{0x0004, 4},{0x003A, 6},{0x0007, 4},{0x0016, 5}
|
||||
},
|
||||
{
|
||||
{0x000E, 4},{0x0007, 5},{0x0046, 7},{0x0045, 7},
|
||||
{0x0064, 9},{0x032A,12},{0x0657,13},{0x0018, 5},
|
||||
{0x000D, 6},{0x0000, 3},{0x000F, 4},{0x000A, 4},
|
||||
{0x000B, 4},{0x001A, 5},{0x0036, 6},{0x0047, 7},
|
||||
{0x0044, 7},{0x0018, 7},{0x0033, 8},{0x00CB,10},
|
||||
{0x0656,13},{0x0329,12},{0x0328,12},{0x0002, 3},
|
||||
{0x0006, 4},{0x0019, 5},{0x000E, 5},{0x0037, 6},
|
||||
{0x0009, 4},{0x000F, 5},{0x0002, 4},{0x0010, 5}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x0018, 5},{0x0023, 6},{0x0077, 7},
|
||||
{0x0194, 9},{0x1956,13},{0x32AF,14},{0x003A, 6},
|
||||
{0x0076, 7},{0x0002, 3},{0x0001, 3},{0x001F, 5},
|
||||
{0x001E, 5},{0x0014, 5},{0x0022, 6},{0x0064, 7},
|
||||
{0x0197, 9},{0x0196, 9},{0x032B,10},{0x0654,11},
|
||||
{0x32AE,14},{0x1955,13},{0x1954,13},{0x0000, 3},
|
||||
{0x0009, 4},{0x001C, 5},{0x0015, 5},{0x0010, 5},
|
||||
{0x000D, 4},{0x0017, 5},{0x0016, 5},{0x0033, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0006, 4},{0x003E, 6},{0x0010, 5},
|
||||
{0x0048, 7},{0x093F,12},{0x24FA,14},{0x0032, 6},
|
||||
{0x0067, 7},{0x0002, 3},{0x0001, 3},{0x001B, 5},
|
||||
{0x001E, 5},{0x0034, 6},{0x0066, 7},{0x0092, 8},
|
||||
{0x0126, 9},{0x024E,10},{0x049E,11},{0x49F7,15},
|
||||
{0x49F6,15},{0x24F9,14},{0x24F8,14},{0x0000, 3},
|
||||
{0x0007, 4},{0x0018, 5},{0x0011, 5},{0x003F, 6},
|
||||
{0x000E, 4},{0x0013, 5},{0x0035, 6},{0x0025, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0008, 4},{0x0012, 5},{0x001C, 5},
|
||||
{0x001C, 6},{0x00EA, 9},{0x1D75,14},{0x001E, 6},
|
||||
{0x0066, 7},{0x0001, 3},{0x0002, 3},{0x001B, 5},
|
||||
{0x001A, 5},{0x001F, 6},{0x003B, 7},{0x0074, 8},
|
||||
{0x01D6,10},{0x03AF,11},{0x1D74,14},{0x1D77,14},
|
||||
{0x1D76,14},{0x0EB9,13},{0x0EB8,13},{0x000F, 4},
|
||||
{0x0006, 4},{0x0013, 5},{0x003B, 6},{0x003A, 6},
|
||||
{0x0000, 3},{0x0018, 5},{0x0032, 6},{0x0067, 7}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000A, 4},{0x001B, 5},{0x000C, 4},
|
||||
{0x000D, 5},{0x00E6, 8},{0x0684,11},{0x0072, 7},
|
||||
{0x00E7, 8},{0x0002, 3},{0x0001, 3},{0x0017, 5},
|
||||
{0x0016, 5},{0x0018, 6},{0x00D1, 8},{0x01A0, 9},
|
||||
{0x0686,11},{0x0D0F,12},{0x0D0A,12},{0x1A17,13},
|
||||
{0x1A16,13},{0x1A1D,13},{0x1A1C,13},{0x000F, 4},
|
||||
{0x001D, 5},{0x000E, 5},{0x0035, 6},{0x0038, 6},
|
||||
{0x0000, 3},{0x000F, 5},{0x0019, 6},{0x0069, 7}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x000C, 4},{0x001B, 5},{0x0000, 3},
|
||||
{0x0003, 4},{0x002E, 6},{0x0051, 9},{0x00BC, 8},
|
||||
{0x0053, 9},{0x0004, 3},{0x0002, 3},{0x0016, 5},
|
||||
{0x0015, 5},{0x0015, 7},{0x0050, 9},{0x00A4,10},
|
||||
{0x0294,12},{0x052B,13},{0x052A,13},{0x052D,13},
|
||||
{0x052C,13},{0x052F,13},{0x052E,13},{0x000E, 4},
|
||||
{0x001A, 5},{0x0004, 5},{0x0028, 6},{0x0029, 6},
|
||||
{0x000F, 4},{0x000B, 6},{0x005F, 7},{0x00BD, 8}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x0009, 6},{0x00D0, 8},{0x01A3, 9},
|
||||
{0x0344,10},{0x0D14,12},{0x1A2B,13},{0x0004, 4},
|
||||
{0x0015, 7},{0x0000, 3},{0x000F, 4},{0x000B, 4},
|
||||
{0x000C, 4},{0x000E, 4},{0x0009, 4},{0x001B, 5},
|
||||
{0x000A, 5},{0x0014, 5},{0x000D, 5},{0x002A, 6},
|
||||
{0x0014, 7},{0x068B,11},{0x1A2A,13},{0x0008, 4},
|
||||
{0x000B, 5},{0x002B, 6},{0x000B, 6},{0x0069, 7},
|
||||
{0x0035, 6},{0x0008, 6},{0x0007, 4},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x003C, 6},{0x0032, 7},{0x0030, 7},
|
||||
{0x00C5, 9},{0x0621,12},{0x0620,12},{0x001F, 5},
|
||||
{0x0033, 7},{0x0001, 3},{0x0000, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x000C, 4},{0x0004, 4},{0x000D, 5},
|
||||
{0x0026, 6},{0x0027, 6},{0x0014, 6},{0x0063, 8},
|
||||
{0x0189,10},{0x0623,12},{0x0622,12},{0x000B, 4},
|
||||
{0x0012, 5},{0x003D, 6},{0x0022, 6},{0x0015, 6},
|
||||
{0x000B, 5},{0x0023, 6},{0x0007, 4},{0x0010, 5}
|
||||
},
|
||||
{
|
||||
{0x000F, 4},{0x000C, 5},{0x0043, 7},{0x0010, 6},
|
||||
{0x0044, 8},{0x0114,10},{0x0455,12},{0x0018, 5},
|
||||
{0x0023, 7},{0x0001, 3},{0x0000, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x0009, 4},{0x0019, 5},{0x0009, 5},
|
||||
{0x0017, 6},{0x0016, 6},{0x0042, 7},{0x008B, 9},
|
||||
{0x0454,12},{0x0457,12},{0x0456,12},{0x000B, 4},
|
||||
{0x0015, 5},{0x000A, 5},{0x0029, 6},{0x0020, 6},
|
||||
{0x000D, 5},{0x0028, 6},{0x0007, 4},{0x0011, 5}
|
||||
},
|
||||
{
|
||||
{0x0001, 3},{0x001A, 5},{0x0029, 6},{0x002A, 6},
|
||||
{0x00A0, 8},{0x0285,10},{0x1425,13},{0x0002, 5},
|
||||
{0x0000, 7},{0x0002, 3},{0x0003, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x0008, 4},{0x0012, 5},{0x0001, 6},
|
||||
{0x0051, 7},{0x0001, 7},{0x0143, 9},{0x0508,11},
|
||||
{0x1424,13},{0x1427,13},{0x1426,13},{0x000F, 4},
|
||||
{0x001C, 5},{0x0003, 5},{0x0037, 6},{0x002B, 6},
|
||||
{0x0013, 5},{0x0036, 6},{0x001D, 5},{0x0001, 5}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x001F, 5},{0x003D, 6},{0x0006, 5},
|
||||
{0x0016, 7},{0x0053, 9},{0x014A,11},{0x0034, 6},
|
||||
{0x002A, 8},{0x0002, 3},{0x0003, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x001C, 5},{0x0037, 6},{0x0017, 7},
|
||||
{0x002B, 8},{0x0028, 8},{0x00A4,10},{0x052D,13},
|
||||
{0x052C,13},{0x052F,13},{0x052E,13},{0x0000, 3},
|
||||
{0x001D, 5},{0x0007, 5},{0x0004, 5},{0x0035, 6},
|
||||
{0x0014, 5},{0x0036, 6},{0x0015, 5},{0x003C, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000A, 4},{0x0007, 5},{0x001D, 5},
|
||||
{0x0009, 6},{0x01F3, 9},{0x07C7,11},{0x0008, 6},
|
||||
{0x01F0, 9},{0x0003, 3},{0x0002, 3},{0x000D, 4},
|
||||
{0x000C, 4},{0x0017, 5},{0x007D, 7},{0x01F2, 9},
|
||||
{0x07C6,11},{0x07C5,11},{0x1F12,13},{0x3E27,14},
|
||||
{0x3E26,14},{0x1F11,13},{0x1F10,13},{0x0000, 3},
|
||||
{0x001E, 5},{0x0006, 5},{0x0039, 6},{0x0038, 6},
|
||||
{0x003F, 6},{0x002C, 6},{0x0005, 5},{0x002D, 6}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0007, 4},{0x0018, 5},{0x0003, 4},
|
||||
{0x0005, 5},{0x0035, 7},{0x004F, 9},{0x0012, 7},
|
||||
{0x04E5,13},{0x0005, 3},{0x0004, 3},{0x000D, 4},
|
||||
{0x000E, 4},{0x0033, 6},{0x0026, 8},{0x009D,10},
|
||||
{0x04E4,13},{0x04E7,13},{0x04E6,13},{0x04E1,13},
|
||||
{0x04E0,13},{0x04E3,13},{0x04E2,13},{0x0000, 3},
|
||||
{0x001F, 5},{0x000C, 5},{0x003D, 6},{0x003C, 6},
|
||||
{0x0032, 6},{0x0034, 7},{0x001B, 6},{0x0008, 6}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x0004, 4},{0x001C, 5},{0x000F, 4},
|
||||
{0x0002, 4},{0x0007, 5},{0x0075, 7},{0x00E8, 8},
|
||||
{0x1D2A,13},{0x0005, 3},{0x0004, 3},{0x000D, 4},
|
||||
{0x000C, 4},{0x0077, 7},{0x0E96,12},{0x3A57,14},
|
||||
{0x3A56,14},{0x3A5D,14},{0x3A5C,14},{0x3A5F,14},
|
||||
{0x3A5E,14},{0x1D29,13},{0x1D28,13},{0x0003, 3},
|
||||
{0x0006, 5},{0x000A, 5},{0x002C, 7},{0x0017, 6},
|
||||
{0x0076, 7},{0x01D3, 9},{0x03A4,10},{0x002D, 7}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x0024, 6},{0x00BF, 8},{0x0085, 8},
|
||||
{0x0211,10},{0x0842,12},{0x1087,13},{0x0018, 5},
|
||||
{0x0020, 6},{0x0001, 3},{0x0002, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x0007, 4},{0x0013, 5},{0x0025, 6},
|
||||
{0x005E, 7},{0x0043, 7},{0x00BE, 8},{0x0109, 9},
|
||||
{0x1086,13},{0x0841,12},{0x0840,12},{0x000F, 4},
|
||||
{0x0001, 4},{0x0011, 5},{0x0000, 5},{0x002E, 6},
|
||||
{0x0019, 5},{0x0001, 5},{0x0006, 4},{0x0016, 5}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x000F, 5},{0x006F, 7},{0x0061, 7},
|
||||
{0x0374,10},{0x1BA8,13},{0x3753,14},{0x0012, 5},
|
||||
{0x0036, 6},{0x0000, 3},{0x0001, 3},{0x000A, 4},
|
||||
{0x000B, 4},{0x001A, 5},{0x0031, 6},{0x0060, 7},
|
||||
{0x00DC, 8},{0x01BB, 9},{0x06EB,11},{0x1BAB,13},
|
||||
{0x3752,14},{0x3755,14},{0x3754,14},{0x000E, 4},
|
||||
{0x0006, 4},{0x0013, 5},{0x000E, 5},{0x003E, 6},
|
||||
{0x0008, 4},{0x001E, 5},{0x0019, 5},{0x003F, 6}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x001C, 5},{0x0025, 6},{0x0024, 6},
|
||||
{0x01DA, 9},{0x1DBD,13},{0x3B7C,14},{0x003C, 6},
|
||||
{0x003D, 6},{0x0000, 3},{0x0001, 3},{0x000B, 4},
|
||||
{0x000A, 4},{0x000B, 5},{0x0077, 7},{0x00EC, 8},
|
||||
{0x03B6,10},{0x076E,11},{0x1DBF,13},{0x76FB,15},
|
||||
{0x76FA,15},{0x3B79,14},{0x3B78,14},{0x000D, 4},
|
||||
{0x001F, 5},{0x0013, 5},{0x000A, 5},{0x0008, 5},
|
||||
{0x000C, 4},{0x0008, 4},{0x0009, 5},{0x003A, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0003, 4},{0x0004, 5},{0x0010, 5},
|
||||
{0x008F, 8},{0x0475,11},{0x11D1,13},{0x0079, 7},
|
||||
{0x0027, 6},{0x0002, 3},{0x0003, 3},{0x0001, 4},
|
||||
{0x0000, 4},{0x0026, 6},{0x0046, 7},{0x011C, 9},
|
||||
{0x0477,11},{0x08ED,12},{0x11D0,13},{0x11D3,13},
|
||||
{0x11D2,13},{0x11D9,13},{0x11D8,13},{0x000D, 4},
|
||||
{0x001F, 5},{0x0012, 5},{0x0005, 5},{0x003D, 6},
|
||||
{0x000C, 4},{0x000E, 4},{0x0022, 6},{0x0078, 7}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x000C, 4},{0x001B, 5},{0x0000, 4},
|
||||
{0x0006, 6},{0x03E2,10},{0x3E3D,14},{0x000F, 7},
|
||||
{0x0034, 6},{0x0003, 3},{0x0002, 3},{0x001E, 5},
|
||||
{0x001D, 5},{0x007D, 7},{0x01F0, 9},{0x07C6,11},
|
||||
{0x3E3C,14},{0x3E3F,14},{0x3E3E,14},{0x3E39,14},
|
||||
{0x3E38,14},{0x3E3B,14},{0x3E3A,14},{0x0008, 4},
|
||||
{0x001C, 5},{0x0002, 5},{0x003F, 6},{0x0035, 6},
|
||||
{0x0009, 4},{0x0001, 3},{0x000E, 7},{0x00F9, 8}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000B, 4},{0x0001, 4},{0x000A, 4},
|
||||
{0x001E, 6},{0x00E0, 9},{0x0E1E,13},{0x0071, 8},
|
||||
{0x0039, 7},{0x0007, 3},{0x0006, 3},{0x000D, 5},
|
||||
{0x000C, 5},{0x0020, 7},{0x01C2,10},{0x1C3F,14},
|
||||
{0x1C3E,14},{0x0E19,13},{0x0E18,13},{0x0E1B,13},
|
||||
{0x0E1A,13},{0x0E1D,13},{0x0E1C,13},{0x0000, 4},
|
||||
{0x0009, 5},{0x001D, 6},{0x001F, 6},{0x0011, 6},
|
||||
{0x0005, 4},{0x0001, 3},{0x0043, 8},{0x0042, 8}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000D, 4},{0x0007, 4},{0x0002, 3},
|
||||
{0x0014, 5},{0x016C, 9},{0x16D1,13},{0x02DF,10},
|
||||
{0x016E, 9},{0x0000, 2},{0x0007, 3},{0x002C, 6},
|
||||
{0x002B, 6},{0x02DE,10},{0x16D0,13},{0x16D3,13},
|
||||
{0x16D2,13},{0x2DB5,14},{0x2DB4,14},{0x2DB7,14},
|
||||
{0x2DB6,14},{0x16D9,13},{0x16D8,13},{0x000C, 5},
|
||||
{0x002A, 6},{0x005A, 7},{0x001B, 6},{0x001A, 6},
|
||||
{0x0017, 5},{0x000C, 4},{0x05B7,11},{0x05B5,11}
|
||||
},
|
||||
{
|
||||
{0x0002, 2},{0x000F, 4},{0x001C, 5},{0x000C, 4},
|
||||
{0x003B, 6},{0x01AC, 9},{0x1AD8,13},{0x35B3,14},
|
||||
{0x35B2,14},{0x0001, 2},{0x0000, 2},{0x0069, 7},
|
||||
{0x0068, 7},{0x35BD,14},{0x35BC,14},{0x35BF,14},
|
||||
{0x35BE,14},{0x35B9,14},{0x35B8,14},{0x35BB,14},
|
||||
{0x35BA,14},{0x35B5,14},{0x35B4,14},{0x01A9, 9},
|
||||
{0x01A8, 9},{0x035A,10},{0x00D7, 8},{0x00D5, 8},
|
||||
{0x003A, 6},{0x001B, 5},{0x35B7,14},{0x35B6,14}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x0010, 5},{0x0072, 7},{0x0071, 7},
|
||||
{0x0154, 9},{0x0AAB,12},{0x0AA8,12},{0x0014, 5},
|
||||
{0x0070, 7},{0x0002, 3},{0x0003, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x0003, 4},{0x0011, 5},{0x0073, 7},
|
||||
{0x0054, 7},{0x00AB, 8},{0x02AB,10},{0x1553,13},
|
||||
{0x1552,13},{0x1555,13},{0x1554,13},{0x000D, 4},
|
||||
{0x001E, 5},{0x0012, 5},{0x003E, 6},{0x002B, 6},
|
||||
{0x0002, 4},{0x003F, 6},{0x001D, 5},{0x0013, 5}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x001F, 5},{0x0029, 6},{0x003D, 6},
|
||||
{0x000C, 7},{0x0069,10},{0x0345,13},{0x0002, 5},
|
||||
{0x0028, 6},{0x0002, 3},{0x0001, 3},{0x000E, 4},
|
||||
{0x000C, 4},{0x0015, 5},{0x0007, 6},{0x001B, 8},
|
||||
{0x006B,10},{0x006A,10},{0x0344,13},{0x0347,13},
|
||||
{0x0346,13},{0x01A1,12},{0x01A0,12},{0x000B, 4},
|
||||
{0x001A, 5},{0x0012, 5},{0x0000, 5},{0x003C, 6},
|
||||
{0x0008, 4},{0x001B, 5},{0x0013, 5},{0x0001, 5}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0004, 4},{0x003F, 6},{0x0014, 5},
|
||||
{0x0056, 7},{0x015C, 9},{0x15D5,13},{0x003C, 6},
|
||||
{0x002A, 6},{0x0000, 3},{0x0001, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x000C, 5},{0x00AF, 8},{0x02BB,10},
|
||||
{0x15D4,13},{0x15D7,13},{0x15D6,13},{0x15D1,13},
|
||||
{0x15D0,13},{0x15D3,13},{0x15D2,13},{0x000B, 4},
|
||||
{0x0019, 5},{0x000D, 5},{0x003E, 6},{0x0031, 6},
|
||||
{0x0007, 4},{0x0005, 4},{0x003D, 6},{0x0030, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0008, 4},{0x001A, 5},{0x0000, 4},
|
||||
{0x0036, 6},{0x0011, 8},{0x0106,12},{0x000A, 7},
|
||||
{0x006E, 7},{0x0002, 3},{0x0003, 3},{0x0003, 4},
|
||||
{0x0002, 4},{0x006F, 7},{0x0021, 9},{0x020F,13},
|
||||
{0x020E,13},{0x0101,12},{0x0100,12},{0x0103,12},
|
||||
{0x0102,12},{0x0105,12},{0x0104,12},{0x000C, 4},
|
||||
{0x001E, 5},{0x0003, 5},{0x003E, 6},{0x003F, 6},
|
||||
{0x0009, 4},{0x000E, 4},{0x000B, 7},{0x0009, 7}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x000E, 4},{0x001E, 5},{0x000C, 4},
|
||||
{0x001F, 5},{0x006E, 7},{0x00AD,10},{0x00AF,10},
|
||||
{0x0014, 7},{0x0004, 3},{0x0003, 3},{0x001A, 5},
|
||||
{0x0017, 5},{0x002A, 8},{0x0576,13},{0x0AEF,14},
|
||||
{0x0AEE,14},{0x0571,13},{0x0570,13},{0x0573,13},
|
||||
{0x0572,13},{0x0575,13},{0x0574,13},{0x0003, 4},
|
||||
{0x0016, 5},{0x0004, 5},{0x0036, 6},{0x000B, 6},
|
||||
{0x000A, 4},{0x0000, 3},{0x006F, 7},{0x00AC,10}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3},
|
||||
{0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13},
|
||||
{0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6},
|
||||
{0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13},
|
||||
{0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13},
|
||||
{0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3},
|
||||
{0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8},
|
||||
{0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3},
|
||||
{0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13},
|
||||
{0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6},
|
||||
{0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13},
|
||||
{0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13},
|
||||
{0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3},
|
||||
{0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8},
|
||||
{0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3},
|
||||
{0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13},
|
||||
{0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6},
|
||||
{0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13},
|
||||
{0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13},
|
||||
{0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3},
|
||||
{0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8},
|
||||
{0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x0011, 5},{0x0020, 6},{0x0074, 7},
|
||||
{0x010D, 9},{0x0863,12},{0x0860,12},{0x000A, 5},
|
||||
{0x0075, 7},{0x0001, 3},{0x0000, 3},{0x000B, 4},
|
||||
{0x000A, 4},{0x0018, 5},{0x0038, 6},{0x0042, 7},
|
||||
{0x010F, 9},{0x010E, 9},{0x0219,10},{0x10C3,13},
|
||||
{0x10C2,13},{0x10C5,13},{0x10C4,13},{0x000F, 4},
|
||||
{0x0004, 4},{0x0019, 5},{0x000B, 5},{0x0039, 6},
|
||||
{0x0009, 4},{0x001B, 5},{0x001A, 5},{0x003B, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0001, 4},{0x003E, 6},{0x0001, 5},
|
||||
{0x00E2, 8},{0x1C6F,13},{0x38D9,14},{0x0039, 6},
|
||||
{0x001F, 6},{0x0002, 3},{0x0001, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0000, 5},{0x0070, 7},{0x01C7, 9},
|
||||
{0x038C,10},{0x071A,11},{0x38D8,14},{0x38DB,14},
|
||||
{0x38DA,14},{0x38DD,14},{0x38DC,14},{0x000D, 4},
|
||||
{0x001D, 5},{0x000E, 5},{0x003F, 6},{0x003C, 6},
|
||||
{0x000C, 4},{0x0006, 4},{0x003D, 6},{0x001E, 6}
|
||||
},
|
||||
{
|
||||
{0x0006, 3},{0x000B, 4},{0x0011, 5},{0x001E, 5},
|
||||
{0x0074, 7},{0x03AA,10},{0x1D5C,13},{0x0001, 6},
|
||||
{0x0021, 6},{0x0001, 3},{0x0002, 3},{0x0007, 4},
|
||||
{0x0006, 4},{0x003E, 6},{0x00EB, 8},{0x01D4, 9},
|
||||
{0x0EAF,12},{0x3ABB,14},{0x3ABA,14},{0x1D59,13},
|
||||
{0x1D58,13},{0x1D5B,13},{0x1D5A,13},{0x000A, 4},
|
||||
{0x001C, 5},{0x0001, 5},{0x003F, 6},{0x003B, 6},
|
||||
{0x0001, 4},{0x0009, 4},{0x0020, 6},{0x0000, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000A, 4},{0x0017, 5},{0x0004, 4},
|
||||
{0x0016, 6},{0x016A, 9},{0x16B1,13},{0x0017, 7},
|
||||
{0x005B, 7},{0x0006, 3},{0x0007, 3},{0x0001, 4},
|
||||
{0x0000, 4},{0x000A, 6},{0x02D7,10},{0x0B5A,12},
|
||||
{0x16B0,13},{0x16B3,13},{0x16B2,13},{0x2D6D,14},
|
||||
{0x2D6C,14},{0x2D6F,14},{0x2D6E,14},{0x0006, 4},
|
||||
{0x000A, 5},{0x0004, 5},{0x002C, 6},{0x0017, 6},
|
||||
{0x0003, 4},{0x0007, 4},{0x0016, 7},{0x00B4, 8}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x000D, 4},{0x0005, 4},{0x0009, 4},
|
||||
{0x0033, 6},{0x0193, 9},{0x192C,13},{0x0061, 8},
|
||||
{0x0031, 7},{0x0000, 2},{0x0007, 3},{0x0010, 5},
|
||||
{0x0011, 5},{0x00C8, 8},{0x192F,13},{0x325B,14},
|
||||
{0x325A,14},{0x1929,13},{0x1928,13},{0x192B,13},
|
||||
{0x192A,13},{0x325D,14},{0x325C,14},{0x0018, 5},
|
||||
{0x001A, 6},{0x001B, 6},{0x0065, 7},{0x0019, 6},
|
||||
{0x0004, 4},{0x0007, 4},{0x0060, 8},{0x0324,10}
|
||||
},
|
||||
{
|
||||
{0x0006, 3},{0x0000, 3},{0x0002, 4},{0x000F, 4},
|
||||
{0x0039, 6},{0x01D9, 9},{0x1D82,13},{0x0761,11},
|
||||
{0x03BE,10},{0x0001, 2},{0x0002, 2},{0x000F, 6},
|
||||
{0x000E, 6},{0x0762,11},{0x3B07,14},{0x3B06,14},
|
||||
{0x3B1D,14},{0x3B1C,14},{0x3B1F,14},{0x3B1E,14},
|
||||
{0x3B19,14},{0x3B18,14},{0x3B1B,14},{0x0038, 6},
|
||||
{0x01DE, 9},{0x00ED, 8},{0x03BF,10},{0x00EE, 8},
|
||||
{0x003A, 6},{0x0006, 5},{0x0EC0,12},{0x3B1A,14}
|
||||
},
|
||||
{
|
||||
{0x0000, 2},{0x0002, 3},{0x000F, 5},{0x0006, 4},
|
||||
{0x001C, 6},{0x01D0,10},{0x0E8C,13},{0x1D1B,14},
|
||||
{0x1D1A,14},{0x0003, 2},{0x0002, 2},{0x00EA, 9},
|
||||
{0x00E9, 9},{0x0E89,13},{0x0E88,13},{0x0E8B,13},
|
||||
{0x0E8A,13},{0x1D65,14},{0x1D64,14},{0x1D67,14},
|
||||
{0x1D66,14},{0x1D61,14},{0x1D60,14},{0x03AD,11},
|
||||
{0x1D63,14},{0x1D62,14},{0x1D1D,14},{0x1D1C,14},
|
||||
{0x003B, 7},{0x01D7,10},{0x1D1F,14},{0x1D1E,14}
|
||||
},
|
||||
{
|
||||
{0x0002, 2},{0x000F, 4},{0x001C, 5},{0x000C, 4},
|
||||
{0x003B, 6},{0x01AC, 9},{0x1AD8,13},{0x35B3,14},
|
||||
{0x35B2,14},{0x0001, 2},{0x0000, 2},{0x0069, 7},
|
||||
{0x0068, 7},{0x35BD,14},{0x35BC,14},{0x35BF,14},
|
||||
{0x35BE,14},{0x35B9,14},{0x35B8,14},{0x35BB,14},
|
||||
{0x35BA,14},{0x35B5,14},{0x35B4,14},{0x01A9, 9},
|
||||
{0x01A8, 9},{0x035A,10},{0x00D7, 8},{0x00D5, 8},
|
||||
{0x003A, 6},{0x001B, 5},{0x35B7,14},{0x35B6,14}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*A description of a Huffman code value used when encoding the tree.*/
|
||||
typedef struct{
|
||||
/*The bit pattern, left-shifted so that the MSB of all patterns is
|
||||
aligned.*/
|
||||
unsigned long pattern;
|
||||
/*The amount the bit pattern was shifted.*/
|
||||
int shift;
|
||||
/*The token this bit pattern represents.*/
|
||||
int token;
|
||||
}th_huff_entry;
|
||||
|
||||
|
||||
|
||||
/*Compares two th_huff_entry structures by their bit patterns.
|
||||
_c1: The first entry to compare.
|
||||
_c2: The second entry to compare.
|
||||
Return: <0 if _c1<_c2, >0 if _c1>_c2.*/
|
||||
static int huff_entry_cmp(const void *_c1,const void *_c2){
|
||||
unsigned long b1;
|
||||
unsigned long b2;
|
||||
b1=((const th_huff_entry *)_c1)->pattern;
|
||||
b2=((const th_huff_entry *)_c2)->pattern;
|
||||
return b1<b2?-1:b1>b2?1:0;
|
||||
}
|
||||
|
||||
int th_huff_codes2latex(const theora_huff_code _codes[80][32]){
|
||||
int i;
|
||||
printf("\\twocolumn\n");
|
||||
for(i=0;i<80;i++){
|
||||
th_huff_entry entries[32];
|
||||
int maxlen;
|
||||
int mask;
|
||||
int j;
|
||||
/*First, find the maximum code length so we can align all the bit
|
||||
patterns.*/
|
||||
maxlen=_codes[i][0].nbits;
|
||||
for(j=1;j<32;j++)if(maxlen<_codes[i][j].nbits)maxlen=_codes[i][j].nbits;
|
||||
mask=(1<<maxlen)-1;
|
||||
/*Copy over the codes into our temporary workspace.
|
||||
The bit patterns are aligned, and the original entry each code is from
|
||||
is stored as well.*/
|
||||
for(j=0;j<32;j++){
|
||||
entries[j].shift=maxlen-_codes[i][j].nbits;
|
||||
entries[j].pattern=_codes[i][j].pattern<<entries[j].shift&mask;
|
||||
entries[j].token=j;
|
||||
}
|
||||
/*Sort the codes into ascending order.
|
||||
This is the order they will be presented in.*/
|
||||
qsort(entries,32,sizeof(entries[0]),huff_entry_cmp);
|
||||
printf("\\begin{center}\n");
|
||||
printf("\\begin{tabular}{lr}\\toprule\n");
|
||||
printf("\\multicolumn{1}{c}{Huffman Code} & Token Value \\\\\\midrule\n");
|
||||
for(j=0;j<32;j++){
|
||||
int k;
|
||||
printf("\\bin{");
|
||||
for(k=maxlen;k-->entries[j].shift;){
|
||||
printf("%c",(int)(entries[j].pattern>>k&1)+'0');
|
||||
}
|
||||
printf("}");
|
||||
for(;k>=0;k--)printf(" ");
|
||||
printf(" & ");
|
||||
if(entries[j].token<10)printf(" ");
|
||||
printf("$%i$ \\\\\n",entries[j].token);
|
||||
}
|
||||
printf("\\bottomrule\n");
|
||||
printf("\\\\\n");
|
||||
printf("\\multicolumn{2}{c}{VP3.1 Huffman Table Number $%i$}\n",i);
|
||||
printf("\\end{tabular}\n");
|
||||
printf("\\end{center}\n");
|
||||
printf("\\vfill\n");
|
||||
printf("\n");
|
||||
}
|
||||
printf("\\onecolumn\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int _argc,char **_argv){
|
||||
th_huff_codes2latex(TH_VP31_HUFF_CODES);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
0 32 #496d9e
|
||||
0 33 #304d71
|
||||
0 34 #8eb2cf
|
||||
1 4 0 6 0 7 1 0 20 0.000 1 0.0000 1470 3255 270 270 1200 3255 1740 3255
|
||||
1 3 0 0 0 0 0 0 20 0.000 1 0.0000 1485 3255 75 75 1485 3255 1560 3255
|
||||
2 1 0 7 0 3 8 0 20 0.000 0 0 -1 0 0 6
|
||||
2445 4140 2505 4350 2385 4425 2145 4425 2025 4380 1890 4320
|
||||
2 1 0 7 0 3 8 0 20 0.000 0 0 -1 0 0 20
|
||||
2445 3480 2775 3450 2955 3390 3090 3315 3285 3285 3555 3285
|
||||
3615 3390 3540 3675 3465 3720 3315 3765 3105 3810 3330 3765
|
||||
3420 3825 3540 3900 3480 4260 3330 4320 3165 4305 2910 4260
|
||||
2715 4185 2520 4185
|
||||
2 1 0 7 0 3 11 0 20 0.000 0 0 -1 0 0 9
|
||||
1575 3150 1755 2985 2040 2820 2355 2760 2670 2850 2850 2985
|
||||
3165 3270 3435 3420 2835 3780
|
||||
2 1 0 7 0 6 6 0 20 0.000 0 0 -1 0 0 15
|
||||
900 3570 1020 3450 1095 3360 1395 3150 1545 3090 1725 3075
|
||||
2025 3090 2205 3150 2295 3225 2385 3300 2445 3375 2550 3465
|
||||
2655 3540 2775 3600 2865 3600
|
||||
2 1 0 7 0 3 4 0 20 0.000 0 0 -1 0 0 7
|
||||
1515 4080 1770 4080 1875 3945 1965 3870 2025 3780 1995 3780
|
||||
1665 3780
|
||||
2 1 0 0 -1 6 7 0 20 0.000 0 0 -1 0 0 11
|
||||
2865 3615 2850 3735 2775 3945 2685 4080 2595 4155 2010 4185
|
||||
1185 4170 1035 3990 1035 3870 975 3540 1155 3435
|
||||
2 1 0 0 0 3 5 0 20 0.000 0 0 -1 0 0 7
|
||||
1035 3885 1005 4020 1095 4065 1245 4065 1245 3870 1050 3870
|
||||
1065 3870
|
||||
2 1 0 7 0 3 0 0 20 0.000 0 0 -1 0 0 11
|
||||
1245 3915 1245 3840 1170 3750 1005 3585 930 3510 750 3510
|
||||
630 3600 645 3690 765 3780 885 3825 1035 3975
|
||||
2 1 0 7 0 3 0 0 20 0.000 0 0 -1 0 0 8
|
||||
1095 3990 945 3990 855 4050 795 4140 885 4200 1095 4200
|
||||
1155 4140 1245 4050
|
||||
2 1 0 7 0 6 6 0 20 0.000 0 0 -1 0 0 8
|
||||
2685 4185 2400 4185 2220 4215 1920 4305 1695 4335 1485 4320
|
||||
1245 4215 1155 4125
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2250 3900 2250 3825 2175 3825 2175 3900 2250 3900
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2250 3750 2250 3675 2175 3675 2175 3750 2250 3750
|
||||
2 1 0 0 -1 3 5 0 20 0.000 0 0 -1 0 0 9
|
||||
1650 3780 1590 3975 1485 4035 1530 4080 1770 4065 1845 3960
|
||||
1920 3900 1965 3795 1695 3780
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
1950 3450 1950 3375 1875 3375 1875 3450 1950 3450
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2400 3900 2400 3825 2325 3825 2325 3900 2400 3900
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2550 3975 2550 3900 2475 3900 2475 3975 2550 3975
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2700 3900 2700 3825 2625 3825 2625 3900 2700 3900
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2700 3750 2700 3675 2625 3675 2625 3750 2700 3750
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2550 3675 2550 3600 2475 3600 2475 3675 2550 3675
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2400 3750 2400 3675 2325 3675 2325 3750 2400 3750
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2400 3600 2400 3525 2325 3525 2325 3600 2400 3600
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2250 3600 2250 3525 2175 3525 2175 3600 2250 3600
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2250 3450 2250 3375 2175 3375 2175 3450 2250 3450
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2100 3525 2100 3450 2025 3450 2025 3525 2100 3525
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2100 3375 2100 3300 2025 3300 2025 3375 2100 3375
|
||||
2 2 0 0 0 0 3 0 20 0.000 0 0 0 0 0 5
|
||||
2550 3825 2550 3750 2475 3750 2475 3825 2550 3825
|
||||
2 3 0 0 -1 32 13 0 20 0.000 0 0 7 0 0 5
|
||||
2160 2055 3810 3705 2160 5355 510 3705 2160 2055
|
||||
2 1 0 0 32 34 12 0 20 0.000 0 0 -1 0 0 3
|
||||
2160 2055 2160 3705 510 3705
|
||||
2 1 0 0 32 33 12 0 20 0.000 0 0 -1 0 0 3
|
||||
3810 3705 2160 3705 2160 5355
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
noinst_PROGRAMS = dump_video dump_psnr $(BUILDABLE_EXAMPLES)
|
||||
|
||||
# possible contents of BUILDABLE_EXAMPLES:
|
||||
EXTRA_PROGRAMS = player_example encoder_example png2theora
|
||||
|
||||
AM_CFLAGS = $(OGG_CFLAGS)
|
||||
LDADD = ../lib/libtheora.la $(OGG_LIBS)
|
||||
LDADDDEC = ../lib/libtheoradec.la $(OGG_LIBS)
|
||||
LDADDENC = ../lib/libtheoraenc.la ../lib/libtheoradec.la $(OGG_LIBS)
|
||||
|
||||
dump_video_SOURCES = dump_video.c
|
||||
EXTRA_dump_video_SOURCES = getopt.c getopt1.c getopt.h
|
||||
dump_video_LDADD = $(GETOPT_OBJS) $(LDADDDEC)
|
||||
|
||||
dump_psnr_SOURCES = dump_psnr.c
|
||||
EXTRA_dump_psnr_SOURCES = getopt.c getopt1.c getopt.h
|
||||
dump_psnr_LDADD = $(GETOPT_OBJS) $(LDADDDEC) -lm
|
||||
|
||||
player_example_SOURCES = player_example.c
|
||||
player_example_CFLAGS = $(SDL_CFLAGS) $(OGG_CFLAGS) $(VORBIS_CFLAGS)
|
||||
player_example_LDADD = $(LDADDDEC) $(SDL_LIBS) $(VORBIS_LIBS) $(OSS_LIBS)
|
||||
|
||||
encoder_example_SOURCES = encoder_example.c
|
||||
EXTRA_encoder_example_SOURCES = getopt.c getopt1.c getopt.h
|
||||
encoder_example_CFLAGS = $(OGG_CFLAGS) $(VORBIS_CFLAGS)
|
||||
encoder_example_LDADD = $(GETOPT_OBJS) $(LDADDENC) $(VORBIS_LIBS) $(VORBISENC_LIBS) -lm
|
||||
|
||||
png2theora_SOURCES = png2theora.c
|
||||
png2theora_CFLAGS = $(OGG_CFLAGS) $(PNG_CFLAGS)
|
||||
png2theora_LDADD = $(GETOPT_OBJS) $(LDADDENC) $(PNG_LIBS) -lm
|
||||
|
||||
debug:
|
||||
$(MAKE) all CFLAGS="@DEBUG@"
|
||||
|
||||
profile:
|
||||
$(MAKE) all CFLAGS="@PROFILE@"
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
06/09/03 - by mau (mauricio at xiph.org)
|
||||
|
||||
The splayer example is a experimental simple Theora player using SDL and
|
||||
Portaudio for cross platform compatibility. To build the windows version
|
||||
please use the Visual C++ project available at the
|
||||
win32/experimental/splayer directory.
|
||||
|
||||
By default this sample will not be built on Linux, unless Portaudio is
|
||||
properly installed. Follow these steps to install Portaudio:
|
||||
|
||||
1) Get portaudio tar package from www.portaudio.com
|
||||
2) Uncompress it to a local directory
|
||||
3) Run './configure' in the portaudio directory
|
||||
4) Run 'make install'
|
||||
|
||||
This will install Portaudio libraries in /usr/local/lib, and the Portaudio
|
||||
include file at /usr/local/include. On linux you may need to manually
|
||||
execute 'ldconfig' to rebuild the library cache.
|
||||
|
||||
Switch to theora's directory, re-run theora's autogen.sh script to
|
||||
re-generate the appropriate makefiles, and 'make install' to build.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,496 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: example dumpvid application; dumps Theora streams
|
||||
last mod: $Id: dump_video.c,v 1.2 2004/03/24 19:12:42 derf Exp $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
/* By Mauricio Piacentini (mauricio at xiph.org) */
|
||||
/* simply dump decoded YUV data, for verification of theora bitstream */
|
||||
|
||||
#if !defined(_REENTRANT)
|
||||
#define _REENTRANT
|
||||
#endif
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#if !defined(_LARGEFILE_SOURCE)
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#if !defined(_LARGEFILE64_SOURCE)
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#if !defined(_FILE_OFFSET_BITS)
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
/*Yes, yes, we're going to hell.*/
|
||||
#if defined(_WIN32)
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include "getopt.h"
|
||||
#include "theora/theoradec.h"
|
||||
|
||||
const char *optstring = "o:rf";
|
||||
struct option options [] = {
|
||||
{"output",required_argument,NULL,'o'},
|
||||
{"raw",no_argument, NULL,'r'}, /*Disable YUV4MPEG2 headers:*/
|
||||
{"fps-only",no_argument, NULL, 'f'}, /* Only interested in fps of decode loop */
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
|
||||
/* Helper; just grab some more compressed bitstream and sync it for
|
||||
page extraction */
|
||||
int buffer_data(FILE *in,ogg_sync_state *oy){
|
||||
char *buffer=ogg_sync_buffer(oy,4096);
|
||||
int bytes=fread(buffer,1,4096,in);
|
||||
ogg_sync_wrote(oy,bytes);
|
||||
return(bytes);
|
||||
}
|
||||
|
||||
/* never forget that globals are a one-way ticket to Hell */
|
||||
/* Ogg and codec state for demux/decode */
|
||||
ogg_sync_state oy;
|
||||
ogg_page og;
|
||||
ogg_stream_state vo;
|
||||
ogg_stream_state to;
|
||||
th_info ti;
|
||||
th_comment tc;
|
||||
th_setup_info *ts;
|
||||
th_dec_ctx *td;
|
||||
|
||||
int theora_p=0;
|
||||
int theora_processing_headers;
|
||||
int stateflag=0;
|
||||
|
||||
/* single frame video buffering */
|
||||
int videobuf_ready=0;
|
||||
ogg_int64_t videobuf_granulepos=-1;
|
||||
double videobuf_time=0;
|
||||
int raw=0;
|
||||
|
||||
FILE* outfile = NULL;
|
||||
|
||||
int got_sigint=0;
|
||||
static void sigint_handler (int signal) {
|
||||
got_sigint = 1;
|
||||
}
|
||||
|
||||
static th_ycbcr_buffer ycbcr;
|
||||
|
||||
static void stripe_decoded(th_ycbcr_buffer _dst,th_ycbcr_buffer _src,
|
||||
int _fragy0,int _fragy_end){
|
||||
int pli;
|
||||
for(pli=0;pli<3;pli++){
|
||||
int yshift;
|
||||
int y_end;
|
||||
int y;
|
||||
yshift=pli!=0&&!(ti.pixel_fmt&2);
|
||||
y_end=_fragy_end<<3-yshift;
|
||||
/*An implemention intending to display this data would need to check the
|
||||
crop rectangle before proceeding.*/
|
||||
for(y=_fragy0<<3-yshift;y<y_end;y++){
|
||||
memcpy(_dst[pli].data+y*_dst[pli].stride,
|
||||
_src[pli].data+y*_src[pli].stride,_src[pli].width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void open_video(void){
|
||||
th_stripe_callback cb;
|
||||
int pli;
|
||||
/*Here we allocate a buffer so we can use the striped decode feature.
|
||||
There's no real reason to do this in this application, because we want to
|
||||
write to the file top-down, but the frame gets decoded bottom up, so we
|
||||
have to buffer it all anyway.
|
||||
But this illustrates how the API works.*/
|
||||
for(pli=0;pli<3;pli++){
|
||||
int xshift;
|
||||
int yshift;
|
||||
xshift=pli!=0&&!(ti.pixel_fmt&1);
|
||||
yshift=pli!=0&&!(ti.pixel_fmt&2);
|
||||
ycbcr[pli].data=(unsigned char *)malloc(
|
||||
(ti.frame_width>>xshift)*(ti.frame_height>>yshift)*sizeof(char));
|
||||
ycbcr[pli].stride=ti.frame_width>>xshift;
|
||||
ycbcr[pli].width=ti.frame_width>>xshift;
|
||||
ycbcr[pli].height=ti.frame_height>>yshift;
|
||||
}
|
||||
/*Similarly, since ycbcr is a global, there's no real reason to pass it as
|
||||
the context.
|
||||
In a more object-oriented decoder, we could pass the "this" pointer
|
||||
instead (though in C++, platform-dependent calling convention differences
|
||||
prevent us from using a real member function pointer).*/
|
||||
cb.ctx=ycbcr;
|
||||
cb.stripe_decoded=(th_stripe_decoded_func)stripe_decoded;
|
||||
th_decode_ctl(td,TH_DECCTL_SET_STRIPE_CB,&cb,sizeof(cb));
|
||||
}
|
||||
|
||||
/*Write out the planar YUV frame, uncropped.*/
|
||||
static void video_write(void){
|
||||
int pli;
|
||||
int i;
|
||||
/*Uncomment the following to do normal, non-striped decoding.
|
||||
th_ycbcr_buffer ycbcr;
|
||||
th_decode_ycbcr_out(td,ycbcr);*/
|
||||
if(outfile){
|
||||
if(!raw)fprintf(outfile, "FRAME\n");
|
||||
for(pli=0;pli<3;pli++){
|
||||
for(i=0;i<ycbcr[pli].height;i++){
|
||||
fwrite(ycbcr[pli].data+ycbcr[pli].stride*i, 1,
|
||||
ycbcr[pli].width, outfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* dump the theora comment header */
|
||||
static int dump_comments(th_comment *_tc){
|
||||
int i;
|
||||
int len;
|
||||
FILE *out;
|
||||
out=stderr;
|
||||
fprintf(out,"Encoded by %s\n",_tc->vendor);
|
||||
if(_tc->comments){
|
||||
fprintf(out,"theora comment header:\n");
|
||||
for(i=0;i<_tc->comments;i++){
|
||||
if(_tc->user_comments[i]){
|
||||
len=_tc->comment_lengths[i]<INT_MAX?_tc->comment_lengths[i]:INT_MAX;
|
||||
fprintf(out,"\t%.*s\n",len,_tc->user_comments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* helper: push a page into the appropriate steam */
|
||||
/* this can be done blindly; a stream won't accept a page
|
||||
that doesn't belong to it */
|
||||
static int queue_page(ogg_page *page){
|
||||
if(theora_p)ogg_stream_pagein(&to,page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage(void){
|
||||
fprintf(stderr,
|
||||
"Usage: dumpvid <file.ogv> > outfile\n"
|
||||
"input is read from stdin if no file is passed on the command line\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[]){
|
||||
|
||||
ogg_packet op;
|
||||
|
||||
int long_option_index;
|
||||
int c;
|
||||
|
||||
struct timeb start;
|
||||
struct timeb after;
|
||||
struct timeb last;
|
||||
int fps_only=0;
|
||||
int frames = 0;
|
||||
|
||||
FILE *infile = stdin;
|
||||
outfile = stdout;
|
||||
|
||||
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode on windows. */
|
||||
/* Beware the evil ifdef. We avoid these where we can, but this one we
|
||||
cannot. Don't add any more, you'll probably go to hell if you do. */
|
||||
_setmode( _fileno( stdin ), _O_BINARY );
|
||||
_setmode( _fileno( stdout ), _O_BINARY );
|
||||
#endif
|
||||
|
||||
/* Process option arguments. */
|
||||
while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){
|
||||
switch(c){
|
||||
case 'o':
|
||||
if(strcmp(optarg,"-")!=0){
|
||||
outfile=fopen(optarg,"wb");
|
||||
if(outfile==NULL){
|
||||
fprintf(stderr,"Unable to open output file '%s'\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
outfile=stdout;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
raw=1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
fps_only = 1;
|
||||
outfile = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(optind<argc){
|
||||
infile=fopen(argv[optind],"rb");
|
||||
if(infile==NULL){
|
||||
fprintf(stderr,"Unable to open '%s' for extraction.\n", argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
if(++optind<argc){
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/*Ok, Ogg parsing.
|
||||
The idea here is we have a bitstream that is made up of Ogg pages.
|
||||
The libogg sync layer will find them for us.
|
||||
There may be pages from several logical streams interleaved; we find the
|
||||
first theora stream and ignore any others.
|
||||
Then we pass the pages for our stream to the libogg stream layer which
|
||||
assembles our original set of packets out of them.
|
||||
It's the packets that libtheora actually knows how to handle.*/
|
||||
|
||||
/* start up Ogg stream synchronization layer */
|
||||
ogg_sync_init(&oy);
|
||||
|
||||
/* init supporting Theora structures needed in header parsing */
|
||||
th_comment_init(&tc);
|
||||
th_info_init(&ti);
|
||||
|
||||
/*Ogg file open; parse the headers.
|
||||
Theora (like Vorbis) depends on some initial header packets for decoder
|
||||
setup and initialization.
|
||||
We retrieve these first before entering the main decode loop.*/
|
||||
|
||||
/* Only interested in Theora streams */
|
||||
while(!stateflag){
|
||||
int ret=buffer_data(infile,&oy);
|
||||
if(ret==0)break;
|
||||
while(ogg_sync_pageout(&oy,&og)>0){
|
||||
int got_packet;
|
||||
ogg_stream_state test;
|
||||
|
||||
/* is this a mandated initial header? If not, stop parsing */
|
||||
if(!ogg_page_bos(&og)){
|
||||
/* don't leak the page; get it into the appropriate stream */
|
||||
queue_page(&og);
|
||||
stateflag=1;
|
||||
break;
|
||||
}
|
||||
|
||||
ogg_stream_init(&test,ogg_page_serialno(&og));
|
||||
ogg_stream_pagein(&test,&og);
|
||||
got_packet = ogg_stream_packetpeek(&test,&op);
|
||||
|
||||
/* identify the codec: try theora */
|
||||
if((got_packet==1) && !theora_p && (theora_processing_headers=
|
||||
th_decode_headerin(&ti,&tc,&ts,&op))>=0){
|
||||
/* it is theora -- save this stream state */
|
||||
memcpy(&to,&test,sizeof(test));
|
||||
theora_p=1;
|
||||
/*Advance past the successfully processed header.*/
|
||||
if(theora_processing_headers)ogg_stream_packetout(&to,NULL);
|
||||
}else{
|
||||
/* whatever it is, we don't care about it */
|
||||
ogg_stream_clear(&test);
|
||||
}
|
||||
}
|
||||
/* fall through to non-bos page parsing */
|
||||
}
|
||||
|
||||
/* we're expecting more header packets. */
|
||||
while(theora_p && theora_processing_headers){
|
||||
int ret;
|
||||
|
||||
/* look for further theora headers */
|
||||
while(theora_processing_headers&&(ret=ogg_stream_packetpeek(&to,&op))){
|
||||
if(ret<0)continue;
|
||||
theora_processing_headers=th_decode_headerin(&ti,&tc,&ts,&op);
|
||||
if(theora_processing_headers<0){
|
||||
fprintf(stderr,"Error parsing Theora stream headers; "
|
||||
"corrupt stream?\n");
|
||||
exit(1);
|
||||
}
|
||||
else if(theora_processing_headers>0){
|
||||
/*Advance past the successfully processed header.*/
|
||||
ogg_stream_packetout(&to,NULL);
|
||||
}
|
||||
theora_p++;
|
||||
}
|
||||
|
||||
/*Stop now so we don't fail if there aren't enough pages in a short
|
||||
stream.*/
|
||||
if(!(theora_p && theora_processing_headers))break;
|
||||
|
||||
/* The header pages/packets will arrive before anything else we
|
||||
care about, or the stream is not obeying spec */
|
||||
|
||||
if(ogg_sync_pageout(&oy,&og)>0){
|
||||
queue_page(&og); /* demux into the appropriate stream */
|
||||
}else{
|
||||
int ret=buffer_data(infile,&oy); /* someone needs more data */
|
||||
if(ret==0){
|
||||
fprintf(stderr,"End of file while searching for codec headers.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* and now we have it all. initialize decoders */
|
||||
if(theora_p){
|
||||
dump_comments(&tc);
|
||||
td=th_decode_alloc(&ti,ts);
|
||||
fprintf(stderr,"Ogg logical stream %lx is Theora %dx%d %.02f fps video\n"
|
||||
"Encoded frame content is %dx%d with %dx%d offset\n",
|
||||
to.serialno,ti.frame_width,ti.frame_height,
|
||||
(double)ti.fps_numerator/ti.fps_denominator,
|
||||
ti.pic_width,ti.pic_height,ti.pic_x,ti.pic_y);
|
||||
}else{
|
||||
/* tear down the partial theora setup */
|
||||
th_info_clear(&ti);
|
||||
th_comment_clear(&tc);
|
||||
}
|
||||
/*Either way, we're done with the codec setup data.*/
|
||||
th_setup_free(ts);
|
||||
|
||||
/* open video */
|
||||
if(theora_p)open_video();
|
||||
|
||||
if(!raw && outfile){
|
||||
static const char *CHROMA_TYPES[4]={"420jpeg",NULL,"422jpeg","444"};
|
||||
if(ti.pixel_fmt>=4||ti.pixel_fmt==TH_PF_RSVD){
|
||||
fprintf(stderr,"Unknown pixel format: %i\n",ti.pixel_fmt);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(outfile,"YUV4MPEG2 C%s W%d H%d F%d:%d I%c A%d:%d\n",
|
||||
CHROMA_TYPES[ti.pixel_fmt],ti.frame_width,ti.frame_height,
|
||||
ti.fps_numerator,ti.fps_denominator,'p',
|
||||
ti.aspect_numerator,ti.aspect_denominator);
|
||||
}
|
||||
|
||||
/* install signal handler */
|
||||
signal (SIGINT, sigint_handler);
|
||||
|
||||
/*Finally the main decode loop.
|
||||
|
||||
It's one Theora packet per frame, so this is pretty straightforward if
|
||||
we're not trying to maintain sync with other multiplexed streams.
|
||||
|
||||
The videobuf_ready flag is used to maintain the input buffer in the libogg
|
||||
stream state.
|
||||
If there's no output frame available at the end of the decode step, we must
|
||||
need more input data.
|
||||
We could simplify this by just using the return code on
|
||||
ogg_page_packetout(), but the flag system extends easily to the case where
|
||||
you care about more than one multiplexed stream (like with audio
|
||||
playback).
|
||||
In that case, just maintain a flag for each decoder you care about, and
|
||||
pull data when any one of them stalls.
|
||||
|
||||
videobuf_time holds the presentation time of the currently buffered video
|
||||
frame.
|
||||
We ignore this value.*/
|
||||
|
||||
stateflag=0; /* playback has not begun */
|
||||
/* queue any remaining pages from data we buffered but that did not
|
||||
contain headers */
|
||||
while(ogg_sync_pageout(&oy,&og)>0){
|
||||
queue_page(&og);
|
||||
}
|
||||
|
||||
if(fps_only){
|
||||
ftime(&start);
|
||||
ftime(&last);
|
||||
}
|
||||
|
||||
while(!got_sigint){
|
||||
|
||||
while(theora_p && !videobuf_ready){
|
||||
/* theora is one in, one out... */
|
||||
if(ogg_stream_packetout(&to,&op)>0){
|
||||
|
||||
if(th_decode_packetin(td,&op,&videobuf_granulepos)>=0){
|
||||
videobuf_time=th_granule_time(td,videobuf_granulepos);
|
||||
videobuf_ready=1;
|
||||
frames++;
|
||||
if(fps_only)
|
||||
ftime(&after);
|
||||
}
|
||||
|
||||
}else
|
||||
break;
|
||||
}
|
||||
|
||||
if(fps_only && (videobuf_ready || fps_only==2)){
|
||||
long ms =
|
||||
after.time*1000.+after.millitm-
|
||||
(last.time*1000.+last.millitm);
|
||||
|
||||
if(ms>500 || fps_only==1 ||
|
||||
(feof(infile) && !videobuf_ready)){
|
||||
float file_fps = (float)ti.fps_numerator/ti.fps_denominator;
|
||||
fps_only=2;
|
||||
|
||||
ms = after.time*1000.+after.millitm-
|
||||
(start.time*1000.+start.millitm);
|
||||
|
||||
fprintf(stderr,"\rframe:%d rate:%.2fx ",
|
||||
frames,
|
||||
frames*1000./(ms*file_fps));
|
||||
memcpy(&last,&after,sizeof(last));
|
||||
}
|
||||
}
|
||||
|
||||
if(!videobuf_ready && feof(infile))break;
|
||||
|
||||
if(!videobuf_ready){
|
||||
/* no data yet for somebody. Grab another page */
|
||||
buffer_data(infile,&oy);
|
||||
while(ogg_sync_pageout(&oy,&og)>0){
|
||||
queue_page(&og);
|
||||
}
|
||||
}
|
||||
/* dumpvideo frame, and get new one */
|
||||
else if(outfile)video_write();
|
||||
|
||||
videobuf_ready=0;
|
||||
}
|
||||
|
||||
/* end of decoder loop -- close everything */
|
||||
|
||||
if(theora_p){
|
||||
ogg_stream_clear(&to);
|
||||
th_decode_free(td);
|
||||
th_comment_clear(&tc);
|
||||
th_info_clear(&ti);
|
||||
}
|
||||
ogg_sync_clear(&oy);
|
||||
|
||||
if(infile && infile!=stdin)fclose(infile);
|
||||
if(outfile && outfile!=stdout)fclose(outfile);
|
||||
|
||||
fprintf(stderr, "\n\n%d frames\n", frames);
|
||||
fprintf(stderr, "\nDone.\n");
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,180 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
|
||||
#ifndef __need_getopt
|
||||
# define _GETOPT_H 1
|
||||
#endif
|
||||
|
||||
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
||||
standalone, or this is the first header included in the source file.
|
||||
If we are being used with glibc, we need to include <features.h>, but
|
||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
||||
not defined, include <ctype.h>, which will pull in <features.h> for us
|
||||
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
||||
doesn't flood the namespace with stuff the way some other headers do.) */
|
||||
#if !defined __GNU_LIBRARY__
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns -1, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
#ifndef __need_getopt
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
const char *name;
|
||||
# else
|
||||
char *name;
|
||||
# endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
# define no_argument 0
|
||||
# define required_argument 1
|
||||
# define optional_argument 2
|
||||
#endif /* need getopt */
|
||||
|
||||
|
||||
/* Get definitions and prototypes for functions to process the
|
||||
arguments in ARGV (ARGC of them, minus the program name) for
|
||||
options given in OPTS.
|
||||
|
||||
Return the option character from OPTS just read. Return -1 when
|
||||
there are no more options. For unrecognized options, or options
|
||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
||||
returned.
|
||||
|
||||
The OPTS string is a list of characters which are recognized option
|
||||
letters, optionally followed by colons, specifying that that letter
|
||||
takes an argument, to be placed in `optarg'.
|
||||
|
||||
If a letter in OPTS is followed by two colons, its argument is
|
||||
optional. This behavior is specific to the GNU `getopt'.
|
||||
|
||||
The argument `--' causes premature termination of argument
|
||||
scanning, explicitly telling `getopt' that there are no more
|
||||
options.
|
||||
|
||||
If OPTS begins with `--', then non-option arguments are treated as
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`getopt'. */
|
||||
|
||||
#if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# ifdef __GNU_LIBRARY__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
|
||||
# else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
# endif /* __GNU_LIBRARY__ */
|
||||
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
extern int getopt_long_only (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int __argc, char *const *__argv,
|
||||
const char *__shortopts,
|
||||
const struct option *__longopts, int *__longind,
|
||||
int __long_only);
|
||||
# endif
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
# ifndef __need_getopt
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
# endif
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure we later can get all the definitions and declarations. */
|
||||
#undef __need_getopt
|
||||
|
||||
#endif /* getopt.h */
|
||||
@@ -0,0 +1,188 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@@ -0,0 +1,887 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: example SDL player application; plays Ogg Theora files (with
|
||||
optional Vorbis audio second stream)
|
||||
last mod: $Id: player_example.c 17974 2011-05-07 22:31:49Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
/* far more complex than most Ogg 'example' programs. The complexity
|
||||
of maintaining A/V sync is pretty much unavoidable. It's necessary
|
||||
to actually have audio/video playback to make the hard audio clock
|
||||
sync actually work. If there's audio playback, there might as well
|
||||
be simple video playback as well...
|
||||
|
||||
A simple 'demux and write back streams' would have been easier,
|
||||
it's true. */
|
||||
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#if !defined(_LARGEFILE_SOURCE)
|
||||
#define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#if !defined(_LARGEFILE64_SOURCE)
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#if !defined(_FILE_OFFSET_BITS)
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _REENTRANT
|
||||
# define _REENTRANT
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include "theora/theoradec.h"
|
||||
#include "vorbis/codec.h"
|
||||
#include <SDL.h>
|
||||
|
||||
/* yes, this makes us OSS-specific for now. None of SDL, libao, libao2
|
||||
give us any way to determine hardware timing, and since the
|
||||
hard/kernel buffer is going to be most of or > a second, that's
|
||||
just a little bit important */
|
||||
#if defined(__FreeBSD__)
|
||||
#include <machine/soundcard.h>
|
||||
#define AUDIO_DEVICE "/dev/audio"
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include <soundcard.h>
|
||||
#define AUDIO_DEVICE "/dev/audio"
|
||||
#else
|
||||
#include <sys/soundcard.h>
|
||||
#define AUDIO_DEVICE "/dev/dsp"
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* Helper; just grab some more compressed bitstream and sync it for
|
||||
page extraction */
|
||||
int buffer_data(FILE *in,ogg_sync_state *oy){
|
||||
char *buffer=ogg_sync_buffer(oy,4096);
|
||||
int bytes=fread(buffer,1,4096,in);
|
||||
ogg_sync_wrote(oy,bytes);
|
||||
return(bytes);
|
||||
}
|
||||
|
||||
/* never forget that globals are a one-way ticket to Hell */
|
||||
/* Ogg and codec state for demux/decode */
|
||||
ogg_sync_state oy;
|
||||
ogg_page og;
|
||||
ogg_stream_state vo;
|
||||
ogg_stream_state to;
|
||||
th_info ti;
|
||||
th_comment tc;
|
||||
th_dec_ctx *td;
|
||||
th_setup_info *ts;
|
||||
vorbis_info vi;
|
||||
vorbis_dsp_state vd;
|
||||
vorbis_block vb;
|
||||
vorbis_comment vc;
|
||||
th_pixel_fmt px_fmt;
|
||||
|
||||
int theora_p=0;
|
||||
int vorbis_p=0;
|
||||
int stateflag=0;
|
||||
|
||||
/* SDL Video playback structures */
|
||||
SDL_Surface *screen;
|
||||
SDL_Overlay *yuv_overlay;
|
||||
SDL_Rect rect;
|
||||
unsigned char *RGBbuffer;
|
||||
|
||||
#define OC_CLAMP255(_x) ((unsigned char)((((_x)<0)-1)&((_x)|-((_x)>255))))
|
||||
|
||||
/* single frame video buffering */
|
||||
int videobuf_ready=0;
|
||||
ogg_int64_t videobuf_granulepos=-1;
|
||||
double videobuf_time=0;
|
||||
|
||||
/* single audio fragment audio buffering */
|
||||
int audiobuf_fill=0;
|
||||
int audiobuf_ready=0;
|
||||
ogg_int16_t *audiobuf;
|
||||
ogg_int64_t audiobuf_granulepos=0; /* time position of last sample */
|
||||
|
||||
/* audio / video synchronization tracking:
|
||||
|
||||
Since this will make it to Google at some point and lots of people
|
||||
search for how to do this, a quick rundown of a practical A/V sync
|
||||
strategy under Linux [the UNIX where Everything Is Hard]. Naturally,
|
||||
this works on other platforms using OSS for sound as well.
|
||||
|
||||
In OSS, we don't have reliable access to any precise information on
|
||||
the exact current playback position (that, of course would have been
|
||||
too easy; the kernel folks like to keep us app people working hard
|
||||
doing simple things that should have been solved once and abstracted
|
||||
long ago). Hopefully ALSA solves this a little better; we'll probably
|
||||
use that once ALSA is the standard in the stable kernel.
|
||||
|
||||
We can't use the system clock for a/v sync because audio is hard
|
||||
synced to its own clock, and both the system and audio clocks suffer
|
||||
from wobble, drift, and a lack of accuracy that can be guaranteed to
|
||||
add a reliable percent or so of error. After ten seconds, that's
|
||||
100ms. We can't drift by half a second every minute.
|
||||
|
||||
Although OSS can't generally tell us where the audio playback pointer
|
||||
is, we do know that if we work in complete audio fragments and keep
|
||||
the kernel buffer full, a blocking select on the audio buffer will
|
||||
give us a writable fragment immediately after playback finishes with
|
||||
it. We assume at that point that we know the exact number of bytes in
|
||||
the kernel buffer that have not been played (total fragments minus
|
||||
one) and calculate clock drift between audio and system then (and only
|
||||
then). Damp the sync correction fraction, apply, and walla: A
|
||||
reliable A/V clock that even works if it's interrupted. */
|
||||
|
||||
long audiofd_totalsize=-1;
|
||||
int audiofd_fragsize; /* read and write only complete fragments
|
||||
so that SNDCTL_DSP_GETOSPACE is
|
||||
accurate immediately after a bank
|
||||
switch */
|
||||
int audiofd=-1;
|
||||
ogg_int64_t audiofd_timer_calibrate=-1;
|
||||
|
||||
|
||||
static void open_audio(){
|
||||
audio_buf_info info;
|
||||
int format=AFMT_S16_NE; /* host endian */
|
||||
int channels=vi.channels;
|
||||
int rate=vi.rate;
|
||||
int ret;
|
||||
|
||||
audiofd=open(AUDIO_DEVICE,O_RDWR);
|
||||
if(audiofd<0){
|
||||
fprintf(stderr,"Could not open audio device " AUDIO_DEVICE ".\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret=ioctl(audiofd,SNDCTL_DSP_SETFMT,&format);
|
||||
if(ret){
|
||||
fprintf(stderr,"Could not set 16 bit host-endian playback\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret=ioctl(audiofd,SNDCTL_DSP_CHANNELS,&channels);
|
||||
if(ret){
|
||||
fprintf(stderr,"Could not set %d channel playback\n",channels);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret=ioctl(audiofd,SNDCTL_DSP_SPEED,&rate);
|
||||
if(ret){
|
||||
fprintf(stderr,"Could not set %d Hz playback\n",rate);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ioctl(audiofd,SNDCTL_DSP_GETOSPACE,&info);
|
||||
audiofd_fragsize=info.fragsize;
|
||||
audiofd_totalsize=info.fragstotal*info.fragsize;
|
||||
|
||||
audiobuf=malloc(audiofd_fragsize);
|
||||
}
|
||||
|
||||
static void audio_close(void){
|
||||
if(audiofd>-1){
|
||||
ioctl(audiofd,SNDCTL_DSP_RESET,NULL);
|
||||
close(audiofd);
|
||||
free(audiobuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* call this only immediately after unblocking from a full kernel
|
||||
having a newly empty fragment or at the point of DMA restart */
|
||||
void audio_calibrate_timer(int restart){
|
||||
struct timeval tv;
|
||||
ogg_int64_t current_sample;
|
||||
ogg_int64_t new_time;
|
||||
|
||||
gettimeofday(&tv,0);
|
||||
new_time=tv.tv_sec*1000+tv.tv_usec/1000;
|
||||
|
||||
if(restart){
|
||||
current_sample=audiobuf_granulepos-audiobuf_fill/2/vi.channels;
|
||||
}else
|
||||
current_sample=audiobuf_granulepos-
|
||||
(audiobuf_fill+audiofd_totalsize-audiofd_fragsize)/2/vi.channels;
|
||||
|
||||
new_time-=1000*current_sample/vi.rate;
|
||||
|
||||
audiofd_timer_calibrate=new_time;
|
||||
}
|
||||
|
||||
/* get relative time since beginning playback, compensating for A/V
|
||||
drift */
|
||||
double get_time(){
|
||||
static ogg_int64_t last=0;
|
||||
static ogg_int64_t up=0;
|
||||
ogg_int64_t now;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv,0);
|
||||
now=tv.tv_sec*1000+tv.tv_usec/1000;
|
||||
|
||||
if(audiofd_timer_calibrate==-1)audiofd_timer_calibrate=last=now;
|
||||
|
||||
if(audiofd<0){
|
||||
/* no audio timer to worry about, we can just use the system clock */
|
||||
/* only one complication: If the process is suspended, we should
|
||||
reset timing to account for the gap in play time. Do it the
|
||||
easy/hack way */
|
||||
if(now-last>1000)audiofd_timer_calibrate+=(now-last);
|
||||
last=now;
|
||||
}
|
||||
|
||||
if(now-up>200){
|
||||
double timebase=(now-audiofd_timer_calibrate)*.001;
|
||||
int hundredths=timebase*100-(long)timebase*100;
|
||||
int seconds=(long)timebase%60;
|
||||
int minutes=((long)timebase/60)%60;
|
||||
int hours=(long)timebase/3600;
|
||||
|
||||
fprintf(stderr," Playing: %d:%02d:%02d.%02d \r",
|
||||
hours,minutes,seconds,hundredths);
|
||||
up=now;
|
||||
}
|
||||
|
||||
return (now-audiofd_timer_calibrate)*.001;
|
||||
|
||||
}
|
||||
|
||||
/* write a fragment to the OSS kernel audio API, but only if we can
|
||||
stuff in a whole fragment without blocking */
|
||||
void audio_write_nonblocking(void){
|
||||
|
||||
if(audiobuf_ready){
|
||||
audio_buf_info info;
|
||||
long bytes;
|
||||
|
||||
ioctl(audiofd,SNDCTL_DSP_GETOSPACE,&info);
|
||||
bytes=info.bytes;
|
||||
if(bytes>=audiofd_fragsize){
|
||||
if(bytes==audiofd_totalsize)audio_calibrate_timer(1);
|
||||
|
||||
while(1){
|
||||
bytes=write(audiofd,audiobuf+(audiofd_fragsize-audiobuf_fill),
|
||||
audiofd_fragsize);
|
||||
|
||||
if(bytes>0){
|
||||
|
||||
if(bytes!=audiobuf_fill){
|
||||
/* shouldn't actually be possible... but eh */
|
||||
audiobuf_fill-=bytes;
|
||||
}else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
audiobuf_fill=0;
|
||||
audiobuf_ready=0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clean quit on Ctrl-C for SDL and thread shutdown as per SDL example
|
||||
(we don't use any threads, but libSDL does) */
|
||||
int got_sigint=0;
|
||||
static void sigint_handler (int signal) {
|
||||
got_sigint = 1;
|
||||
}
|
||||
|
||||
static void open_video(void){
|
||||
int w;
|
||||
int h;
|
||||
w=(ti.pic_x+ti.pic_width+1&~1)-(ti.pic_x&~1);
|
||||
h=(ti.pic_y+ti.pic_height+1&~1)-(ti.pic_y&~1);
|
||||
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
|
||||
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
screen = SDL_SetVideoMode(w, h, 0, SDL_SWSURFACE);
|
||||
if ( screen == NULL ) {
|
||||
fprintf(stderr, "Unable to set %dx%d video: %s\n",
|
||||
w,h,SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (px_fmt==TH_PF_422)
|
||||
yuv_overlay = SDL_CreateYUVOverlay(w, h,
|
||||
SDL_YUY2_OVERLAY,
|
||||
screen);
|
||||
else if (px_fmt==TH_PF_444) {
|
||||
RGBbuffer = calloc(sizeof(char),w*h*4);
|
||||
fprintf(stderr,"warning: SDL does not support YUV 4:4:4, using slow software conversion.\n");
|
||||
} else
|
||||
yuv_overlay = SDL_CreateYUVOverlay(w, h,
|
||||
SDL_YV12_OVERLAY,
|
||||
screen);
|
||||
|
||||
if ( (yuv_overlay == NULL && px_fmt!=TH_PF_444) || (screen == NULL && px_fmt==TH_PF_444) ) {
|
||||
fprintf(stderr, "SDL: xCouldn't create SDL_yuv_overlay: %s\n",
|
||||
SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = w;
|
||||
rect.h = h;
|
||||
|
||||
if (px_fmt!=TH_PF_444)
|
||||
SDL_DisplayYUVOverlay(yuv_overlay, &rect);
|
||||
}
|
||||
|
||||
static void video_write(void){
|
||||
int i;
|
||||
th_ycbcr_buffer yuv;
|
||||
int y_offset, uv_offset;
|
||||
th_decode_ycbcr_out(td,yuv);
|
||||
/* Lock SDL_yuv_overlay */
|
||||
if ( SDL_MUSTLOCK(screen) ) {
|
||||
if ( SDL_LockSurface(screen) < 0 ) return;
|
||||
}
|
||||
if (px_fmt!=TH_PF_444 && SDL_LockYUVOverlay(yuv_overlay) < 0) return;
|
||||
|
||||
/* let's draw the data on a SDL screen (*screen) */
|
||||
/* deal with border stride */
|
||||
/* reverse u and v for SDL */
|
||||
/* and crop input properly, respecting the encoded frame rect */
|
||||
/* problems may exist for odd frame rect for some encodings */
|
||||
|
||||
y_offset=(ti.pic_x&~1)+yuv[0].stride*(ti.pic_y&~1);
|
||||
|
||||
if (px_fmt==TH_PF_422) {
|
||||
uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y);
|
||||
/* SDL doesn't have a planar 4:2:2 */
|
||||
for(i=0;i<yuv_overlay->h;i++) {
|
||||
int j;
|
||||
char *in_y = (char *)yuv[0].data+y_offset+yuv[0].stride*i;
|
||||
char *out = (char *)(yuv_overlay->pixels[0]+yuv_overlay->pitches[0]*i);
|
||||
for (j=0;j<yuv_overlay->w;j++)
|
||||
out[j*2] = in_y[j];
|
||||
char *in_u = (char *)yuv[1].data+uv_offset+yuv[1].stride*i;
|
||||
char *in_v = (char *)yuv[2].data+uv_offset+yuv[2].stride*i;
|
||||
for (j=0;j<yuv_overlay->w>>1;j++) {
|
||||
out[j*4+1] = in_u[j];
|
||||
out[j*4+3] = in_v[j];
|
||||
}
|
||||
}
|
||||
} else if (px_fmt==TH_PF_444){
|
||||
SDL_Surface *output;
|
||||
for(i=0;i<screen->h;i++) {
|
||||
int j;
|
||||
unsigned char *in_y = (unsigned char *)yuv[0].data+y_offset+yuv[0].stride*i;
|
||||
unsigned char *in_u = (unsigned char *)yuv[1].data+y_offset+yuv[1].stride*i;
|
||||
unsigned char *in_v = (unsigned char *)yuv[2].data+y_offset+yuv[2].stride*i;
|
||||
unsigned char *out = RGBbuffer+(screen->w*i*4);
|
||||
for (j=0;j<screen->w;j++) {
|
||||
int r, g, b;
|
||||
r=(1904000*in_y[j]+2609823*in_v[j]-363703744)/1635200;
|
||||
g=(3827562*in_y[j]-1287801*in_u[j]
|
||||
-2672387*in_v[j]+447306710)/3287200;
|
||||
b=(952000*in_y[j]+1649289*in_u[j]-225932192)/817600;
|
||||
out[4*j+0]=OC_CLAMP255(b);
|
||||
out[4*j+1]=OC_CLAMP255(g);
|
||||
out[4*j+2]=OC_CLAMP255(r);
|
||||
}
|
||||
output=SDL_CreateRGBSurfaceFrom(RGBbuffer,screen->w,screen->h,32,4*screen->w,0,0,0,0);
|
||||
SDL_BlitSurface(output,NULL,screen,NULL);
|
||||
}
|
||||
} else {
|
||||
uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y/2);
|
||||
for(i=0;i<yuv_overlay->h;i++)
|
||||
memcpy(yuv_overlay->pixels[0]+yuv_overlay->pitches[0]*i,
|
||||
yuv[0].data+y_offset+yuv[0].stride*i,
|
||||
yuv_overlay->w);
|
||||
for(i=0;i<yuv_overlay->h/2;i++){
|
||||
memcpy(yuv_overlay->pixels[1]+yuv_overlay->pitches[1]*i,
|
||||
yuv[2].data+uv_offset+yuv[2].stride*i,
|
||||
yuv_overlay->w/2);
|
||||
memcpy(yuv_overlay->pixels[2]+yuv_overlay->pitches[2]*i,
|
||||
yuv[1].data+uv_offset+yuv[1].stride*i,
|
||||
yuv_overlay->w/2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock SDL_yuv_overlay */
|
||||
if ( SDL_MUSTLOCK(screen) ) {
|
||||
SDL_UnlockSurface(screen);
|
||||
}
|
||||
if (px_fmt!=TH_PF_444) {
|
||||
SDL_UnlockYUVOverlay(yuv_overlay);
|
||||
/* Show, baby, show! */
|
||||
SDL_DisplayYUVOverlay(yuv_overlay, &rect);
|
||||
} else {
|
||||
SDL_Flip(screen);
|
||||
}
|
||||
}
|
||||
/* dump the theora (or vorbis) comment header */
|
||||
static int dump_comments(th_comment *tc){
|
||||
int i, len;
|
||||
char *value;
|
||||
FILE *out=stdout;
|
||||
|
||||
fprintf(out,"Encoded by %s\n",tc->vendor);
|
||||
if(tc->comments){
|
||||
fprintf(out, "theora comment header:\n");
|
||||
for(i=0;i<tc->comments;i++){
|
||||
if(tc->user_comments[i]){
|
||||
len=tc->comment_lengths[i];
|
||||
value=malloc(len+1);
|
||||
memcpy(value,tc->user_comments[i],len);
|
||||
value[len]='\0';
|
||||
fprintf(out, "\t%s\n", value);
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Report the encoder-specified colorspace for the video, if any.
|
||||
We don't actually make use of the information in this example;
|
||||
a real player should attempt to perform color correction for
|
||||
whatever display device it supports. */
|
||||
static void report_colorspace(th_info *ti)
|
||||
{
|
||||
switch(ti->colorspace){
|
||||
case TH_CS_UNSPECIFIED:
|
||||
/* nothing to report */
|
||||
break;;
|
||||
case TH_CS_ITU_REC_470M:
|
||||
fprintf(stderr," encoder specified ITU Rec 470M (NTSC) color.\n");
|
||||
break;;
|
||||
case TH_CS_ITU_REC_470BG:
|
||||
fprintf(stderr," encoder specified ITU Rec 470BG (PAL) color.\n");
|
||||
break;;
|
||||
default:
|
||||
fprintf(stderr,"warning: encoder specified unknown colorspace (%d).\n",
|
||||
ti->colorspace);
|
||||
break;;
|
||||
}
|
||||
}
|
||||
|
||||
/* helper: push a page into the appropriate steam */
|
||||
/* this can be done blindly; a stream won't accept a page
|
||||
that doesn't belong to it */
|
||||
static int queue_page(ogg_page *page){
|
||||
if(theora_p)ogg_stream_pagein(&to,page);
|
||||
if(vorbis_p)ogg_stream_pagein(&vo,page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usage(void){
|
||||
fprintf(stderr,
|
||||
"Usage: player_example <file.ogv>\n"
|
||||
"input is read from stdin if no file is passed on the command line\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc,char *const *argv){
|
||||
|
||||
int pp_level_max;
|
||||
int pp_level;
|
||||
int pp_inc;
|
||||
int i,j;
|
||||
ogg_packet op;
|
||||
|
||||
FILE *infile = stdin;
|
||||
|
||||
int frames = 0;
|
||||
int dropped = 0;
|
||||
|
||||
#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
|
||||
/* Beware the evil ifdef. We avoid these where we can, but this one we
|
||||
cannot. Don't add any more, you'll probably go to hell if you do. */
|
||||
_setmode( _fileno( stdin ), _O_BINARY );
|
||||
#endif
|
||||
|
||||
/* open the input file if any */
|
||||
if(argc==2){
|
||||
infile=fopen(argv[1],"rb");
|
||||
if(infile==NULL){
|
||||
fprintf(stderr,"Unable to open '%s' for playback.\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(argc>2){
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* start up Ogg stream synchronization layer */
|
||||
ogg_sync_init(&oy);
|
||||
|
||||
/* init supporting Vorbis structures needed in header parsing */
|
||||
vorbis_info_init(&vi);
|
||||
vorbis_comment_init(&vc);
|
||||
|
||||
/* init supporting Theora structures needed in header parsing */
|
||||
th_comment_init(&tc);
|
||||
th_info_init(&ti);
|
||||
|
||||
/* Ogg file open; parse the headers */
|
||||
/* Only interested in Vorbis/Theora streams */
|
||||
while(!stateflag){
|
||||
int ret=buffer_data(infile,&oy);
|
||||
if(ret==0)break;
|
||||
while(ogg_sync_pageout(&oy,&og)>0){
|
||||
ogg_stream_state test;
|
||||
|
||||
/* is this a mandated initial header? If not, stop parsing */
|
||||
if(!ogg_page_bos(&og)){
|
||||
/* don't leak the page; get it into the appropriate stream */
|
||||
queue_page(&og);
|
||||
stateflag=1;
|
||||
break;
|
||||
}
|
||||
|
||||
ogg_stream_init(&test,ogg_page_serialno(&og));
|
||||
ogg_stream_pagein(&test,&og);
|
||||
ogg_stream_packetout(&test,&op);
|
||||
|
||||
|
||||
/* identify the codec: try theora */
|
||||
if(!theora_p && th_decode_headerin(&ti,&tc,&ts,&op)>=0){
|
||||
/* it is theora */
|
||||
memcpy(&to,&test,sizeof(test));
|
||||
theora_p=1;
|
||||
}else if(!vorbis_p && vorbis_synthesis_headerin(&vi,&vc,&op)>=0){
|
||||
/* it is vorbis */
|
||||
memcpy(&vo,&test,sizeof(test));
|
||||
vorbis_p=1;
|
||||
}else{
|
||||
/* whatever it is, we don't care about it */
|
||||
ogg_stream_clear(&test);
|
||||
}
|
||||
}
|
||||
/* fall through to non-bos page parsing */
|
||||
}
|
||||
|
||||
/* we're expecting more header packets. */
|
||||
while((theora_p && theora_p<3) || (vorbis_p && vorbis_p<3)){
|
||||
int ret;
|
||||
|
||||
/* look for further theora headers */
|
||||
while(theora_p && (theora_p<3) && (ret=ogg_stream_packetout(&to,&op))){
|
||||
if(ret<0){
|
||||
fprintf(stderr,"Error parsing Theora stream headers; "
|
||||
"corrupt stream?\n");
|
||||
exit(1);
|
||||
}
|
||||
if(!th_decode_headerin(&ti,&tc,&ts,&op)){
|
||||
fprintf(stderr,"Error parsing Theora stream headers; "
|
||||
"corrupt stream?\n");
|
||||
exit(1);
|
||||
}
|
||||
theora_p++;
|
||||
}
|
||||
|
||||
/* look for more vorbis header packets */
|
||||
while(vorbis_p && (vorbis_p<3) && (ret=ogg_stream_packetout(&vo,&op))){
|
||||
if(ret<0){
|
||||
fprintf(stderr,"Error parsing Vorbis stream headers; corrupt stream?\n");
|
||||
exit(1);
|
||||
}
|
||||
if(vorbis_synthesis_headerin(&vi,&vc,&op)){
|
||||
fprintf(stderr,"Error parsing Vorbis stream headers; corrupt stream?\n");
|
||||
exit(1);
|
||||
}
|
||||
vorbis_p++;
|
||||
if(vorbis_p==3)break;
|
||||
}
|
||||
|
||||
/* The header pages/packets will arrive before anything else we
|
||||
care about, or the stream is not obeying spec */
|
||||
|
||||
if(ogg_sync_pageout(&oy,&og)>0){
|
||||
queue_page(&og); /* demux into the appropriate stream */
|
||||
}else{
|
||||
int ret=buffer_data(infile,&oy); /* someone needs more data */
|
||||
if(ret==0){
|
||||
fprintf(stderr,"End of file while searching for codec headers.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* and now we have it all. initialize decoders */
|
||||
if(theora_p){
|
||||
td=th_decode_alloc(&ti,ts);
|
||||
printf("Ogg logical stream %lx is Theora %dx%d %.02f fps",
|
||||
to.serialno,ti.pic_width,ti.pic_height,
|
||||
(double)ti.fps_numerator/ti.fps_denominator);
|
||||
px_fmt=ti.pixel_fmt;
|
||||
switch(ti.pixel_fmt){
|
||||
case TH_PF_420: printf(" 4:2:0 video\n"); break;
|
||||
case TH_PF_422: printf(" 4:2:2 video\n"); break;
|
||||
case TH_PF_444: printf(" 4:4:4 video\n"); break;
|
||||
case TH_PF_RSVD:
|
||||
default:
|
||||
printf(" video\n (UNKNOWN Chroma sampling!)\n");
|
||||
break;
|
||||
}
|
||||
if(ti.pic_width!=ti.frame_width || ti.pic_height!=ti.frame_height)
|
||||
printf(" Frame content is %dx%d with offset (%d,%d).\n",
|
||||
ti.frame_width, ti.frame_height, ti.pic_x, ti.pic_y);
|
||||
report_colorspace(&ti);
|
||||
dump_comments(&tc);
|
||||
th_decode_ctl(td,TH_DECCTL_GET_PPLEVEL_MAX,&pp_level_max,
|
||||
sizeof(pp_level_max));
|
||||
pp_level=pp_level_max;
|
||||
th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
|
||||
pp_inc=0;
|
||||
|
||||
/*{
|
||||
int arg = 0xffff;
|
||||
th_decode_ctl(td,TH_DECCTL_SET_TELEMETRY_MBMODE,&arg,sizeof(arg));
|
||||
th_decode_ctl(td,TH_DECCTL_SET_TELEMETRY_MV,&arg,sizeof(arg));
|
||||
th_decode_ctl(td,TH_DECCTL_SET_TELEMETRY_QI,&arg,sizeof(arg));
|
||||
arg=10;
|
||||
th_decode_ctl(td,TH_DECCTL_SET_TELEMETRY_BITS,&arg,sizeof(arg));
|
||||
}*/
|
||||
}else{
|
||||
/* tear down the partial theora setup */
|
||||
th_info_clear(&ti);
|
||||
th_comment_clear(&tc);
|
||||
}
|
||||
|
||||
th_setup_free(ts);
|
||||
|
||||
if(vorbis_p){
|
||||
vorbis_synthesis_init(&vd,&vi);
|
||||
vorbis_block_init(&vd,&vb);
|
||||
fprintf(stderr,"Ogg logical stream %lx is Vorbis %d channel %ld Hz audio.\n",
|
||||
vo.serialno,vi.channels,vi.rate);
|
||||
}else{
|
||||
/* tear down the partial vorbis setup */
|
||||
vorbis_info_clear(&vi);
|
||||
vorbis_comment_clear(&vc);
|
||||
}
|
||||
|
||||
/* open audio */
|
||||
if(vorbis_p)open_audio();
|
||||
|
||||
/* open video */
|
||||
if(theora_p)open_video();
|
||||
|
||||
/* install signal handler as SDL clobbered the default */
|
||||
signal (SIGINT, sigint_handler);
|
||||
|
||||
/* on to the main decode loop. We assume in this example that audio
|
||||
and video start roughly together, and don't begin playback until
|
||||
we have a start frame for both. This is not necessarily a valid
|
||||
assumption in Ogg A/V streams! It will always be true of the
|
||||
example_encoder (and most streams) though. */
|
||||
|
||||
stateflag=0; /* playback has not begun */
|
||||
while(!got_sigint){
|
||||
|
||||
/* we want a video and audio frame ready to go at all times. If
|
||||
we have to buffer incoming, buffer the compressed data (ie, let
|
||||
ogg do the buffering) */
|
||||
while(vorbis_p && !audiobuf_ready){
|
||||
int ret;
|
||||
float **pcm;
|
||||
|
||||
/* if there's pending, decoded audio, grab it */
|
||||
if((ret=vorbis_synthesis_pcmout(&vd,&pcm))>0){
|
||||
int count=audiobuf_fill/2;
|
||||
int maxsamples=(audiofd_fragsize-audiobuf_fill)/2/vi.channels;
|
||||
for(i=0;i<ret && i<maxsamples;i++)
|
||||
for(j=0;j<vi.channels;j++){
|
||||
int val=rint(pcm[j][i]*32767.f);
|
||||
if(val>32767)val=32767;
|
||||
if(val<-32768)val=-32768;
|
||||
audiobuf[count++]=val;
|
||||
}
|
||||
vorbis_synthesis_read(&vd,i);
|
||||
audiobuf_fill+=i*vi.channels*2;
|
||||
if(audiobuf_fill==audiofd_fragsize)audiobuf_ready=1;
|
||||
if(vd.granulepos>=0)
|
||||
audiobuf_granulepos=vd.granulepos-ret+i;
|
||||
else
|
||||
audiobuf_granulepos+=i;
|
||||
|
||||
}else{
|
||||
|
||||
/* no pending audio; is there a pending packet to decode? */
|
||||
if(ogg_stream_packetout(&vo,&op)>0){
|
||||
if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
|
||||
vorbis_synthesis_blockin(&vd,&vb);
|
||||
}else /* we need more data; break out to suck in another page */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while(theora_p && !videobuf_ready){
|
||||
/* theora is one in, one out... */
|
||||
if(ogg_stream_packetout(&to,&op)>0){
|
||||
|
||||
if(pp_inc){
|
||||
pp_level+=pp_inc;
|
||||
th_decode_ctl(td,TH_DECCTL_SET_PPLEVEL,&pp_level,
|
||||
sizeof(pp_level));
|
||||
pp_inc=0;
|
||||
}
|
||||
/*HACK: This should be set after a seek or a gap, but we might not have
|
||||
a granulepos for the first packet (we only have them for the last
|
||||
packet on a page), so we just set it as often as we get it.
|
||||
To do this right, we should back-track from the last packet on the
|
||||
page and compute the correct granulepos for the first packet after
|
||||
a seek or a gap.*/
|
||||
if(op.granulepos>=0){
|
||||
th_decode_ctl(td,TH_DECCTL_SET_GRANPOS,&op.granulepos,
|
||||
sizeof(op.granulepos));
|
||||
}
|
||||
if(th_decode_packetin(td,&op,&videobuf_granulepos)==0){
|
||||
videobuf_time=th_granule_time(td,videobuf_granulepos);
|
||||
frames++;
|
||||
|
||||
/* is it already too old to be useful? This is only actually
|
||||
useful cosmetically after a SIGSTOP. Note that we have to
|
||||
decode the frame even if we don't show it (for now) due to
|
||||
keyframing. Soon enough libtheora will be able to deal
|
||||
with non-keyframe seeks. */
|
||||
|
||||
if(videobuf_time>=get_time())
|
||||
videobuf_ready=1;
|
||||
else{
|
||||
/*If we are too slow, reduce the pp level.*/
|
||||
pp_inc=pp_level>0?-1:0;
|
||||
dropped++;
|
||||
}
|
||||
}
|
||||
|
||||
}else
|
||||
break;
|
||||
}
|
||||
|
||||
if(!videobuf_ready && !audiobuf_ready && feof(infile))break;
|
||||
|
||||
if(!videobuf_ready || !audiobuf_ready){
|
||||
/* no data yet for somebody. Grab another page */
|
||||
buffer_data(infile,&oy);
|
||||
while(ogg_sync_pageout(&oy,&og)>0){
|
||||
queue_page(&og);
|
||||
}
|
||||
}
|
||||
|
||||
/* If playback has begun, top audio buffer off immediately. */
|
||||
if(stateflag) audio_write_nonblocking();
|
||||
|
||||
/* are we at or past time for this video frame? */
|
||||
if(stateflag && videobuf_ready && videobuf_time<=get_time()){
|
||||
video_write();
|
||||
videobuf_ready=0;
|
||||
}
|
||||
|
||||
if(stateflag &&
|
||||
(audiobuf_ready || !vorbis_p) &&
|
||||
(videobuf_ready || !theora_p) &&
|
||||
!got_sigint){
|
||||
/* we have an audio frame ready (which means the audio buffer is
|
||||
full), it's not time to play video, so wait until one of the
|
||||
audio buffer is ready or it's near time to play video */
|
||||
|
||||
/* set up select wait on the audiobuffer and a timeout for video */
|
||||
struct timeval timeout;
|
||||
fd_set writefs;
|
||||
fd_set empty;
|
||||
int n=0;
|
||||
|
||||
FD_ZERO(&writefs);
|
||||
FD_ZERO(&empty);
|
||||
if(audiofd>=0){
|
||||
FD_SET(audiofd,&writefs);
|
||||
n=audiofd+1;
|
||||
}
|
||||
|
||||
if(theora_p){
|
||||
double tdiff;
|
||||
long milliseconds;
|
||||
tdiff=videobuf_time-get_time();
|
||||
/*If we have lots of extra time, increase the post-processing level.*/
|
||||
if(tdiff>ti.fps_denominator*0.25/ti.fps_numerator){
|
||||
pp_inc=pp_level<pp_level_max?1:0;
|
||||
}
|
||||
else if(tdiff<ti.fps_denominator*0.05/ti.fps_numerator){
|
||||
pp_inc=pp_level>0?-1:0;
|
||||
}
|
||||
milliseconds=tdiff*1000-5;
|
||||
if(milliseconds>500)milliseconds=500;
|
||||
if(milliseconds>0){
|
||||
timeout.tv_sec=milliseconds/1000;
|
||||
timeout.tv_usec=(milliseconds%1000)*1000;
|
||||
|
||||
n=select(n,&empty,&writefs,&empty,&timeout);
|
||||
if(n)audio_calibrate_timer(0);
|
||||
}
|
||||
}else{
|
||||
select(n,&empty,&writefs,&empty,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* if our buffers either don't exist or are ready to go,
|
||||
we can begin playback */
|
||||
if((!theora_p || videobuf_ready) &&
|
||||
(!vorbis_p || audiobuf_ready))stateflag=1;
|
||||
/* same if we've run out of input */
|
||||
if(feof(infile))stateflag=1;
|
||||
|
||||
}
|
||||
|
||||
/* tear it all down */
|
||||
|
||||
audio_close();
|
||||
SDL_Quit();
|
||||
|
||||
if(vorbis_p){
|
||||
ogg_stream_clear(&vo);
|
||||
vorbis_block_clear(&vb);
|
||||
vorbis_dsp_clear(&vd);
|
||||
vorbis_comment_clear(&vc);
|
||||
vorbis_info_clear(&vi);
|
||||
}
|
||||
if(theora_p){
|
||||
ogg_stream_clear(&to);
|
||||
th_decode_free(td);
|
||||
th_comment_clear(&tc);
|
||||
th_info_clear(&ti);
|
||||
}
|
||||
ogg_sync_clear(&oy);
|
||||
|
||||
if(infile && infile!=stdin)fclose(infile);
|
||||
|
||||
fprintf(stderr,
|
||||
"\r \r");
|
||||
fprintf(stderr, "%d frames", frames);
|
||||
if (dropped) fprintf(stderr, " (%d dropped)", dropped);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\nDone.\n");
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,942 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009,2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: example encoder application; makes an Ogg Theora
|
||||
file from a sequence of png images
|
||||
last mod: $Id: png2theora.c 17975 2011-05-07 22:35:30Z giles $
|
||||
based on code from Vegard Nossum
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <png.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include "theora/theoraenc.h"
|
||||
|
||||
#define PROGRAM_NAME "png2theora"
|
||||
#define PROGRAM_VERSION "1.1"
|
||||
|
||||
static const char *option_output = NULL;
|
||||
static int video_fps_numerator = 24;
|
||||
static int video_fps_denominator = 1;
|
||||
static int video_aspect_numerator = 0;
|
||||
static int video_aspect_denominator = 0;
|
||||
static int video_rate = -1;
|
||||
static int video_quality = -1;
|
||||
ogg_uint32_t keyframe_frequency=0;
|
||||
int buf_delay=-1;
|
||||
int vp3_compatible=0;
|
||||
static int chroma_format = TH_PF_420;
|
||||
|
||||
static FILE *twopass_file = NULL;
|
||||
static int twopass=0;
|
||||
static int passno;
|
||||
|
||||
static FILE *ogg_fp = NULL;
|
||||
static ogg_stream_state ogg_os;
|
||||
static ogg_packet op;
|
||||
static ogg_page og;
|
||||
|
||||
static th_enc_ctx *td;
|
||||
static th_info ti;
|
||||
|
||||
static char *input_filter;
|
||||
|
||||
const char *optstring = "o:hv:\4:\2:V:s:S:f:F:ck:d:\1\2\3\4\5\6";
|
||||
struct option options [] = {
|
||||
{"output",required_argument,NULL,'o'},
|
||||
{"help",no_argument,NULL,'h'},
|
||||
{"chroma-444",no_argument,NULL,'\5'},
|
||||
{"chroma-422",no_argument,NULL,'\6'},
|
||||
{"video-rate-target",required_argument,NULL,'V'},
|
||||
{"video-quality",required_argument,NULL,'v'},
|
||||
{"aspect-numerator",required_argument,NULL,'s'},
|
||||
{"aspect-denominator",required_argument,NULL,'S'},
|
||||
{"framerate-numerator",required_argument,NULL,'f'},
|
||||
{"framerate-denominator",required_argument,NULL,'F'},
|
||||
{"vp3-compatible",no_argument,NULL,'c'},
|
||||
{"soft-target",no_argument,NULL,'\1'},
|
||||
{"keyframe-freq",required_argument,NULL,'k'},
|
||||
{"buf-delay",required_argument,NULL,'d'},
|
||||
{"two-pass",no_argument,NULL,'\2'},
|
||||
{"first-pass",required_argument,NULL,'\3'},
|
||||
{"second-pass",required_argument,NULL,'\4'},
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
|
||||
static void usage(void){
|
||||
fprintf(stderr,
|
||||
"%s %s\n"
|
||||
"Usage: %s [options] <input>\n\n"
|
||||
"The input argument uses C printf format to represent a list of files,\n"
|
||||
" i.e. file-%%06d.png to look for files file000001.png to file9999999.png \n\n"
|
||||
"Options: \n\n"
|
||||
" -o --output <filename.ogv> file name for encoded output (required);\n"
|
||||
" -v --video-quality <n> Theora quality selector fro 0 to 10\n"
|
||||
" (0 yields smallest files but lowest\n"
|
||||
" video quality. 10 yields highest\n"
|
||||
" fidelity but large files)\n\n"
|
||||
" -V --video-rate-target <n> bitrate target for Theora video\n\n"
|
||||
" --soft-target Use a large reservoir and treat the rate\n"
|
||||
" as a soft target; rate control is less\n"
|
||||
" strict but resulting quality is usually\n"
|
||||
" higher/smoother overall. Soft target also\n"
|
||||
" allows an optional -v setting to specify\n"
|
||||
" a minimum allowed quality.\n\n"
|
||||
" --two-pass Compress input using two-pass rate control\n"
|
||||
" This option performs both passes automatically.\n\n"
|
||||
" --first-pass <filename> Perform first-pass of a two-pass rate\n"
|
||||
" controlled encoding, saving pass data to\n"
|
||||
" <filename> for a later second pass\n\n"
|
||||
" --second-pass <filename> Perform second-pass of a two-pass rate\n"
|
||||
" controlled encoding, reading first-pass\n"
|
||||
" data from <filename>. The first pass\n"
|
||||
" data must come from a first encoding pass\n"
|
||||
" using identical input video to work\n"
|
||||
" properly.\n\n"
|
||||
" -k --keyframe-freq <n> Keyframe frequency\n"
|
||||
" -d --buf-delay <n> Buffer delay (in frames). Longer delays\n"
|
||||
" allow smoother rate adaptation and provide\n"
|
||||
" better overall quality, but require more\n"
|
||||
" client side buffering and add latency. The\n"
|
||||
" default value is the keyframe interval for\n"
|
||||
" one-pass encoding (or somewhat larger if\n"
|
||||
" --soft-target is used) and infinite for\n"
|
||||
" two-pass encoding.\n"
|
||||
" --chroma-444 Use 4:4:4 chroma subsampling\n"
|
||||
" --chroma-422 Use 4:2:2 chroma subsampling\n"
|
||||
" (4:2:0 is default)\n\n"
|
||||
" -s --aspect-numerator <n> Aspect ratio numerator, default is 0\n"
|
||||
" -S --aspect-denominator <n> Aspect ratio denominator, default is 0\n"
|
||||
" -f --framerate-numerator <n> Frame rate numerator\n"
|
||||
" -F --framerate-denominator <n> Frame rate denominator\n"
|
||||
" The frame rate nominator divided by this\n"
|
||||
" determines the frame rate in units per tick\n"
|
||||
,PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_NAME
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
int
|
||||
alphasort (const void *a, const void *b)
|
||||
{
|
||||
return strcoll ((*(const struct dirent **) a)->d_name,
|
||||
(*(const struct dirent **) b)->d_name);
|
||||
}
|
||||
|
||||
int
|
||||
scandir (const char *dir, struct dirent ***namelist,
|
||||
int (*select)(const struct dirent *), int (*compar)(const void *, const void *))
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *entry;
|
||||
register int i=0;
|
||||
size_t entrysize;
|
||||
|
||||
if ((d=opendir(dir)) == NULL)
|
||||
return(-1);
|
||||
|
||||
*namelist=NULL;
|
||||
while ((entry=readdir(d)) != NULL)
|
||||
{
|
||||
if (select == NULL || (select != NULL && (*select)(entry)))
|
||||
{
|
||||
*namelist=(struct dirent **)realloc((void *)(*namelist),
|
||||
(size_t)((i+1)*sizeof(struct dirent *)));
|
||||
if (*namelist == NULL) return(-1);
|
||||
entrysize=sizeof(struct dirent)-sizeof(entry->d_name)+strlen(entry->d_name)+1;
|
||||
(*namelist)[i]=(struct dirent *)malloc(entrysize);
|
||||
if ((*namelist)[i] == NULL) return(-1);
|
||||
memcpy((*namelist)[i], entry, entrysize);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (closedir(d)) return(-1);
|
||||
if (i == 0) return(-1);
|
||||
if (compar != NULL)
|
||||
qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar);
|
||||
|
||||
return(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
theora_write_frame(th_ycbcr_buffer ycbcr, int last)
|
||||
{
|
||||
ogg_packet op;
|
||||
ogg_page og;
|
||||
|
||||
/* Theora is a one-frame-in,one-frame-out system; submit a frame
|
||||
for compression and pull out the packet */
|
||||
/* in two-pass mode's second pass, we need to submit first-pass data */
|
||||
if(passno==2){
|
||||
int ret;
|
||||
for(;;){
|
||||
static unsigned char buffer[80];
|
||||
static int buf_pos;
|
||||
int bytes;
|
||||
/*Ask the encoder how many bytes it would like.*/
|
||||
bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0);
|
||||
if(bytes<0){
|
||||
fprintf(stderr,"Error submitting pass data in second pass.\n");
|
||||
exit(1);
|
||||
}
|
||||
/*If it's got enough, stop.*/
|
||||
if(bytes==0)break;
|
||||
/*Read in some more bytes, if necessary.*/
|
||||
if(bytes>80-buf_pos)bytes=80-buf_pos;
|
||||
if(bytes>0&&fread(buffer+buf_pos,1,bytes,twopass_file)<bytes){
|
||||
fprintf(stderr,"Could not read frame data from two-pass data file!\n");
|
||||
exit(1);
|
||||
}
|
||||
/*And pass them off.*/
|
||||
ret=th_encode_ctl(td,TH_ENCCTL_2PASS_IN,buffer,bytes);
|
||||
if(ret<0){
|
||||
fprintf(stderr,"Error submitting pass data in second pass.\n");
|
||||
exit(1);
|
||||
}
|
||||
/*If the encoder consumed the whole buffer, reset it.*/
|
||||
if(ret>=bytes)buf_pos=0;
|
||||
/*Otherwise remember how much it used.*/
|
||||
else buf_pos+=ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(th_encode_ycbcr_in(td, ycbcr)) {
|
||||
fprintf(stderr, "%s: error: could not encode frame\n",
|
||||
option_output);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* in two-pass mode's first pass we need to extract and save the pass data */
|
||||
if(passno==1){
|
||||
unsigned char *buffer;
|
||||
int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
|
||||
if(bytes<0){
|
||||
fprintf(stderr,"Could not read two-pass data from encoder.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(fwrite(buffer,1,bytes,twopass_file)<bytes){
|
||||
fprintf(stderr,"Unable to write to two-pass data file.\n");
|
||||
exit(1);
|
||||
}
|
||||
fflush(twopass_file);
|
||||
}
|
||||
|
||||
if(!th_encode_packetout(td, last, &op)) {
|
||||
fprintf(stderr, "%s: error: could not read packets\n",
|
||||
option_output);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (passno!=1) {
|
||||
ogg_stream_packetin(&ogg_os, &op);
|
||||
while(ogg_stream_pageout(&ogg_os, &og)) {
|
||||
fwrite(og.header, og.header_len, 1, ogg_fp);
|
||||
fwrite(og.body, og.body_len, 1, ogg_fp);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
clamp(int d)
|
||||
{
|
||||
if(d < 0)
|
||||
return 0;
|
||||
|
||||
if(d > 255)
|
||||
return 255;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static void
|
||||
rgb_to_yuv(png_bytep *png,
|
||||
th_ycbcr_buffer ycbcr,
|
||||
unsigned int w, unsigned int h)
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
|
||||
unsigned int x1;
|
||||
unsigned int y1;
|
||||
|
||||
unsigned long yuv_w;
|
||||
|
||||
unsigned char *yuv_y;
|
||||
unsigned char *yuv_u;
|
||||
unsigned char *yuv_v;
|
||||
|
||||
yuv_w = ycbcr[0].width;
|
||||
|
||||
yuv_y = ycbcr[0].data;
|
||||
yuv_u = ycbcr[1].data;
|
||||
yuv_v = ycbcr[2].data;
|
||||
|
||||
/*This ignores gamma and RGB primary/whitepoint differences.
|
||||
It also isn't terribly fast (though a decent compiler will
|
||||
strength-reduce the division to a multiplication).*/
|
||||
|
||||
if (chroma_format == TH_PF_420) {
|
||||
for(y = 0; y < h; y += 2) {
|
||||
y1=y+(y+1<h);
|
||||
for(x = 0; x < w; x += 2) {
|
||||
x1=x+(x+1<w);
|
||||
png_byte r0 = png[y][3 * x + 0];
|
||||
png_byte g0 = png[y][3 * x + 1];
|
||||
png_byte b0 = png[y][3 * x + 2];
|
||||
png_byte r1 = png[y][3 * x1 + 0];
|
||||
png_byte g1 = png[y][3 * x1 + 1];
|
||||
png_byte b1 = png[y][3 * x1 + 2];
|
||||
png_byte r2 = png[y1][3 * x + 0];
|
||||
png_byte g2 = png[y1][3 * x + 1];
|
||||
png_byte b2 = png[y1][3 * x + 2];
|
||||
png_byte r3 = png[y1][3 * x1 + 0];
|
||||
png_byte g3 = png[y1][3 * x1 + 1];
|
||||
png_byte b3 = png[y1][3 * x1 + 2];
|
||||
|
||||
yuv_y[x + y * yuv_w] = clamp((65481*r0+128553*g0+24966*b0+4207500)/255000);
|
||||
yuv_y[x1 + y * yuv_w] = clamp((65481*r1+128553*g1+24966*b1+4207500)/255000);
|
||||
yuv_y[x + y1 * yuv_w] = clamp((65481*r2+128553*g2+24966*b2+4207500)/255000);
|
||||
yuv_y[x1 + y1 * yuv_w] = clamp((65481*r3+128553*g3+24966*b3+4207500)/255000);
|
||||
|
||||
yuv_u[(x >> 1) + (y >> 1) * ycbcr[1].stride] =
|
||||
clamp( ((-33488*r0-65744*g0+99232*b0+29032005)/4 +
|
||||
(-33488*r0-65744*g0+99232*b0+29032005)/4 +
|
||||
(-33488*r2-65744*g2+99232*b2+29032005)/4 +
|
||||
(-33488*r3-65744*g3+99232*b3+29032005)/4)/225930);
|
||||
yuv_v[(x >> 1) + (y >> 1) * ycbcr[2].stride] =
|
||||
clamp( ((157024*r0-131488*g0-25536*b0+45940035)/4 +
|
||||
(157024*r1-131488*g1-25536*b1+45940035)/4 +
|
||||
(157024*r2-131488*g2-25536*b2+45940035)/4 +
|
||||
(157024*r3-131488*g3-25536*b3+45940035)/4)/357510);
|
||||
}
|
||||
}
|
||||
} else if (chroma_format == TH_PF_444) {
|
||||
for(y = 0; y < h; y++) {
|
||||
for(x = 0; x < w; x++) {
|
||||
png_byte r = png[y][3 * x + 0];
|
||||
png_byte g = png[y][3 * x + 1];
|
||||
png_byte b = png[y][3 * x + 2];
|
||||
|
||||
yuv_y[x + y * yuv_w] = clamp((65481*r+128553*g+24966*b+4207500)/255000);
|
||||
yuv_u[x + y * yuv_w] = clamp((-33488*r-65744*g+99232*b+29032005)/225930);
|
||||
yuv_v[x + y * yuv_w] = clamp((157024*r-131488*g-25536*b+45940035)/357510);
|
||||
}
|
||||
}
|
||||
} else { /* TH_PF_422 */
|
||||
for(y = 0; y < h; y += 1) {
|
||||
for(x = 0; x < w; x += 2) {
|
||||
x1=x+(x+1<w);
|
||||
png_byte r0 = png[y][3 * x + 0];
|
||||
png_byte g0 = png[y][3 * x + 1];
|
||||
png_byte b0 = png[y][3 * x + 2];
|
||||
png_byte r1 = png[y][3 * x1 + 0];
|
||||
png_byte g1 = png[y][3 * x1 + 1];
|
||||
png_byte b1 = png[y][3 * x1 + 2];
|
||||
|
||||
yuv_y[x + y * yuv_w] = clamp((65481*r0+128553*g0+24966*b0+4207500)/255000);
|
||||
yuv_y[x1 + y * yuv_w] = clamp((65481*r1+128553*g1+24966*b1+4207500)/255000);
|
||||
|
||||
yuv_u[(x >> 1) + y * ycbcr[1].stride] =
|
||||
clamp( ((-33488*r0-65744*g0+99232*b0+29032005)/2 +
|
||||
(-33488*r1-65744*g1+99232*b1+29032005)/2)/225930);
|
||||
yuv_v[(x >> 1) + y * ycbcr[2].stride] =
|
||||
clamp( ((157024*r0-131488*g0-25536*b0+45940035)/2 +
|
||||
(157024*r1-131488*g1-25536*b1+45940035)/2)/357510);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
png_read(const char *pathname, unsigned int *w, unsigned int *h, th_ycbcr_buffer ycbcr)
|
||||
{
|
||||
FILE *fp;
|
||||
unsigned char header[8];
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_infop end_ptr;
|
||||
png_bytep row_data;
|
||||
png_bytep *row_pointers;
|
||||
png_color_16p bkgd;
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
unsigned long yuv_w;
|
||||
unsigned long yuv_h;
|
||||
int bit_depth;
|
||||
int color_type;
|
||||
int interlace_type;
|
||||
int compression_type;
|
||||
int filter_method;
|
||||
png_uint_32 y;
|
||||
|
||||
fp = fopen(pathname, "rb");
|
||||
if(!fp) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
pathname, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
fread(header, 1, 8, fp);
|
||||
if(png_sig_cmp(header, 0, 8)) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
pathname, "not a PNG");
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL);
|
||||
if(!png_ptr) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
pathname, "couldn't create png read structure");
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if(!info_ptr) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
pathname, "couldn't create png info structure");
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
end_ptr = png_create_info_struct(png_ptr);
|
||||
if(!end_ptr) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
pathname, "couldn't create png info structure");
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
&interlace_type, &compression_type, &filter_method);
|
||||
png_set_expand(png_ptr);
|
||||
if(bit_depth<8)png_set_packing(png_ptr);
|
||||
if(bit_depth==16)png_set_strip_16(png_ptr);
|
||||
if(!(color_type&PNG_COLOR_MASK_COLOR))png_set_gray_to_rgb(png_ptr);
|
||||
if(png_get_bKGD(png_ptr, info_ptr, &bkgd)){
|
||||
png_set_background(png_ptr, bkgd, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||
}
|
||||
/*Note that color_type 2 and 3 can also have alpha, despite not setting the
|
||||
PNG_COLOR_MASK_ALPHA bit.
|
||||
We always strip it to prevent libpng from overrunning our buffer.*/
|
||||
png_set_strip_alpha(png_ptr);
|
||||
|
||||
row_data = (png_bytep)png_malloc(png_ptr,
|
||||
3*height*width*png_sizeof(*row_data));
|
||||
row_pointers = (png_bytep *)png_malloc(png_ptr,
|
||||
height*png_sizeof(*row_pointers));
|
||||
for(y = 0; y < height; y++) {
|
||||
row_pointers[y] = row_data + y*(3*width);
|
||||
}
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
png_read_end(png_ptr, end_ptr);
|
||||
|
||||
*w = width;
|
||||
*h = height;
|
||||
/* Must hold: yuv_w >= w */
|
||||
yuv_w = (*w + 15) & ~15;
|
||||
/* Must hold: yuv_h >= h */
|
||||
yuv_h = (*h + 15) & ~15;
|
||||
|
||||
/* Do we need to allocate a buffer */
|
||||
if (!ycbcr[0].data){
|
||||
ycbcr[0].width = yuv_w;
|
||||
ycbcr[0].height = yuv_h;
|
||||
ycbcr[0].stride = yuv_w;
|
||||
ycbcr[1].width = (chroma_format == TH_PF_444) ? yuv_w : (yuv_w >> 1);
|
||||
ycbcr[1].stride = ycbcr[1].width;
|
||||
ycbcr[1].height = (chroma_format == TH_PF_420) ? (yuv_h >> 1) : yuv_h;
|
||||
ycbcr[2].width = ycbcr[1].width;
|
||||
ycbcr[2].stride = ycbcr[1].stride;
|
||||
ycbcr[2].height = ycbcr[1].height;
|
||||
|
||||
ycbcr[0].data = malloc(ycbcr[0].stride * ycbcr[0].height);
|
||||
ycbcr[1].data = malloc(ycbcr[1].stride * ycbcr[1].height);
|
||||
ycbcr[2].data = malloc(ycbcr[2].stride * ycbcr[2].height);
|
||||
} else {
|
||||
if ((ycbcr[0].width != yuv_w) || (ycbcr[0].height != yuv_h)){
|
||||
fprintf(stderr, "Input size %lux%lu does not match %dx%d\n", yuv_w,yuv_h,ycbcr[0].width,ycbcr[0].height);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rgb_to_yuv(row_pointers, ycbcr, *w, *h);
|
||||
|
||||
png_free(png_ptr, row_pointers);
|
||||
png_free(png_ptr, row_data);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr);
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int include_files (const struct dirent *de)
|
||||
{
|
||||
char name[1024];
|
||||
int number = -1;
|
||||
sscanf(de->d_name, input_filter, &number);
|
||||
sprintf(name, input_filter, number);
|
||||
return !strcmp(name, de->d_name);
|
||||
}
|
||||
|
||||
static int ilog(unsigned _v){
|
||||
int ret;
|
||||
for(ret=0;_v;ret++)_v>>=1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c,long_option_index;
|
||||
int i, n;
|
||||
char *input_mask;
|
||||
char *input_directory;
|
||||
char *scratch;
|
||||
th_comment tc;
|
||||
struct dirent **png_files;
|
||||
int soft_target=0;
|
||||
int ret;
|
||||
|
||||
while(1) {
|
||||
|
||||
c=getopt_long(argc,argv,optstring,options,&long_option_index);
|
||||
if(c == EOF)
|
||||
break;
|
||||
|
||||
switch(c) {
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
case 'o':
|
||||
option_output = optarg;
|
||||
break;;
|
||||
case 'v':
|
||||
video_quality=rint(atof(optarg)*6.3);
|
||||
if(video_quality<0 || video_quality>63){
|
||||
fprintf(stderr,"Illegal video quality (choose 0 through 10)\n");
|
||||
exit(1);
|
||||
}
|
||||
video_rate=0;
|
||||
break;
|
||||
case 'V':
|
||||
video_rate=rint(atof(optarg)*1000);
|
||||
if(video_rate<1){
|
||||
fprintf(stderr,"Illegal video bitrate (choose > 0 please)\n");
|
||||
exit(1);
|
||||
}
|
||||
video_quality=0;
|
||||
break;
|
||||
case '\1':
|
||||
soft_target=1;
|
||||
break;
|
||||
case 'c':
|
||||
vp3_compatible=1;
|
||||
break;
|
||||
case 'k':
|
||||
keyframe_frequency=rint(atof(optarg));
|
||||
if(keyframe_frequency<1 || keyframe_frequency>2147483647){
|
||||
fprintf(stderr,"Illegal keyframe frequency\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
buf_delay=atoi(optarg);
|
||||
if(buf_delay<=0){
|
||||
fprintf(stderr,"Illegal buffer delay\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
video_aspect_numerator=rint(atof(optarg));
|
||||
break;
|
||||
case 'S':
|
||||
video_aspect_denominator=rint(atof(optarg));
|
||||
break;
|
||||
case 'f':
|
||||
video_fps_numerator=rint(atof(optarg));
|
||||
break;
|
||||
case 'F':
|
||||
video_fps_denominator=rint(atof(optarg));
|
||||
break;
|
||||
case '\5':
|
||||
chroma_format=TH_PF_444;
|
||||
break;
|
||||
case '\6':
|
||||
chroma_format=TH_PF_422;
|
||||
break;
|
||||
case '\2':
|
||||
twopass=3; /* perform both passes */
|
||||
twopass_file=tmpfile();
|
||||
if(!twopass_file){
|
||||
fprintf(stderr,"Unable to open temporary file for twopass data\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '\3':
|
||||
twopass=1; /* perform first pass */
|
||||
twopass_file=fopen(optarg,"wb");
|
||||
if(!twopass_file){
|
||||
fprintf(stderr,"Unable to open \'%s\' for twopass data\n",optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '\4':
|
||||
twopass=2; /* perform second pass */
|
||||
twopass_file=fopen(optarg,"rb");
|
||||
if(!twopass_file){
|
||||
fprintf(stderr,"Unable to open twopass data file \'%s\'",optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc < 3) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if(soft_target){
|
||||
if(video_rate<=0){
|
||||
fprintf(stderr,"Soft rate target (--soft-target) requested without a bitrate (-V).\n");
|
||||
exit(1);
|
||||
}
|
||||
if(video_quality==-1)
|
||||
video_quality=0;
|
||||
}else{
|
||||
if(video_rate>0)
|
||||
video_quality=0;
|
||||
if(video_quality==-1)
|
||||
video_quality=48;
|
||||
}
|
||||
|
||||
if(keyframe_frequency<=0){
|
||||
/*Use a default keyframe frequency of 64 for 1-pass (streaming) mode, and
|
||||
256 for two-pass mode.*/
|
||||
keyframe_frequency=twopass?256:64;
|
||||
}
|
||||
|
||||
input_mask = argv[optind];
|
||||
if (!input_mask) {
|
||||
fprintf(stderr, "no input files specified; run with -h for help.\n");
|
||||
exit(1);
|
||||
}
|
||||
/* dirname and basename must operate on scratch strings */
|
||||
scratch = strdup(input_mask);
|
||||
input_directory = strdup(dirname(scratch));
|
||||
free(scratch);
|
||||
scratch = strdup(input_mask);
|
||||
input_filter = strdup(basename(scratch));
|
||||
free(scratch);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "scanning %s with filter '%s'\n",
|
||||
input_directory, input_filter);
|
||||
#endif
|
||||
n = scandir (input_directory, &png_files, include_files, alphasort);
|
||||
|
||||
if (!n) {
|
||||
fprintf(stderr, "no input files found; run with -h for help.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ogg_fp = fopen(option_output, "wb");
|
||||
if(!ogg_fp) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
option_output, "couldn't open output file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
if(ogg_stream_init(&ogg_os, rand())) {
|
||||
fprintf(stderr, "%s: error: %s\n",
|
||||
option_output, "couldn't create ogg stream state");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(passno=(twopass==3?1:twopass);passno<=(twopass==3?2:twopass);passno++){
|
||||
unsigned int w;
|
||||
unsigned int h;
|
||||
char input_png[1024];
|
||||
th_ycbcr_buffer ycbcr;
|
||||
|
||||
ycbcr[0].data = 0;
|
||||
int last = 0;
|
||||
|
||||
snprintf(input_png, 1023,"%s/%s", input_directory, png_files[0]->d_name);
|
||||
if(png_read(input_png, &w, &h, ycbcr)) {
|
||||
fprintf(stderr, "could not read %s\n", input_png);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (passno!=2) fprintf(stderr,"%d frames, %dx%d\n",n,w,h);
|
||||
|
||||
/* setup complete. Raw processing loop */
|
||||
switch(passno){
|
||||
case 0: case 2:
|
||||
fprintf(stderr,"\rCompressing.... \n");
|
||||
break;
|
||||
case 1:
|
||||
fprintf(stderr,"\rScanning first pass.... \n");
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", input_png);
|
||||
|
||||
th_info_init(&ti);
|
||||
ti.frame_width = ((w + 15) >>4)<<4;
|
||||
ti.frame_height = ((h + 15)>>4)<<4;
|
||||
ti.pic_width = w;
|
||||
ti.pic_height = h;
|
||||
ti.pic_x = 0;
|
||||
ti.pic_y = 0;
|
||||
ti.fps_numerator = video_fps_numerator;
|
||||
ti.fps_denominator = video_fps_denominator;
|
||||
ti.aspect_numerator = video_aspect_numerator;
|
||||
ti.aspect_denominator = video_aspect_denominator;
|
||||
ti.colorspace = TH_CS_UNSPECIFIED;
|
||||
ti.pixel_fmt = chroma_format;
|
||||
ti.target_bitrate = video_rate;
|
||||
ti.quality = video_quality;
|
||||
ti.keyframe_granule_shift=ilog(keyframe_frequency-1);
|
||||
|
||||
td=th_encode_alloc(&ti);
|
||||
th_info_clear(&ti);
|
||||
/* setting just the granule shift only allows power-of-two keyframe
|
||||
spacing. Set the actual requested spacing. */
|
||||
ret=th_encode_ctl(td,TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
|
||||
&keyframe_frequency,sizeof(keyframe_frequency-1));
|
||||
if(ret<0){
|
||||
fprintf(stderr,"Could not set keyframe interval to %d.\n",(int)keyframe_frequency);
|
||||
}
|
||||
if(vp3_compatible){
|
||||
ret=th_encode_ctl(td,TH_ENCCTL_SET_VP3_COMPATIBLE,&vp3_compatible,
|
||||
sizeof(vp3_compatible));
|
||||
if(ret<0||!vp3_compatible){
|
||||
fprintf(stderr,"Could not enable strict VP3 compatibility.\n");
|
||||
if(ret>=0){
|
||||
fprintf(stderr,"Ensure your source format is supported by VP3.\n");
|
||||
fprintf(stderr,
|
||||
"(4:2:0 pixel format, width and height multiples of 16).\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(soft_target){
|
||||
/* reverse the rate control flags to favor a 'long time' strategy */
|
||||
int arg = TH_RATECTL_CAP_UNDERFLOW;
|
||||
ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_FLAGS,&arg,sizeof(arg));
|
||||
if(ret<0)
|
||||
fprintf(stderr,"Could not set encoder flags for --soft-target\n");
|
||||
/* Default buffer control is overridden on two-pass */
|
||||
if(!twopass&&buf_delay<0){
|
||||
if((keyframe_frequency*7>>1) > 5*video_fps_numerator/video_fps_denominator)
|
||||
arg=keyframe_frequency*7>>1;
|
||||
else
|
||||
arg=5*video_fps_numerator/video_fps_denominator;
|
||||
ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,&arg,sizeof(arg));
|
||||
if(ret<0)
|
||||
fprintf(stderr,"Could not set rate control buffer for --soft-target\n");
|
||||
}
|
||||
}
|
||||
/* set up two-pass if needed */
|
||||
if(passno==1){
|
||||
unsigned char *buffer;
|
||||
int bytes;
|
||||
bytes=th_encode_ctl(td,TH_ENCCTL_2PASS_OUT,&buffer,sizeof(buffer));
|
||||
if(bytes<0){
|
||||
fprintf(stderr,"Could not set up the first pass of two-pass mode.\n");
|
||||
fprintf(stderr,"Did you remember to specify an estimated bitrate?\n");
|
||||
exit(1);
|
||||
}
|
||||
/*Perform a seek test to ensure we can overwrite this placeholder data at
|
||||
the end; this is better than letting the user sit through a whole
|
||||
encode only to find out their pass 1 file is useless at the end.*/
|
||||
if(fseek(twopass_file,0,SEEK_SET)<0){
|
||||
fprintf(stderr,"Unable to seek in two-pass data file.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(fwrite(buffer,1,bytes,twopass_file)<bytes){
|
||||
fprintf(stderr,"Unable to write to two-pass data file.\n");
|
||||
exit(1);
|
||||
}
|
||||
fflush(twopass_file);
|
||||
}
|
||||
if(passno==2){
|
||||
/*Enable the second pass here.
|
||||
We make this call just to set the encoder into 2-pass mode, because
|
||||
by default enabling two-pass sets the buffer delay to the whole file
|
||||
(because there's no way to explicitly request that behavior).
|
||||
If we waited until we were actually encoding, it would overwite our
|
||||
settings.*/
|
||||
if(th_encode_ctl(td,TH_ENCCTL_2PASS_IN,NULL,0)<0){
|
||||
fprintf(stderr,"Could not set up the second pass of two-pass mode.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(twopass==3){
|
||||
if(fseek(twopass_file,0,SEEK_SET)<0){
|
||||
fprintf(stderr,"Unable to seek in two-pass data file.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Now we can set the buffer delay if the user requested a non-default one
|
||||
(this has to be done after two-pass is enabled).*/
|
||||
if(passno!=1&&buf_delay>=0){
|
||||
ret=th_encode_ctl(td,TH_ENCCTL_SET_RATE_BUFFER,
|
||||
&buf_delay,sizeof(buf_delay));
|
||||
if(ret<0){
|
||||
fprintf(stderr,"Warning: could not set desired buffer delay.\n");
|
||||
}
|
||||
}
|
||||
/* write the bitstream header packets with proper page interleave */
|
||||
th_comment_init(&tc);
|
||||
/* first packet will get its own page automatically */
|
||||
if(th_encode_flushheader(td,&tc,&op)<=0){
|
||||
fprintf(stderr,"Internal Theora library error.\n");
|
||||
exit(1);
|
||||
}
|
||||
th_comment_clear(&tc);
|
||||
if(passno!=1){
|
||||
ogg_stream_packetin(&ogg_os,&op);
|
||||
if(ogg_stream_pageout(&ogg_os,&og)!=1){
|
||||
fprintf(stderr,"Internal Ogg library error.\n");
|
||||
exit(1);
|
||||
}
|
||||
fwrite(og.header,1,og.header_len,ogg_fp);
|
||||
fwrite(og.body,1,og.body_len,ogg_fp);
|
||||
}
|
||||
/* create the remaining theora headers */
|
||||
for(;;){
|
||||
ret=th_encode_flushheader(td,&tc,&op);
|
||||
if(ret<0){
|
||||
fprintf(stderr,"Internal Theora library error.\n");
|
||||
exit(1);
|
||||
}
|
||||
else if(!ret)break;
|
||||
if(passno!=1)ogg_stream_packetin(&ogg_os,&op);
|
||||
}
|
||||
/* Flush the rest of our headers. This ensures
|
||||
the actual data in each stream will start
|
||||
on a new page, as per spec. */
|
||||
if(passno!=1){
|
||||
for(;;){
|
||||
int result = ogg_stream_flush(&ogg_os,&og);
|
||||
if(result<0){
|
||||
/* can't get here */
|
||||
fprintf(stderr,"Internal Ogg library error.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(result==0)break;
|
||||
fwrite(og.header,1,og.header_len,ogg_fp);
|
||||
fwrite(og.body,1,og.body_len,ogg_fp);
|
||||
}
|
||||
}
|
||||
|
||||
i=0; last=0;
|
||||
do {
|
||||
if(i >= n-1) last = 1;
|
||||
if(theora_write_frame(ycbcr, last)) {
|
||||
fprintf(stderr,"Encoding error.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
i++;
|
||||
if (!last) {
|
||||
snprintf(input_png, 1023,"%s/%s", input_directory, png_files[i]->d_name);
|
||||
if(png_read(input_png, &w, &h, ycbcr)) {
|
||||
fprintf(stderr, "could not read %s\n", input_png);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "%s\n", input_png);
|
||||
}
|
||||
} while (!last);
|
||||
|
||||
if(passno==1){
|
||||
/* need to read the final (summary) packet */
|
||||
unsigned char *buffer;
|
||||
int bytes = th_encode_ctl(td, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
|
||||
if(bytes<0){
|
||||
fprintf(stderr,"Could not read two-pass summary data from encoder.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(fseek(twopass_file,0,SEEK_SET)<0){
|
||||
fprintf(stderr,"Unable to seek in two-pass data file.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(fwrite(buffer,1,bytes,twopass_file)<bytes){
|
||||
fprintf(stderr,"Unable to write to two-pass data file.\n");
|
||||
exit(1);
|
||||
}
|
||||
fflush(twopass_file);
|
||||
}
|
||||
th_encode_free(td);
|
||||
free(ycbcr[0].data);
|
||||
free(ycbcr[1].data);
|
||||
free(ycbcr[2].data);
|
||||
}
|
||||
|
||||
if(ogg_stream_flush(&ogg_os, &og)) {
|
||||
fwrite(og.header, og.header_len, 1, ogg_fp);
|
||||
fwrite(og.body, og.body_len, 1, ogg_fp);
|
||||
}
|
||||
|
||||
free(input_directory);
|
||||
free(input_filter);
|
||||
|
||||
while (n--) free(png_files[n]);
|
||||
free(png_files);
|
||||
|
||||
if(ogg_fp){
|
||||
fflush(ogg_fp);
|
||||
if(ogg_fp!=stdout)fclose(ogg_fp);
|
||||
}
|
||||
|
||||
ogg_stream_clear(&ogg_os);
|
||||
if(twopass_file)fclose(twopass_file);
|
||||
fprintf(stderr,"\r \ndone.\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = theora
|
||||
@@ -0,0 +1,7 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
theoraincludedir = $(includedir)/theora
|
||||
|
||||
theorainclude_HEADERS = theora.h theoradec.h theoraenc.h codec.h
|
||||
|
||||
noinst_HEADERS = codec.h theoradec.h
|
||||
@@ -0,0 +1,591 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* 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 with 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.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.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.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).
|
||||
The Cb and Cr chroma planes are half the width and half the
|
||||
height of the luma plane.*/
|
||||
TH_PF_420,
|
||||
/**Currently reserved.*/
|
||||
TH_PF_RSVD,
|
||||
/**Chroma decimation by 2 in the X direction (4:2:2).
|
||||
The Cb and Cr chroma planes are half the width of the luma plane, but full
|
||||
height.*/
|
||||
TH_PF_422,
|
||||
/**No chroma decimation (4:4:4).
|
||||
The Cb and Cr chroma planes are full width and full height.*/
|
||||
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.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.*/
|
||||
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.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
|
||||
@@ -0,0 +1,784 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* 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>
|
||||
|
||||
/** \file
|
||||
* The libtheora pre-1.0 legacy C API.
|
||||
*
|
||||
* \ingroup oldfuncs
|
||||
*
|
||||
* \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 with
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/** \defgroup oldfuncs Legacy pre-1.0 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_old
|
||||
* These are the available request codes for theora_control()
|
||||
* when called with a decoder instance.
|
||||
* By convention decoder control codes are odd, to distinguish
|
||||
* them from \ref encctlcodes_old "encoder control codes" which
|
||||
* are even.
|
||||
*
|
||||
* Note that since the 1.0 release, both the legacy and the final
|
||||
* implementation accept all the same control codes, but only the
|
||||
* final API declares the newer 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)
|
||||
|
||||
/**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 OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>.
|
||||
* \retval OC_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
|
||||
* \retval OC_IMPL Not supported by this implementation.*/
|
||||
#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
|
||||
|
||||
/**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_old */
|
||||
|
||||
/**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.
|
||||
*
|
||||
* \param[in] buf #th_quant_info
|
||||
* \retval OC_FAULT \a theora_state is <tt>NULL</tt>.
|
||||
* \retval OC_EINVAL Encoding has already begun, the quantization parameters
|
||||
* are not acceptable to this version of the encoder,
|
||||
* \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 OC_IMPL Not supported by this implementation.*/
|
||||
#define TH_ENCCTL_SET_QUANT_PARAMS (2)
|
||||
|
||||
/**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 OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>.
|
||||
* \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
|
||||
* \retval OC_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 OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>.
|
||||
* \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
|
||||
* \retval OC_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 OC_FAULT \a theora_state or \a buf is <tt>NULL</tt>.
|
||||
* \retval OC_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 OC_IMPL Not supported by this implementation in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_SET_SPLEVEL (14)
|
||||
|
||||
/*@}*/
|
||||
|
||||
#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_old "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_ */
|
||||
@@ -0,0 +1,325 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* 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 <stddef.h>
|
||||
# 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.
|
||||
* 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.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \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)
|
||||
|
||||
/**Enables telemetry and sets the macroblock display mode */
|
||||
#define TH_DECCTL_SET_TELEMETRY_MBMODE (9)
|
||||
/**Enables telemetry and sets the motion vector display mode */
|
||||
#define TH_DECCTL_SET_TELEMETRY_MV (11)
|
||||
/**Enables telemetry and sets the adaptive quantization display mode */
|
||||
#define TH_DECCTL_SET_TELEMETRY_QI (13)
|
||||
/**Enables telemetry and sets the bitstream breakdown visualization mode */
|
||||
#define TH_DECCTL_SET_TELEMETRY_BITS (15)
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
/**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.
|
||||
*
|
||||
* <b>Security Warning:</b> The Theora format supports very large frame sizes,
|
||||
* potentially even larger than the address space of a 32-bit machine, and
|
||||
* creating a decoder context allocates the space for several frames of data.
|
||||
* If the allocation fails here, your program will crash, possibly at some
|
||||
* future point because the OS kernel returned a valid memory range and will
|
||||
* only fail when it tries to map the pages in it the first time they are
|
||||
* used.
|
||||
* Even if it succeeds, you may experience a denial of service if the frame
|
||||
* size is large enough to cause excessive paging.
|
||||
* If you are integrating libtheora in a larger application where such things
|
||||
* are undesirable, it is highly recommended that you check the frame size in
|
||||
* \a _info before calling this function and refuse to decode streams where it
|
||||
* is larger than some reasonable maximum.
|
||||
* libtheora will not check this for you, because there may be machines that
|
||||
* can handle such streams and applications that wish to.
|
||||
* \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 \a _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
|
||||
* \retval TH_EFAULT \a _dec or \a _ycbcr was <tt>NULL</tt>.
|
||||
*/
|
||||
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
|
||||
@@ -0,0 +1,500 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* 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>libtheoraenc</tt> C encoding API.*/
|
||||
|
||||
#if !defined(_O_THEORA_THEORAENC_H_)
|
||||
# define _O_THEORA_THEORAENC_H_ (1)
|
||||
# include <stddef.h>
|
||||
# include <ogg/ogg.h>
|
||||
# include "codec.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**\name th_encode_ctl() codes
|
||||
* \anchor encctlcodes
|
||||
* These are the available request codes for th_encode_ctl().
|
||||
* 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_EFAULT \a _enc_ctx 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_EIMPL 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.
|
||||
*
|
||||
* \param[in] _buf #th_quant_info
|
||||
* \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL Encoding has already begun, \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_EIMPL 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_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
|
||||
* \retval TH_EIMPL 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-adaptive quantization and always coding
|
||||
* all four luma blocks in a macro block when 4MV is used.
|
||||
* 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_EFAULT \a _enc_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_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. constant quality, etc.).
|
||||
*
|
||||
* \param[out] _buf <tt>int</tt>: The maximum encoding speed level.
|
||||
* \retval TH_EFAULT \a _enc_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 in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_GET_SPLEVEL_MAX (12)
|
||||
/**Sets the speed level.
|
||||
* The current speed level may be retrieved using #TH_ENCCTL_GET_SPLEVEL.
|
||||
*
|
||||
* \param[in] _buf <tt>int</tt>: The new encoding speed level.
|
||||
* 0 is slowest, larger values use less CPU.
|
||||
* \retval TH_EFAULT \a _enc_ctx 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_EIMPL Not supported by this implementation in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_SET_SPLEVEL (14)
|
||||
/**Gets the current speed level.
|
||||
* The default speed level may vary according to encoder implementation, but if
|
||||
* this control code is not supported (it returns #TH_EIMPL), the default may
|
||||
* be assumed to be the slowest available speed (0).
|
||||
* The maximum encoding speed level may be implementation- and encoding
|
||||
* mode-specific, and can be obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
|
||||
*
|
||||
* \param[out] _buf <tt>int</tt>: The current encoding speed level.
|
||||
* 0 is slowest, larger values use less CPU.
|
||||
* \retval TH_EFAULT \a _enc_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 in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_GET_SPLEVEL (16)
|
||||
/**Sets the number of duplicates of the next frame to produce.
|
||||
* Although libtheora can encode duplicate frames very cheaply, it costs some
|
||||
* amount of CPU to detect them, and a run of duplicates cannot span a
|
||||
* keyframe boundary.
|
||||
* This control code tells the encoder to produce the specified number of extra
|
||||
* duplicates of the next frame.
|
||||
* This allows the encoder to make smarter keyframe placement decisions and
|
||||
* rate control decisions, and reduces CPU usage as well, when compared to
|
||||
* just submitting the same frame for encoding multiple times.
|
||||
* This setting only applies to the next frame submitted for encoding.
|
||||
* You MUST call th_encode_packetout() repeatedly until it returns 0, or the
|
||||
* extra duplicate frames will be lost.
|
||||
*
|
||||
* \param[in] _buf <tt>int</tt>: The number of duplicates to produce.
|
||||
* If this is negative or zero, no duplicates will be produced.
|
||||
* \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the
|
||||
* number of duplicates is greater than or equal to the
|
||||
* maximum keyframe interval.
|
||||
* In the latter case, NO duplicate frames will be produced.
|
||||
* You must ensure that the maximum keyframe interval is set
|
||||
* larger than the maximum number of duplicates you will
|
||||
* ever wish to insert prior to encoding.
|
||||
* \retval TH_EIMPL Not supported by this implementation in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_SET_DUP_COUNT (18)
|
||||
/**Modifies the default bitrate management behavior.
|
||||
* Use to allow or disallow frame dropping, and to enable or disable capping
|
||||
* bit reservoir overflows and underflows.
|
||||
* See \ref encctlcodes "the list of available flags".
|
||||
* The flags are set by default to
|
||||
* <tt>#TH_RATECTL_DROP_FRAMES|#TH_RATECTL_CAP_OVERFLOW</tt>.
|
||||
*
|
||||
* \param[in] _buf <tt>int</tt>: Any combination of
|
||||
* \ref ratectlflags "the available flags":
|
||||
* - #TH_RATECTL_DROP_FRAMES: Enable frame dropping.
|
||||
* - #TH_RATECTL_CAP_OVERFLOW: Don't bank excess bits for later
|
||||
* use.
|
||||
* - #TH_RATECTL_CAP_UNDERFLOW: Don't try to make up shortfalls
|
||||
* later.
|
||||
* \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt> or rate control
|
||||
* is not enabled.
|
||||
* \retval TH_EIMPL Not supported by this implementation in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_SET_RATE_FLAGS (20)
|
||||
/**Sets the size of the bitrate management bit reservoir as a function
|
||||
* of number of frames.
|
||||
* The reservoir size affects how quickly bitrate management reacts to
|
||||
* instantaneous changes in the video complexity.
|
||||
* Larger reservoirs react more slowly, and provide better overall quality, but
|
||||
* require more buffering by a client, adding more latency to live streams.
|
||||
* By default, libtheora sets the reservoir to the maximum distance between
|
||||
* keyframes, subject to a minimum and maximum limit.
|
||||
* This call may be used to increase or decrease the reservoir, increasing or
|
||||
* decreasing the allowed temporary variance in bitrate.
|
||||
* An implementation may impose some limits on the size of a reservoir it can
|
||||
* handle, in which case the actual reservoir size may not be exactly what was
|
||||
* requested.
|
||||
* The actual value set will be returned.
|
||||
*
|
||||
* \param[in] _buf <tt>int</tt>: Requested size of the reservoir measured in
|
||||
* frames.
|
||||
* \param[out] _buf <tt>int</tt>: The actual size of the reservoir set.
|
||||
* \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or rate control
|
||||
* is not enabled. The buffer has an implementation
|
||||
* defined minimum and maximum size and the value in _buf
|
||||
* will be adjusted to match the actual value set.
|
||||
* \retval TH_EIMPL Not supported by this implementation in the current
|
||||
* encoding mode.*/
|
||||
#define TH_ENCCTL_SET_RATE_BUFFER (22)
|
||||
/**Enable pass 1 of two-pass encoding mode and retrieve the first pass metrics.
|
||||
* Pass 1 mode must be enabled before the first frame is encoded, and a target
|
||||
* bitrate must have already been specified to the encoder.
|
||||
* Although this does not have to be the exact rate that will be used in the
|
||||
* second pass, closer values may produce better results.
|
||||
* The first call returns the size of the two-pass header data, along with some
|
||||
* placeholder content, and sets the encoder into pass 1 mode implicitly.
|
||||
* This call sets the encoder to pass 1 mode implicitly.
|
||||
* Then, a subsequent call must be made after each call to
|
||||
* th_encode_ycbcr_in() to retrieve the metrics for that frame.
|
||||
* An additional, final call must be made to retrieve the summary data,
|
||||
* containing such information as the total number of frames, etc.
|
||||
* This must be stored in place of the placeholder data that was returned
|
||||
* in the first call, before the frame metrics data.
|
||||
* All of this data must be presented back to the encoder during pass 2 using
|
||||
* #TH_ENCCTL_2PASS_IN.
|
||||
*
|
||||
* \param[out] <tt>char *</tt>_buf: Returns a pointer to internal storage
|
||||
* containing the two pass metrics data.
|
||||
* This storage is only valid until the next call, or until the
|
||||
* encoder context is freed, and must be copied by the
|
||||
* application.
|
||||
* \retval >=0 The number of bytes of metric data available in the
|
||||
* returned buffer.
|
||||
* \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(char *)</tt>, no target
|
||||
* bitrate has been set, or the first call was made after
|
||||
* the first frame was submitted for encoding.
|
||||
* \retval TH_EIMPL Not supported by this implementation.*/
|
||||
#define TH_ENCCTL_2PASS_OUT (24)
|
||||
/**Submits two-pass encoding metric data collected the first encoding pass to
|
||||
* the second pass.
|
||||
* The first call must be made before the first frame is encoded, and a target
|
||||
* bitrate must have already been specified to the encoder.
|
||||
* It sets the encoder to pass 2 mode implicitly; this cannot be disabled.
|
||||
* The encoder may require reading data from some or all of the frames in
|
||||
* advance, depending on, e.g., the reservoir size used in the second pass.
|
||||
* You must call this function repeatedly before each frame to provide data
|
||||
* until either a) it fails to consume all of the data presented or b) all of
|
||||
* the pass 1 data has been consumed.
|
||||
* In the first case, you must save the remaining data to be presented after
|
||||
* the next frame.
|
||||
* You can call this function with a NULL argument to get an upper bound on
|
||||
* the number of bytes that will be required before the next frame.
|
||||
*
|
||||
* When pass 2 is first enabled, the default bit reservoir is set to the entire
|
||||
* file; this gives maximum flexibility but can lead to very high peak rates.
|
||||
* You can subsequently set it to another value with #TH_ENCCTL_SET_RATE_BUFFER
|
||||
* (e.g., to set it to the keyframe interval for non-live streaming), however,
|
||||
* you may then need to provide more data before the next frame.
|
||||
*
|
||||
* \param[in] _buf <tt>char[]</tt>: A buffer containing the data returned by
|
||||
* #TH_ENCCTL_2PASS_OUT in pass 1.
|
||||
* You may pass <tt>NULL</tt> for \a _buf to return an upper
|
||||
* bound on the number of additional bytes needed before the
|
||||
* next frame.
|
||||
* The summary data returned at the end of pass 1 must be at
|
||||
* the head of the buffer on the first call with a
|
||||
* non-<tt>NULL</tt> \a _buf, and the placeholder data
|
||||
* returned at the start of pass 1 should be omitted.
|
||||
* After each call you should advance this buffer by the number
|
||||
* of bytes consumed.
|
||||
* \retval >0 The number of bytes of metric data required/consumed.
|
||||
* \retval 0 No more data is required before the next frame.
|
||||
* \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL No target bitrate has been set, or the first call was
|
||||
* made after the first frame was submitted for
|
||||
* encoding.
|
||||
* \retval TH_ENOTFORMAT The data did not appear to be pass 1 from a compatible
|
||||
* implementation of this library.
|
||||
* \retval TH_EBADHEADER The data was invalid; this may be returned when
|
||||
* attempting to read an aborted pass 1 file that still
|
||||
* has the placeholder data in place of the summary
|
||||
* data.
|
||||
* \retval TH_EIMPL Not supported by this implementation.*/
|
||||
#define TH_ENCCTL_2PASS_IN (26)
|
||||
/**Sets the current encoding quality.
|
||||
* This is only valid so long as no bitrate has been specified, either through
|
||||
* the #th_info struct used to initialize the encoder or through
|
||||
* #TH_ENCCTL_SET_BITRATE (this restriction may be relaxed in a future
|
||||
* version).
|
||||
* If it is set before the headers are emitted, the target quality encoded in
|
||||
* them will be updated.
|
||||
*
|
||||
* \param[in] _buf <tt>int</tt>: The new target quality, in the range 0...63,
|
||||
* inclusive.
|
||||
* \retval 0 Success.
|
||||
* \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL A target bitrate has already been specified, or the
|
||||
* quality index was not in the range 0...63.
|
||||
* \retval TH_EIMPL Not supported by this implementation.*/
|
||||
#define TH_ENCCTL_SET_QUALITY (28)
|
||||
/**Sets the current encoding bitrate.
|
||||
* Once a bitrate is set, the encoder must use a rate-controlled mode for all
|
||||
* future frames (this restriction may be relaxed in a future version).
|
||||
* If it is set before the headers are emitted, the target bitrate encoded in
|
||||
* them will be updated.
|
||||
* Due to the buffer delay, the exact bitrate of each section of the encode is
|
||||
* not guaranteed.
|
||||
* The encoder may have already used more bits than allowed for the frames it
|
||||
* has encoded, expecting to make them up in future frames, or it may have
|
||||
* used fewer, holding the excess in reserve.
|
||||
* The exact transition between the two bitrates is not well-defined by this
|
||||
* API, but may be affected by flags set with #TH_ENCCTL_SET_RATE_FLAGS.
|
||||
* After a number of frames equal to the buffer delay, one may expect further
|
||||
* output to average at the target bitrate.
|
||||
*
|
||||
* \param[in] _buf <tt>long</tt>: The new target bitrate, in bits per second.
|
||||
* \retval 0 Success.
|
||||
* \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL The target bitrate was not positive.
|
||||
* \retval TH_EIMPL Not supported by this implementation.*/
|
||||
#define TH_ENCCTL_SET_BITRATE (30)
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**\name TH_ENCCTL_SET_RATE_FLAGS flags
|
||||
* \anchor ratectlflags
|
||||
* These are the flags available for use with #TH_ENCCTL_SET_RATE_FLAGS.*/
|
||||
/*@{*/
|
||||
/**Drop frames to keep within bitrate buffer constraints.
|
||||
* This can have a severe impact on quality, but is the only way to ensure that
|
||||
* bitrate targets are met at low rates during sudden bursts of activity.*/
|
||||
#define TH_RATECTL_DROP_FRAMES (0x1)
|
||||
/**Ignore bitrate buffer overflows.
|
||||
* If the encoder uses so few bits that the reservoir of available bits
|
||||
* overflows, ignore the excess.
|
||||
* The encoder will not try to use these extra bits in future frames.
|
||||
* At high rates this may cause the result to be undersized, but allows a
|
||||
* client to play the stream using a finite buffer; it should normally be
|
||||
* enabled.*/
|
||||
#define TH_RATECTL_CAP_OVERFLOW (0x2)
|
||||
/**Ignore bitrate buffer underflows.
|
||||
* If the encoder uses so many bits that the reservoir of available bits
|
||||
* underflows, ignore the deficit.
|
||||
* The encoder will not try to make up these extra bits in future frames.
|
||||
* At low rates this may cause the result to be oversized; it should normally
|
||||
* be disabled.*/
|
||||
#define TH_RATECTL_CAP_UNDERFLOW (0x4)
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
/**The quantization parameters used by VP3.*/
|
||||
extern const th_quant_info TH_VP31_QUANT_INFO;
|
||||
|
||||
/**The Huffman tables used by VP3.*/
|
||||
extern const th_huff_code
|
||||
TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
|
||||
|
||||
|
||||
|
||||
/**\name Encoder state
|
||||
The following data structure is opaque, and its contents are not publicly
|
||||
defined by this API.
|
||||
Referring to its internals directly is unsupported, and may break without
|
||||
warning.*/
|
||||
/*@{*/
|
||||
/**The encoder context.*/
|
||||
typedef struct th_enc_ctx th_enc_ctx;
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
/**\defgroup encfuncs Functions for Encoding*/
|
||||
/*@{*/
|
||||
/**\name Functions for encoding
|
||||
* You must link to <tt>libtheoraenc</tt> and <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 encode.
|
||||
* The basic steps are:
|
||||
* - Fill in a #th_info structure with details on the format of the video you
|
||||
* wish to encode.
|
||||
* - Allocate a #th_enc_ctx handle with th_encode_alloc().
|
||||
* - Perform any additional encoder configuration required with
|
||||
* th_encode_ctl().
|
||||
* - Repeatedly call th_encode_flushheader() to retrieve all the header
|
||||
* packets.
|
||||
* - For each uncompressed frame:
|
||||
* - Submit the uncompressed frame via th_encode_ycbcr_in()
|
||||
* - Repeatedly call th_encode_packetout() to retrieve any video data packets
|
||||
* that are ready.
|
||||
* - Call th_encode_free() to release all encoder memory.*/
|
||||
/*@{*/
|
||||
/**Allocates an encoder instance.
|
||||
* \param _info A #th_info struct filled with the desired encoding parameters.
|
||||
* \return The initialized #th_enc_ctx handle.
|
||||
* \retval NULL If the encoding parameters were invalid.*/
|
||||
extern th_enc_ctx *th_encode_alloc(const th_info *_info);
|
||||
/**Encoder control function.
|
||||
* This is used to provide advanced control the encoding process.
|
||||
* \param _enc A #th_enc_ctx 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 th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz);
|
||||
/**Outputs the next header packet.
|
||||
* This should be called repeatedly after encoder initialization until it
|
||||
* returns 0 in order to get all of the header packets, in order, before
|
||||
* encoding actual video data.
|
||||
* \param _enc A #th_enc_ctx handle.
|
||||
* \param _comments The metadata to place in the comment header, when it is
|
||||
* encoded.
|
||||
* \param _op An <tt>ogg_packet</tt> structure to fill.
|
||||
* All of the elements of this structure will be set,
|
||||
* including a pointer to the header data.
|
||||
* The memory for the header data is owned by
|
||||
* <tt>libtheoraenc</tt>, and may be invalidated when the
|
||||
* next encoder function is called.
|
||||
* \return A positive value indicates that a header packet was successfully
|
||||
* produced.
|
||||
* \retval 0 No packet was produced, and no more header packets remain.
|
||||
* \retval TH_EFAULT \a _enc, \a _comments, or \a _op was <tt>NULL</tt>.*/
|
||||
extern int th_encode_flushheader(th_enc_ctx *_enc,
|
||||
th_comment *_comments,ogg_packet *_op);
|
||||
/**Submits an uncompressed frame to the encoder.
|
||||
* \param _enc A #th_enc_ctx handle.
|
||||
* \param _ycbcr A buffer of Y'CbCr data to encode.
|
||||
* If the width and height of the buffer matches the frame size
|
||||
* the encoder was initialized with, the encoder will only
|
||||
* reference the portion inside the picture region.
|
||||
* Any data outside this region will be ignored, and need not map
|
||||
* to a valid address.
|
||||
* Alternatively, you can pass a buffer equal to the size of the
|
||||
* picture region, if this is less than the full frame size.
|
||||
* When using subsampled chroma planes, odd picture sizes or odd
|
||||
* picture offsets may require an unexpected chroma plane size,
|
||||
* and their use is generally discouraged, as they will not be
|
||||
* well-supported by players and other media frameworks.
|
||||
* See Section 4.4 of
|
||||
* <a href="http://www.theora.org/doc/Theora.pdf">the Theora
|
||||
* specification</a> for details if you wish to use them anyway.
|
||||
* \retval 0 Success.
|
||||
* \retval TH_EFAULT \a _enc or \a _ycbcr is <tt>NULL</tt>.
|
||||
* \retval TH_EINVAL The buffer size matches neither the frame size nor the
|
||||
* picture size the encoder was initialized with, or
|
||||
* encoding has already completed.*/
|
||||
extern int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _ycbcr);
|
||||
/**Retrieves encoded video data packets.
|
||||
* This should be called repeatedly after each frame is submitted to flush any
|
||||
* encoded packets, until it returns 0.
|
||||
* The encoder will not buffer these packets as subsequent frames are
|
||||
* compressed, so a failure to do so will result in lost video data.
|
||||
* \note Currently the encoder operates in a one-frame-in, one-packet-out
|
||||
* manner.
|
||||
* However, this may be changed in the future.
|
||||
* \param _enc A #th_enc_ctx handle.
|
||||
* \param _last Set this flag to a non-zero value if no more uncompressed
|
||||
* frames will be submitted.
|
||||
* This ensures that a proper EOS flag is set on the last packet.
|
||||
* \param _op An <tt>ogg_packet</tt> structure to fill.
|
||||
* All of the elements of this structure will be set, including a
|
||||
* pointer to the video data.
|
||||
* The memory for the video data is owned by
|
||||
* <tt>libtheoraenc</tt>, and may be invalidated when the next
|
||||
* encoder function is called.
|
||||
* \return A positive value indicates that a video data packet was successfully
|
||||
* produced.
|
||||
* \retval 0 No packet was produced, and no more encoded video data
|
||||
* remains.
|
||||
* \retval TH_EFAULT \a _enc or \a _op was <tt>NULL</tt>.*/
|
||||
extern int th_encode_packetout(th_enc_ctx *_enc,int _last,ogg_packet *_op);
|
||||
/**Frees an allocated encoder instance.
|
||||
* \param _enc A #th_enc_ctx handle.*/
|
||||
extern void th_encode_free(th_enc_ctx *_enc);
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,177 @@
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
AM_CFLAGS = $(OGG_CFLAGS) $(CAIRO_CFLAGS)
|
||||
|
||||
EXTRA_DIST = \
|
||||
cpu.c \
|
||||
encoder_disabled.c \
|
||||
x86/mmxencfrag.c \
|
||||
x86/mmxfdct.c \
|
||||
x86/sse2fdct.c \
|
||||
x86/x86enc.c \
|
||||
x86/x86enc.h \
|
||||
x86/mmxfrag.c \
|
||||
x86/mmxfrag.h \
|
||||
x86/mmxidct.c \
|
||||
x86/mmxloop.h \
|
||||
x86/mmxstate.c \
|
||||
x86/x86int.h \
|
||||
x86/x86state.c \
|
||||
x86_vc
|
||||
|
||||
lib_LTLIBRARIES = libtheoradec.la libtheoraenc.la libtheora.la
|
||||
|
||||
if THEORA_DISABLE_ENCODE
|
||||
encoder_uniq_sources = \
|
||||
encoder_disabled.c
|
||||
|
||||
encoder_sources = \
|
||||
$(encoder_uniq_sources)
|
||||
else
|
||||
encoder_uniq_x86_sources = \
|
||||
x86/mmxencfrag.c \
|
||||
x86/mmxfdct.c \
|
||||
x86/x86enc.c
|
||||
|
||||
encoder_uniq_x86_64_sources = \
|
||||
x86/sse2fdct.c
|
||||
|
||||
encoder_shared_x86_sources = \
|
||||
x86/mmxfrag.c \
|
||||
x86/mmxidct.c \
|
||||
x86/mmxstate.c \
|
||||
x86/x86state.c
|
||||
|
||||
encoder_shared_x86_64_sources =
|
||||
|
||||
if CPU_x86_64
|
||||
encoder_uniq_arch_sources = \
|
||||
$(encoder_uniq_x86_sources) \
|
||||
$(encoder_uniq_x86_64_sources)
|
||||
encoder_shared_arch_sources = \
|
||||
$(encoder_shared_x86_sources) \
|
||||
$(encoder_shared_x86_64_sources)
|
||||
else
|
||||
if CPU_x86_32
|
||||
encoder_uniq_arch_sources = $(encoder_uniq_x86_sources)
|
||||
encoder_shared_arch_sources = $(encoder_shared_x86_sources)
|
||||
else
|
||||
encoder_uniq_arch_sources =
|
||||
encoder_shared_arch_sources =
|
||||
endif
|
||||
endif
|
||||
|
||||
encoder_uniq_sources = \
|
||||
analyze.c \
|
||||
fdct.c \
|
||||
encfrag.c \
|
||||
encapiwrapper.c \
|
||||
encinfo.c \
|
||||
encode.c \
|
||||
enquant.c \
|
||||
huffenc.c \
|
||||
mathops.c \
|
||||
mcenc.c \
|
||||
rate.c \
|
||||
tokenize.c \
|
||||
$(encoder_uniq_arch_sources)
|
||||
|
||||
encoder_sources = \
|
||||
apiwrapper.c \
|
||||
fragment.c \
|
||||
idct.c \
|
||||
internal.c \
|
||||
state.c \
|
||||
quant.c \
|
||||
$(encoder_shared_arch_sources) \
|
||||
$(encoder_uniq_sources)
|
||||
|
||||
endif
|
||||
|
||||
decoder_x86_sources = \
|
||||
x86/mmxidct.c \
|
||||
x86/mmxfrag.c \
|
||||
x86/mmxstate.c \
|
||||
x86/x86state.c
|
||||
if CPU_x86_64
|
||||
decoder_arch_sources = $(decoder_x86_sources)
|
||||
else
|
||||
if CPU_x86_32
|
||||
decoder_arch_sources = $(decoder_x86_sources)
|
||||
else
|
||||
decoder_arch_sources =
|
||||
endif
|
||||
endif
|
||||
|
||||
decoder_sources = \
|
||||
apiwrapper.c \
|
||||
bitpack.c \
|
||||
decapiwrapper.c \
|
||||
decinfo.c \
|
||||
decode.c \
|
||||
dequant.c \
|
||||
fragment.c \
|
||||
huffdec.c \
|
||||
idct.c \
|
||||
info.c \
|
||||
internal.c \
|
||||
quant.c \
|
||||
state.c \
|
||||
$(decoder_arch_sources)
|
||||
|
||||
noinst_HEADERS = \
|
||||
cpu.h \
|
||||
internal.h \
|
||||
encint.h \
|
||||
enquant.h \
|
||||
huffenc.h \
|
||||
mathops.h \
|
||||
modedec.h \
|
||||
x86/x86enc.h \
|
||||
apiwrapper.h \
|
||||
bitpack.h \
|
||||
dct.h \
|
||||
decint.h \
|
||||
dequant.h \
|
||||
huffdec.h \
|
||||
huffman.h \
|
||||
ocintrin.h \
|
||||
quant.h \
|
||||
x86/mmxfrag.h \
|
||||
x86/mmxloop.h \
|
||||
x86/x86int.h
|
||||
|
||||
libtheoradec_la_SOURCES = \
|
||||
$(decoder_sources) \
|
||||
Version_script-dec theoradec.exp
|
||||
libtheoradec_la_LDFLAGS = \
|
||||
-version-info @THDEC_LIB_CURRENT@:@THDEC_LIB_REVISION@:@THDEC_LIB_AGE@ \
|
||||
@THEORADEC_LDFLAGS@ @CAIRO_LIBS@ \
|
||||
-no-undefined
|
||||
|
||||
libtheoraenc_la_SOURCES = \
|
||||
$(encoder_sources) \
|
||||
Version_script-enc theoraenc.exp
|
||||
libtheoraenc_la_LDFLAGS = \
|
||||
-version-info @THENC_LIB_CURRENT@:@THENC_LIB_REVISION@:@THENC_LIB_AGE@ \
|
||||
@THEORAENC_LDFLAGS@ $(OGG_LIBS) \
|
||||
-no-undefined
|
||||
libtheoraenc_la_LIBADD = libtheoradec.la
|
||||
|
||||
libtheora_la_SOURCES = \
|
||||
$(decoder_sources) \
|
||||
$(encoder_uniq_sources) \
|
||||
Version_script theora.exp
|
||||
libtheora_la_LDFLAGS = \
|
||||
-version-info @TH_LIB_CURRENT@:@TH_LIB_REVISION@:@TH_LIB_AGE@ \
|
||||
@THEORA_LDFLAGS@ @CAIRO_LIBS@ $(OGG_LIBS) \
|
||||
-no-undefined
|
||||
|
||||
debug:
|
||||
$(MAKE) all CFLAGS="@DEBUG@"
|
||||
|
||||
profile:
|
||||
$(MAKE) all CFLAGS="@PROFILE@"
|
||||
|
||||
# contstruct various symbol export list files
|
||||
.def.exp : defexp.awk
|
||||
awk -f defexp.awk $< > $@
|
||||
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Export file for libtheora
|
||||
#
|
||||
# Only the symbols listed in the global section will be callable from
|
||||
# applications linking to the libraries.
|
||||
#
|
||||
|
||||
# We use something that looks like a versioned so filename here
|
||||
# to define the old API because of a historical confusion. This
|
||||
# label must be kept to maintain ABI compatibility.
|
||||
|
||||
libtheora.so.1.0
|
||||
{
|
||||
global:
|
||||
theora_version_string;
|
||||
theora_version_number;
|
||||
|
||||
theora_encode_init;
|
||||
theora_encode_YUVin;
|
||||
theora_encode_packetout;
|
||||
theora_encode_header;
|
||||
theora_encode_comment;
|
||||
theora_encode_tables;
|
||||
|
||||
theora_decode_header;
|
||||
theora_decode_init;
|
||||
theora_decode_packetin;
|
||||
theora_decode_YUVout;
|
||||
|
||||
theora_control;
|
||||
|
||||
theora_packet_isheader;
|
||||
theora_packet_iskeyframe;
|
||||
|
||||
theora_granule_shift;
|
||||
theora_granule_frame;
|
||||
theora_granule_time;
|
||||
|
||||
theora_info_init;
|
||||
theora_info_clear;
|
||||
|
||||
theora_clear;
|
||||
|
||||
theora_comment_init;
|
||||
theora_comment_add;
|
||||
theora_comment_add_tag;
|
||||
theora_comment_query;
|
||||
theora_comment_query_count;
|
||||
theora_comment_clear;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
#
|
||||
# Export file for libtheoradec
|
||||
#
|
||||
# Only the symbols listed in the global section will be callable from
|
||||
# applications linking to the libraries.
|
||||
#
|
||||
|
||||
# The 1.x API
|
||||
libtheoradec_1.0
|
||||
{
|
||||
global:
|
||||
th_version_string;
|
||||
th_version_number;
|
||||
|
||||
th_decode_headerin;
|
||||
th_decode_alloc;
|
||||
th_setup_free;
|
||||
th_decode_ctl;
|
||||
th_decode_packetin;
|
||||
th_decode_ycbcr_out;
|
||||
th_decode_free;
|
||||
|
||||
th_packet_isheader;
|
||||
th_packet_iskeyframe;
|
||||
|
||||
th_granule_frame;
|
||||
th_granule_time;
|
||||
|
||||
th_info_init;
|
||||
th_info_clear;
|
||||
|
||||
th_comment_init;
|
||||
th_comment_add;
|
||||
th_comment_add_tag;
|
||||
th_comment_query;
|
||||
th_comment_query_count;
|
||||
th_comment_clear;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
# The deprecated legacy api from the libtheora alpha releases.
|
||||
# We use something that looks like a versioned so filename here
|
||||
# to define the old API because of a historical confusion. This
|
||||
# label must be kept to maintain ABI compatibility.
|
||||
|
||||
libtheora.so.1.0
|
||||
{
|
||||
global:
|
||||
theora_version_string;
|
||||
theora_version_number;
|
||||
|
||||
theora_decode_header;
|
||||
theora_decode_init;
|
||||
theora_decode_packetin;
|
||||
theora_decode_YUVout;
|
||||
|
||||
theora_control;
|
||||
|
||||
theora_packet_isheader;
|
||||
theora_packet_iskeyframe;
|
||||
|
||||
theora_granule_shift;
|
||||
theora_granule_frame;
|
||||
theora_granule_time;
|
||||
|
||||
theora_info_init;
|
||||
theora_info_clear;
|
||||
|
||||
theora_clear;
|
||||
|
||||
theora_comment_init;
|
||||
theora_comment_add;
|
||||
theora_comment_add_tag;
|
||||
theora_comment_query;
|
||||
theora_comment_query_count;
|
||||
theora_comment_clear;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Export file for libtheora
|
||||
#
|
||||
# Only the symbols listed in the global section will be callable from
|
||||
# applications linking to the libraries.
|
||||
#
|
||||
|
||||
# The 1.x encoder API
|
||||
libtheoraenc_1.0
|
||||
{
|
||||
global:
|
||||
th_encode_alloc;
|
||||
th_encode_ctl;
|
||||
th_encode_flushheader;
|
||||
th_encode_ycbcr_in;
|
||||
th_encode_packetout;
|
||||
th_encode_free;
|
||||
|
||||
TH_VP31_QUANT_INFO;
|
||||
TH_VP31_HUFF_CODES;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
# The encoder portion of the deprecated alpha release api.
|
||||
# We use something that looks like a versioned so filename here
|
||||
# to define the old API because of a historical confusion. This
|
||||
# label must be kept to maintain ABI compatibility.
|
||||
|
||||
libtheora.so.1.0
|
||||
{
|
||||
global:
|
||||
theora_encode_init;
|
||||
theora_encode_YUVin;
|
||||
theora_encode_packetout;
|
||||
theora_encode_header;
|
||||
theora_encode_comment;
|
||||
theora_encode_tables;
|
||||
|
||||
local:
|
||||
*;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: apiwrapper.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#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_vtable *)_th->internal_decode)->clear)(_th);
|
||||
}
|
||||
if(_th->internal_encode!=NULL){
|
||||
(*((oc_state_dispatch_vtable *)_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_vtable *)_th->internal_decode)->control)(_th,
|
||||
_req,_buf,_buf_sz);
|
||||
}
|
||||
else if(_th->internal_encode!=NULL){
|
||||
return (*((oc_state_dispatch_vtable *)_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_vtable *)_th->internal_decode)->granule_frame)(
|
||||
_th,_gp);
|
||||
}
|
||||
else if(_th->internal_encode!=NULL){
|
||||
return (*((oc_state_dispatch_vtable *)_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_vtable *)_th->internal_decode)->granule_time)(
|
||||
_th,_gp);
|
||||
}
|
||||
else if(_th->internal_encode!=NULL){
|
||||
return (*((oc_state_dispatch_vtable *)_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);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors 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"
|
||||
# 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
|
||||
@@ -0,0 +1,111 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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 OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: packing variable sized words into an octet stream
|
||||
last mod: $Id: bitpack.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bitpack.h"
|
||||
|
||||
/*We're 'MSb' endian; if we write a word but read individual bits,
|
||||
then we'll read the MSb first.*/
|
||||
|
||||
void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){
|
||||
memset(_b,0,sizeof(*_b));
|
||||
_b->ptr=_buf;
|
||||
_b->stop=_buf+_bytes;
|
||||
}
|
||||
|
||||
static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
|
||||
const unsigned char *ptr;
|
||||
const unsigned char *stop;
|
||||
oc_pb_window window;
|
||||
int available;
|
||||
window=_b->window;
|
||||
available=_b->bits;
|
||||
ptr=_b->ptr;
|
||||
stop=_b->stop;
|
||||
while(available<=OC_PB_WINDOW_SIZE-8&&ptr<stop){
|
||||
available+=8;
|
||||
window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
|
||||
}
|
||||
_b->ptr=ptr;
|
||||
if(_bits>available){
|
||||
if(ptr>=stop){
|
||||
_b->eof=1;
|
||||
available=OC_LOTS_OF_BITS;
|
||||
}
|
||||
else window|=*ptr>>(available&7);
|
||||
}
|
||||
_b->bits=available;
|
||||
return window;
|
||||
}
|
||||
|
||||
int oc_pack_look1(oc_pack_buf *_b){
|
||||
oc_pb_window window;
|
||||
int available;
|
||||
window=_b->window;
|
||||
available=_b->bits;
|
||||
if(available<1)_b->window=window=oc_pack_refill(_b,1);
|
||||
return window>>OC_PB_WINDOW_SIZE-1;
|
||||
}
|
||||
|
||||
void oc_pack_adv1(oc_pack_buf *_b){
|
||||
_b->window<<=1;
|
||||
_b->bits--;
|
||||
}
|
||||
|
||||
/*Here we assume that 0<=_bits&&_bits<=32.*/
|
||||
long oc_pack_read(oc_pack_buf *_b,int _bits){
|
||||
oc_pb_window window;
|
||||
int available;
|
||||
long result;
|
||||
window=_b->window;
|
||||
available=_b->bits;
|
||||
if(_bits==0)return 0;
|
||||
if(available<_bits){
|
||||
window=oc_pack_refill(_b,_bits);
|
||||
available=_b->bits;
|
||||
}
|
||||
result=window>>OC_PB_WINDOW_SIZE-_bits;
|
||||
available-=_bits;
|
||||
window<<=1;
|
||||
window<<=_bits-1;
|
||||
_b->bits=available;
|
||||
_b->window=window;
|
||||
return result;
|
||||
}
|
||||
|
||||
int oc_pack_read1(oc_pack_buf *_b){
|
||||
oc_pb_window window;
|
||||
int available;
|
||||
int result;
|
||||
window=_b->window;
|
||||
available=_b->bits;
|
||||
if(available<1){
|
||||
window=oc_pack_refill(_b,1);
|
||||
available=_b->bits;
|
||||
}
|
||||
result=window>>OC_PB_WINDOW_SIZE-1;
|
||||
available--;
|
||||
window<<=1;
|
||||
_b->bits=available;
|
||||
_b->window=window;
|
||||
return result;
|
||||
}
|
||||
|
||||
long oc_pack_bytes_left(oc_pack_buf *_b){
|
||||
if(_b->eof)return -1;
|
||||
return _b->stop-_b->ptr+(_b->bits>>3);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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 OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation and contributors 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(_bitpack_H)
|
||||
# define _bitpack_H (1)
|
||||
# include <stddef.h>
|
||||
# include <limits.h>
|
||||
|
||||
|
||||
|
||||
typedef size_t oc_pb_window;
|
||||
typedef struct oc_pack_buf oc_pack_buf;
|
||||
|
||||
|
||||
|
||||
# define OC_PB_WINDOW_SIZE ((int)sizeof(oc_pb_window)*CHAR_BIT)
|
||||
/*This is meant to be a large, positive constant that can still be efficiently
|
||||
loaded as an immediate (on platforms like ARM, for example).
|
||||
Even relatively modest values like 100 would work fine.*/
|
||||
# define OC_LOTS_OF_BITS (0x40000000)
|
||||
|
||||
|
||||
|
||||
struct oc_pack_buf{
|
||||
oc_pb_window window;
|
||||
const unsigned char *ptr;
|
||||
const unsigned char *stop;
|
||||
int bits;
|
||||
int eof;
|
||||
};
|
||||
|
||||
void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes);
|
||||
int oc_pack_look1(oc_pack_buf *_b);
|
||||
void oc_pack_adv1(oc_pack_buf *_b);
|
||||
/*Here we assume 0<=_bits&&_bits<=32.*/
|
||||
long oc_pack_read(oc_pack_buf *_b,int _bits);
|
||||
int oc_pack_read1(oc_pack_buf *_b);
|
||||
/* returns -1 for read beyond EOF, or the number of whole bytes available */
|
||||
long oc_pack_bytes_left(oc_pack_buf *_b);
|
||||
|
||||
/*These two functions are implemented locally in huffdec.c*/
|
||||
/*Read in bits without advancing the bitptr.
|
||||
Here we assume 0<=_bits&&_bits<=32.*/
|
||||
/*static int oc_pack_look(oc_pack_buf *_b,int _bits);*/
|
||||
/*static void oc_pack_adv(oc_pack_buf *_b,int _bits);*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,226 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
CPU capability detection for x86 processors.
|
||||
Originally written by Rudolf Marek.
|
||||
|
||||
function:
|
||||
last mod: $Id: cpu.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#if !defined(OC_X86_ASM)
|
||||
static ogg_uint32_t oc_cpu_flags_get(void){
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# if !defined(_MSC_VER)
|
||||
# if defined(__amd64__)||defined(__x86_64__)
|
||||
/*On x86-64, gcc seems to be able to figure out how to save %rbx for us when
|
||||
compiling with -fPIC.*/
|
||||
# define cpuid(_op,_eax,_ebx,_ecx,_edx) \
|
||||
__asm__ __volatile__( \
|
||||
"cpuid\n\t" \
|
||||
:[eax]"=a"(_eax),[ebx]"=b"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
|
||||
:"a"(_op) \
|
||||
:"cc" \
|
||||
)
|
||||
# else
|
||||
/*On x86-32, not so much.*/
|
||||
# define cpuid(_op,_eax,_ebx,_ecx,_edx) \
|
||||
__asm__ __volatile__( \
|
||||
"xchgl %%ebx,%[ebx]\n\t" \
|
||||
"cpuid\n\t" \
|
||||
"xchgl %%ebx,%[ebx]\n\t" \
|
||||
:[eax]"=a"(_eax),[ebx]"=r"(_ebx),[ecx]"=c"(_ecx),[edx]"=d"(_edx) \
|
||||
:"a"(_op) \
|
||||
:"cc" \
|
||||
)
|
||||
# endif
|
||||
# else
|
||||
/*Why does MSVC need this complicated rigamarole?
|
||||
At this point I honestly do not care.*/
|
||||
|
||||
/*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 _cpu_info[4],ogg_uint32_t _op){
|
||||
_asm{
|
||||
mov eax,[_op]
|
||||
mov esi,_cpu_info
|
||||
cpuid
|
||||
mov [esi+0],eax
|
||||
mov [esi+4],ebx
|
||||
mov [esi+8],ecx
|
||||
mov [esi+12],edx
|
||||
}
|
||||
}
|
||||
|
||||
# define cpuid(_op,_eax,_ebx,_ecx,_edx) \
|
||||
do{ \
|
||||
ogg_uint32_t cpu_info[4]; \
|
||||
oc_cpuid_helper(cpu_info,_op); \
|
||||
(_eax)=cpu_info[0]; \
|
||||
(_ebx)=cpu_info[1]; \
|
||||
(_ecx)=cpu_info[2]; \
|
||||
(_edx)=cpu_info[3]; \
|
||||
}while(0)
|
||||
|
||||
static void oc_detect_cpuid_helper(ogg_uint32_t *_eax,ogg_uint32_t *_ebx){
|
||||
_asm{
|
||||
pushfd
|
||||
pushfd
|
||||
pop eax
|
||||
mov ebx,eax
|
||||
xor eax,200000h
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
popfd
|
||||
mov ecx,_eax
|
||||
mov [ecx],eax
|
||||
mov ecx,_ebx
|
||||
mov [ecx],ebx
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
static ogg_uint32_t oc_parse_intel_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
|
||||
ogg_uint32_t flags;
|
||||
/*If there isn't even MMX, give up.*/
|
||||
if(!(_edx&0x00800000))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;
|
||||
if(_ecx&0x00000001)flags|=OC_CPU_X86_PNI;
|
||||
if(_ecx&0x00000100)flags|=OC_CPU_X86_SSSE3;
|
||||
if(_ecx&0x00080000)flags|=OC_CPU_X86_SSE4_1;
|
||||
if(_ecx&0x00100000)flags|=OC_CPU_X86_SSE4_2;
|
||||
return flags;
|
||||
}
|
||||
|
||||
static ogg_uint32_t oc_parse_amd_flags(ogg_uint32_t _edx,ogg_uint32_t _ecx){
|
||||
ogg_uint32_t flags;
|
||||
/*If there isn't even MMX, give up.*/
|
||||
if(!(_edx&0x00800000))return 0;
|
||||
flags=OC_CPU_X86_MMX;
|
||||
if(_edx&0x00400000)flags|=OC_CPU_X86_MMXEXT;
|
||||
if(_edx&0x80000000)flags|=OC_CPU_X86_3DNOW;
|
||||
if(_edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT;
|
||||
if(_ecx&0x00000040)flags|=OC_CPU_X86_SSE4A;
|
||||
if(_ecx&0x00000800)flags|=OC_CPU_X86_SSE5;
|
||||
return flags;
|
||||
}
|
||||
|
||||
static ogg_uint32_t oc_cpu_flags_get(void){
|
||||
ogg_uint32_t flags;
|
||||
ogg_uint32_t eax;
|
||||
ogg_uint32_t ebx;
|
||||
ogg_uint32_t ecx;
|
||||
ogg_uint32_t edx;
|
||||
# if !defined(__amd64__)&&!defined(__x86_64__)
|
||||
/*Not all x86-32 chips support cpuid, so we have to check.*/
|
||||
# if !defined(_MSC_VER)
|
||||
__asm__ __volatile__(
|
||||
"pushfl\n\t"
|
||||
"pushfl\n\t"
|
||||
"popl %[a]\n\t"
|
||||
"movl %[a],%[b]\n\t"
|
||||
"xorl $0x200000,%[a]\n\t"
|
||||
"pushl %[a]\n\t"
|
||||
"popfl\n\t"
|
||||
"pushfl\n\t"
|
||||
"popl %[a]\n\t"
|
||||
"popfl\n\t"
|
||||
:[a]"=r"(eax),[b]"=r"(ebx)
|
||||
:
|
||||
:"cc"
|
||||
);
|
||||
# else
|
||||
oc_detect_cpuid_helper(&eax,&ebx);
|
||||
# endif
|
||||
/*No cpuid.*/
|
||||
if(eax==ebx)return 0;
|
||||
# endif
|
||||
cpuid(0,eax,ebx,ecx,edx);
|
||||
/* l e t n I e n i u n e G*/
|
||||
if(ecx==0x6C65746E&&edx==0x49656E69&&ebx==0x756E6547||
|
||||
/* 6 8 x M T e n i u n e G*/
|
||||
ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547){
|
||||
/*Intel, Transmeta (tested with Crusoe TM5800):*/
|
||||
cpuid(1,eax,ebx,ecx,edx);
|
||||
flags=oc_parse_intel_flags(edx,ecx);
|
||||
}
|
||||
/* D M A c i t n e h t u A*/
|
||||
else if(ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541||
|
||||
/* C S N y b e d o e G*/
|
||||
ecx==0x43534e20&&edx==0x79622065&&ebx==0x646f6547){
|
||||
/*AMD, Geode:*/
|
||||
cpuid(0x80000000,eax,ebx,ecx,edx);
|
||||
if(eax<0x80000001)flags=0;
|
||||
else{
|
||||
cpuid(0x80000001,eax,ebx,ecx,edx);
|
||||
flags=oc_parse_amd_flags(edx,ecx);
|
||||
}
|
||||
/*Also check for SSE.*/
|
||||
cpuid(1,eax,ebx,ecx,edx);
|
||||
flags|=oc_parse_intel_flags(edx,ecx);
|
||||
}
|
||||
/*Technically some VIA chips can be configured in the BIOS to return any
|
||||
string here the user wants.
|
||||
There is a special detection method that can be used to identify such
|
||||
processors, but in my opinion, if the user really wants to change it, they
|
||||
deserve what they get.*/
|
||||
/* s l u a H r u a t n e C*/
|
||||
else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){
|
||||
/*VIA:*/
|
||||
/*I only have documentation for the C7 (Esther) and Isaiah (forthcoming)
|
||||
chips (thanks to the engineers from Centaur Technology who provided it).
|
||||
These chips support Intel-like cpuid info.
|
||||
The C3-2 (Nehemiah) cores appear to, as well.*/
|
||||
cpuid(1,eax,ebx,ecx,edx);
|
||||
flags=oc_parse_intel_flags(edx,ecx);
|
||||
if(eax>=0x80000001){
|
||||
/*The (non-Nehemiah) C3 processors support AMD-like cpuid info.
|
||||
We need to check this even if the Intel test succeeds to pick up 3DNow!
|
||||
support on these processors.
|
||||
Unlike actual AMD processors, we cannot _rely_ on this info, since
|
||||
some cores (e.g., the 693 stepping of the Nehemiah) claim to support
|
||||
this function, yet return edx=0, despite the Intel test indicating
|
||||
MMX support.
|
||||
Therefore the features detected here are strictly added to those
|
||||
detected by the Intel test.*/
|
||||
/*TODO: How about earlier chips?*/
|
||||
cpuid(0x80000001,eax,ebx,ecx,edx);
|
||||
/*Note: As of the C7, this function returns Intel-style extended feature
|
||||
flags, not AMD-style.
|
||||
Currently, this only defines bits 11, 20, and 29 (0x20100800), which
|
||||
do not conflict with any of the AMD flags we inspect.
|
||||
For the remaining bits, Intel tells us, "Do not count on their value",
|
||||
but VIA assures us that they will all be zero (at least on the C7 and
|
||||
Isaiah chips).
|
||||
In the (unlikely) event a future processor uses bits 18, 19, 30, or 31
|
||||
(0xC0C00000) for something else, we will have to add code to detect
|
||||
the model to decide when it is appropriate to inspect them.*/
|
||||
flags|=oc_parse_amd_flags(edx,ecx);
|
||||
}
|
||||
}
|
||||
else{
|
||||
/*Implement me.*/
|
||||
flags=0;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
function:
|
||||
last mod: $Id: cpu.h 16503 2009-08-22 18:14:02Z 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)
|
||||
#define OC_CPU_X86_PNI (1<<6)
|
||||
#define OC_CPU_X86_SSSE3 (1<<7)
|
||||
#define OC_CPU_X86_SSE4_1 (1<<8)
|
||||
#define OC_CPU_X86_SSE4_2 (1<<9)
|
||||
#define OC_CPU_X86_SSE4A (1<<10)
|
||||
#define OC_CPU_X86_SSE5 (1<<11)
|
||||
|
||||
#endif
|
||||
@@ -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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: dct.h 16503 2009-08-22 18:14:02Z 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
|
||||
@@ -0,0 +1,193 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors 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 "decint.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);
|
||||
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_vtable 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));
|
||||
if(apiinfo==NULL)return OC_FAULT;
|
||||
/*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;
|
||||
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));
|
||||
if(_ci->codec_setup==NULL)return OC_FAULT;
|
||||
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;
|
||||
if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT;
|
||||
api=(th_api_wrapper *)_td->i->codec_setup;
|
||||
ret=th_decode_packetin(api->decode,_op,&gp);
|
||||
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_dec_ctx *decode;
|
||||
th_ycbcr_buffer buf;
|
||||
int ret;
|
||||
if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT;
|
||||
api=(th_api_wrapper *)_td->i->codec_setup;
|
||||
decode=(th_dec_ctx *)api->decode;
|
||||
if(!decode)return OC_FAULT;
|
||||
ret=th_decode_ycbcr_out(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;
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: decinfo.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#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(oc_pack_buf *_opb,char *_buf,size_t _len){
|
||||
while(_len-->0){
|
||||
long val;
|
||||
val=oc_pack_read(_opb,8);
|
||||
*_buf++=(char)val;
|
||||
}
|
||||
}
|
||||
|
||||
/*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
|
||||
static long oc_unpack_length(oc_pack_buf *_opb){
|
||||
long ret[4];
|
||||
int i;
|
||||
for(i=0;i<4;i++)ret[i]=oc_pack_read(_opb,8);
|
||||
return ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24;
|
||||
}
|
||||
|
||||
static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
|
||||
long val;
|
||||
/*Check the codec bitstream version.*/
|
||||
val=oc_pack_read(_opb,8);
|
||||
_info->version_major=(unsigned char)val;
|
||||
val=oc_pack_read(_opb,8);
|
||||
_info->version_minor=(unsigned char)val;
|
||||
val=oc_pack_read(_opb,8);
|
||||
_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.*/
|
||||
val=oc_pack_read(_opb,16);
|
||||
_info->frame_width=(ogg_uint32_t)val<<4;
|
||||
val=oc_pack_read(_opb,16);
|
||||
_info->frame_height=(ogg_uint32_t)val<<4;
|
||||
val=oc_pack_read(_opb,24);
|
||||
_info->pic_width=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,24);
|
||||
_info->pic_height=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,8);
|
||||
_info->pic_x=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,8);
|
||||
_info->pic_y=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,32);
|
||||
_info->fps_numerator=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,32);
|
||||
_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;
|
||||
}
|
||||
/*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.*/
|
||||
_info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
|
||||
val=oc_pack_read(_opb,24);
|
||||
_info->aspect_numerator=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,24);
|
||||
_info->aspect_denominator=(ogg_uint32_t)val;
|
||||
val=oc_pack_read(_opb,8);
|
||||
_info->colorspace=(th_colorspace)val;
|
||||
val=oc_pack_read(_opb,24);
|
||||
_info->target_bitrate=(int)val;
|
||||
val=oc_pack_read(_opb,6);
|
||||
_info->quality=(int)val;
|
||||
val=oc_pack_read(_opb,5);
|
||||
_info->keyframe_granule_shift=(int)val;
|
||||
val=oc_pack_read(_opb,2);
|
||||
_info->pixel_fmt=(th_pixel_fmt)val;
|
||||
if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER;
|
||||
val=oc_pack_read(_opb,3);
|
||||
if(val!=0||oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){
|
||||
long len;
|
||||
int i;
|
||||
/*Read the vendor string.*/
|
||||
len=oc_unpack_length(_opb);
|
||||
if(len<0||len>oc_pack_bytes_left(_opb))return TH_EBADHEADER;
|
||||
_tc->vendor=_ogg_malloc((size_t)len+1);
|
||||
if(_tc->vendor==NULL)return TH_EFAULT;
|
||||
oc_unpack_octets(_opb,_tc->vendor,len);
|
||||
_tc->vendor[len]='\0';
|
||||
/*Read the user comments.*/
|
||||
_tc->comments=(int)oc_unpack_length(_opb);
|
||||
len=_tc->comments;
|
||||
if(len<0||len>(LONG_MAX>>2)||len<<2>oc_pack_bytes_left(_opb)){
|
||||
_tc->comments=0;
|
||||
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||len>oc_pack_bytes_left(_opb)){
|
||||
_tc->comments=i;
|
||||
return TH_EBADHEADER;
|
||||
}
|
||||
_tc->comment_lengths[i]=len;
|
||||
_tc->user_comments[i]=_ogg_malloc((size_t)len+1);
|
||||
if(_tc->user_comments[i]==NULL){
|
||||
_tc->comments=i;
|
||||
return TH_EFAULT;
|
||||
}
|
||||
oc_unpack_octets(_opb,_tc->user_comments[i],len);
|
||||
_tc->user_comments[i][len]='\0';
|
||||
}
|
||||
return oc_pack_bytes_left(_opb)<0?TH_EBADHEADER:0;
|
||||
}
|
||||
|
||||
static int oc_setup_unpack(oc_pack_buf *_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(oc_pack_buf *_opb,th_info *_info,
|
||||
th_comment *_tc,th_setup_info **_setup,ogg_packet *_op){
|
||||
char buffer[6];
|
||||
long val;
|
||||
int packtype;
|
||||
int ret;
|
||||
val=oc_pack_read(_opb,8);
|
||||
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));
|
||||
if(setup==NULL)return TH_EFAULT;
|
||||
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){
|
||||
oc_pack_buf opb;
|
||||
if(_op==NULL)return TH_EBADHEADER;
|
||||
if(_info==NULL)return TH_EFAULT;
|
||||
oc_pack_readinit(&opb,_op->packet,_op->bytes);
|
||||
return oc_dec_headerin(&opb,_info,_tc,_setup,_op);
|
||||
}
|
||||
|
||||
void th_setup_free(th_setup_info *_setup){
|
||||
if(_setup!=NULL){
|
||||
oc_setup_clear(_setup);
|
||||
_ogg_free(_setup);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: decint.h 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#if !defined(_decint_H)
|
||||
# define _decint_H (1)
|
||||
# include "theora/theoradec.h"
|
||||
# include "internal.h"
|
||||
# include "bitpack.h"
|
||||
|
||||
typedef struct th_setup_info oc_setup_info;
|
||||
typedef struct th_dec_ctx oc_dec_ctx;
|
||||
|
||||
# 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.*/
|
||||
oc_pack_buf opb;
|
||||
/*Huffman decode trees.*/
|
||||
oc_huff_node *huff_tables[TH_NHUFFMAN_TABLES];
|
||||
/*The index of the first token in each plane for each coefficient.*/
|
||||
ptrdiff_t ti0[3][64];
|
||||
/*The number of outstanding EOB runs at the start of each coefficient in each
|
||||
plane.*/
|
||||
ptrdiff_t eob_runs[3][64];
|
||||
/*The DCT token lists.*/
|
||||
unsigned char *dct_tokens;
|
||||
/*The extra bits associated with DCT tokens.*/
|
||||
unsigned char *extra_bits;
|
||||
/*The number of dct tokens unpacked so far.*/
|
||||
int dct_tokens_count;
|
||||
/*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_state;
|
||||
/*The buffer used for the post-processed frame.
|
||||
Note that this is _not_ guaranteed to have the same strides and offsets as
|
||||
the reference frame buffers.*/
|
||||
th_ycbcr_buffer pp_frame_buf;
|
||||
/*The striped decode callback function.*/
|
||||
th_stripe_callback stripe_cb;
|
||||
# if defined(HAVE_CAIRO)
|
||||
/*Output metrics for debugging.*/
|
||||
int telemetry;
|
||||
int telemetry_mbmode;
|
||||
int telemetry_mv;
|
||||
int telemetry_qi;
|
||||
int telemetry_bits;
|
||||
int telemetry_frame_bytes;
|
||||
int telemetry_coding_bytes;
|
||||
int telemetry_mode_bytes;
|
||||
int telemetry_mv_bytes;
|
||||
int telemetry_qi_bytes;
|
||||
int telemetry_dc_bytes;
|
||||
unsigned char *telemetry_frame_data;
|
||||
# endif
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
# awk script to convert symbol export table formats
|
||||
|
||||
# converts an msvc .def file to an darwin ld export-symbols-list file
|
||||
# we only support the most basic module definition syntax
|
||||
|
||||
# skip comments
|
||||
/^\w*#.*/ {next}
|
||||
/^\w*;.*/ {next}
|
||||
|
||||
# remember and propagate the library name
|
||||
/LIBRARY/ {name = $2; print "# export list for", name; next}
|
||||
|
||||
# skip various other lines
|
||||
/^\w*NAME/ ||
|
||||
/^\w*VERSION/ ||
|
||||
/^\w*EXPORTS/ ||
|
||||
/^\w*HEAPSIZE/ ||
|
||||
/^\w*STACKSIZE/ ||
|
||||
/^\w*STUB/ {next}
|
||||
|
||||
# todo: handle SECTIONS
|
||||
|
||||
# for symbols, strip the semicolon and mangle the name
|
||||
/[a-zA-Z]+/ {sub(/\;/, ""); print "_" $1}
|
||||
|
||||
# todo: warn if we see publicname=privatename mappings
|
||||
# which other linkers don't support
|
||||
@@ -0,0 +1,182 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: dequant.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include "dequant.h"
|
||||
#include "decint.h"
|
||||
|
||||
int oc_quant_params_unpack(oc_pack_buf *_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;
|
||||
val=oc_pack_read(_opb,3);
|
||||
nbits=(int)val;
|
||||
for(qi=0;qi<64;qi++){
|
||||
val=oc_pack_read(_opb,nbits);
|
||||
_qinfo->loop_filter_limits[qi]=(unsigned char)val;
|
||||
}
|
||||
val=oc_pack_read(_opb,4);
|
||||
nbits=(int)val+1;
|
||||
for(qi=0;qi<64;qi++){
|
||||
val=oc_pack_read(_opb,nbits);
|
||||
_qinfo->ac_scale[qi]=(ogg_uint16_t)val;
|
||||
}
|
||||
val=oc_pack_read(_opb,4);
|
||||
nbits=(int)val+1;
|
||||
for(qi=0;qi<64;qi++){
|
||||
val=oc_pack_read(_opb,nbits);
|
||||
_qinfo->dc_scale[qi]=(ogg_uint16_t)val;
|
||||
}
|
||||
val=oc_pack_read(_opb,9);
|
||||
nbase_mats=(int)val+1;
|
||||
base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0]));
|
||||
if(base_mats==NULL)return TH_EFAULT;
|
||||
for(bmi=0;bmi<nbase_mats;bmi++){
|
||||
for(ci=0;ci<64;ci++){
|
||||
val=oc_pack_read(_opb,8);
|
||||
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){
|
||||
val=oc_pack_read1(_opb);
|
||||
if(!val){
|
||||
int qtj;
|
||||
int plj;
|
||||
if(qti>0){
|
||||
val=oc_pack_read1(_opb);
|
||||
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;
|
||||
}
|
||||
}
|
||||
val=oc_pack_read(_opb,nbits);
|
||||
indices[0]=(int)val;
|
||||
for(qi=qri=0;qi<63;){
|
||||
val=oc_pack_read(_opb,oc_ilog(62-qi));
|
||||
sizes[qri]=(int)val+1;
|
||||
qi+=(int)val+1;
|
||||
val=oc_pack_read(_opb,nbits);
|
||||
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]));
|
||||
if(qranges->sizes==NULL){
|
||||
/*Note: The caller is responsible for cleaning up any partially
|
||||
constructed qinfo.*/
|
||||
_ogg_free(base_mats);
|
||||
return TH_EFAULT;
|
||||
}
|
||||
memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0]));
|
||||
qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0]));
|
||||
if(qrbms==NULL){
|
||||
/*Note: The caller is responsible for cleaning up any partially
|
||||
constructed qinfo.*/
|
||||
_ogg_free(base_mats);
|
||||
return TH_EFAULT;
|
||||
}
|
||||
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);
|
||||
}
|
||||
_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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: dequant.h 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#if !defined(_dequant_H)
|
||||
# define _dequant_H (1)
|
||||
# include "quant.h"
|
||||
# include "bitpack.h"
|
||||
|
||||
int oc_quant_params_unpack(oc_pack_buf *_opb,
|
||||
th_quant_info *_qinfo);
|
||||
void oc_quant_params_clear(th_quant_info *_qinfo);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,168 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "apiwrapper.h"
|
||||
#include "encint.h"
|
||||
#include "theora/theoraenc.h"
|
||||
|
||||
|
||||
|
||||
static void th_enc_api_clear(th_api_wrapper *_api){
|
||||
if(_api->encode)th_encode_free(_api->encode);
|
||||
memset(_api,0,sizeof(*_api));
|
||||
}
|
||||
|
||||
static void theora_encode_clear(theora_state *_te){
|
||||
if(_te->i!=NULL)theora_info_clear(_te->i);
|
||||
memset(_te,0,sizeof(*_te));
|
||||
}
|
||||
|
||||
static int theora_encode_control(theora_state *_te,int _req,
|
||||
void *_buf,size_t _buf_sz){
|
||||
return th_encode_ctl(((th_api_wrapper *)_te->i->codec_setup)->encode,
|
||||
_req,_buf,_buf_sz);
|
||||
}
|
||||
|
||||
static ogg_int64_t theora_encode_granule_frame(theora_state *_te,
|
||||
ogg_int64_t _gp){
|
||||
return th_granule_frame(((th_api_wrapper *)_te->i->codec_setup)->encode,_gp);
|
||||
}
|
||||
|
||||
static double theora_encode_granule_time(theora_state *_te,ogg_int64_t _gp){
|
||||
return th_granule_time(((th_api_wrapper *)_te->i->codec_setup)->encode,_gp);
|
||||
}
|
||||
|
||||
static const oc_state_dispatch_vtable OC_ENC_DISPATCH_VTBL={
|
||||
(oc_state_clear_func)theora_encode_clear,
|
||||
(oc_state_control_func)theora_encode_control,
|
||||
(oc_state_granule_frame_func)theora_encode_granule_frame,
|
||||
(oc_state_granule_time_func)theora_encode_granule_time,
|
||||
};
|
||||
|
||||
int theora_encode_init(theora_state *_te,theora_info *_ci){
|
||||
th_api_info *apiinfo;
|
||||
th_info info;
|
||||
ogg_uint32_t keyframe_frequency_force;
|
||||
/*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_malloc(sizeof(*apiinfo));
|
||||
if(apiinfo==NULL)return TH_EFAULT;
|
||||
/*Make our own copy of the info struct, since its lifetime should be
|
||||
independent of the one we were passed in.*/
|
||||
*&apiinfo->info=*_ci;
|
||||
oc_theora_info2th_info(&info,_ci);
|
||||
apiinfo->api.encode=th_encode_alloc(&info);
|
||||
if(apiinfo->api.encode==NULL){
|
||||
_ogg_free(apiinfo);
|
||||
return OC_EINVAL;
|
||||
}
|
||||
apiinfo->api.clear=(oc_setup_clear_func)th_enc_api_clear;
|
||||
/*Provide entry points for ABI compatibility with old decoder shared libs.*/
|
||||
_te->internal_encode=(void *)&OC_ENC_DISPATCH_VTBL;
|
||||
_te->internal_decode=NULL;
|
||||
_te->granulepos=0;
|
||||
_te->i=&apiinfo->info;
|
||||
_te->i->codec_setup=&apiinfo->api;
|
||||
/*Set the precise requested keyframe frequency.*/
|
||||
keyframe_frequency_force=_ci->keyframe_auto_p?
|
||||
_ci->keyframe_frequency_force:_ci->keyframe_frequency;
|
||||
th_encode_ctl(apiinfo->api.encode,
|
||||
TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
|
||||
&keyframe_frequency_force,sizeof(keyframe_frequency_force));
|
||||
/*TODO: Additional codec setup using the extra fields in theora_info.*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int theora_encode_YUVin(theora_state *_te,yuv_buffer *_yuv){
|
||||
th_api_wrapper *api;
|
||||
th_ycbcr_buffer buf;
|
||||
int ret;
|
||||
api=(th_api_wrapper *)_te->i->codec_setup;
|
||||
buf[0].width=_yuv->y_width;
|
||||
buf[0].height=_yuv->y_height;
|
||||
buf[0].stride=_yuv->y_stride;
|
||||
buf[0].data=_yuv->y;
|
||||
buf[1].width=_yuv->uv_width;
|
||||
buf[1].height=_yuv->uv_height;
|
||||
buf[1].stride=_yuv->uv_stride;
|
||||
buf[1].data=_yuv->u;
|
||||
buf[2].width=_yuv->uv_width;
|
||||
buf[2].height=_yuv->uv_height;
|
||||
buf[2].stride=_yuv->uv_stride;
|
||||
buf[2].data=_yuv->v;
|
||||
ret=th_encode_ycbcr_in(api->encode,buf);
|
||||
if(ret<0)return ret;
|
||||
_te->granulepos=api->encode->state.granpos;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int theora_encode_packetout(theora_state *_te,int _last_p,ogg_packet *_op){
|
||||
th_api_wrapper *api;
|
||||
api=(th_api_wrapper *)_te->i->codec_setup;
|
||||
return th_encode_packetout(api->encode,_last_p,_op);
|
||||
}
|
||||
|
||||
int theora_encode_header(theora_state *_te,ogg_packet *_op){
|
||||
oc_enc_ctx *enc;
|
||||
th_api_wrapper *api;
|
||||
int ret;
|
||||
api=(th_api_wrapper *)_te->i->codec_setup;
|
||||
enc=api->encode;
|
||||
/*If we've already started encoding, fail.*/
|
||||
if(enc->packet_state>OC_PACKET_EMPTY||enc->state.granpos!=0){
|
||||
return TH_EINVAL;
|
||||
}
|
||||
/*Reset the state to make sure we output an info packet.*/
|
||||
enc->packet_state=OC_PACKET_INFO_HDR;
|
||||
ret=th_encode_flushheader(api->encode,NULL,_op);
|
||||
return ret>=0?0:ret;
|
||||
}
|
||||
|
||||
int theora_encode_comment(theora_comment *_tc,ogg_packet *_op){
|
||||
oggpack_buffer opb;
|
||||
void *buf;
|
||||
int packet_state;
|
||||
int ret;
|
||||
packet_state=OC_PACKET_COMMENT_HDR;
|
||||
oggpackB_writeinit(&opb);
|
||||
ret=oc_state_flushheader(NULL,&packet_state,&opb,NULL,NULL,
|
||||
th_version_string(),(th_comment *)_tc,_op);
|
||||
if(ret>=0){
|
||||
/*The oggpack_buffer's lifetime ends with this function, so we have to
|
||||
copy out the packet contents.
|
||||
Presumably the application knows it is supposed to free this.
|
||||
This part works nothing like the Vorbis API, and the documentation on it
|
||||
has been wrong for some time, claiming libtheora owned the memory.*/
|
||||
buf=_ogg_malloc(_op->bytes);
|
||||
if(buf==NULL){
|
||||
_op->packet=NULL;
|
||||
ret=TH_EFAULT;
|
||||
}
|
||||
else{
|
||||
memcpy(buf,_op->packet,_op->bytes);
|
||||
_op->packet=buf;
|
||||
ret=0;
|
||||
}
|
||||
}
|
||||
oggpack_writeclear(&opb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int theora_encode_tables(theora_state *_te,ogg_packet *_op){
|
||||
oc_enc_ctx *enc;
|
||||
th_api_wrapper *api;
|
||||
int ret;
|
||||
api=(th_api_wrapper *)_te->i->codec_setup;
|
||||
enc=api->encode;
|
||||
/*If we've already started encoding, fail.*/
|
||||
if(enc->packet_state>OC_PACKET_EMPTY||enc->state.granpos!=0){
|
||||
return TH_EINVAL;
|
||||
}
|
||||
/*Reset the state to make sure we output a setup packet.*/
|
||||
enc->packet_state=OC_PACKET_SETUP_HDR;
|
||||
ret=th_encode_flushheader(api->encode,NULL,_op);
|
||||
return ret>=0?0:ret;
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: encfrag.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "encint.h"
|
||||
|
||||
|
||||
void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride){
|
||||
(*_enc->opt_vtable.frag_sub)(_diff,_src,_ref,_ystride);
|
||||
}
|
||||
|
||||
void oc_enc_frag_sub_c(ogg_int16_t _diff[64],const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int j;
|
||||
for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-_ref[j]);
|
||||
_src+=_ystride;
|
||||
_ref+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,int _ystride){
|
||||
(*_enc->opt_vtable.frag_sub_128)(_diff,_src,_ystride);
|
||||
}
|
||||
|
||||
void oc_enc_frag_sub_128_c(ogg_int16_t *_diff,
|
||||
const unsigned char *_src,int _ystride){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int j;
|
||||
for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-128);
|
||||
_src+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_x,
|
||||
const unsigned char *_y,int _ystride){
|
||||
return (*_enc->opt_vtable.frag_sad)(_x,_y,_ystride);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_sad_c(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride){
|
||||
unsigned sad;
|
||||
int i;
|
||||
sad=0;
|
||||
for(i=8;i-->0;){
|
||||
int j;
|
||||
for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]);
|
||||
_src+=_ystride;
|
||||
_ref+=_ystride;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride,
|
||||
unsigned _thresh){
|
||||
return (*_enc->opt_vtable.frag_sad_thresh)(_src,_ref,_ystride,_thresh);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride,unsigned _thresh){
|
||||
unsigned sad;
|
||||
int i;
|
||||
sad=0;
|
||||
for(i=8;i-->0;){
|
||||
int j;
|
||||
for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]);
|
||||
if(sad>_thresh)break;
|
||||
_src+=_ystride;
|
||||
_ref+=_ystride;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref1,
|
||||
const unsigned char *_ref2,int _ystride,unsigned _thresh){
|
||||
return (*_enc->opt_vtable.frag_sad2_thresh)(_src,_ref1,_ref2,_ystride,
|
||||
_thresh);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
|
||||
unsigned _thresh){
|
||||
unsigned sad;
|
||||
int i;
|
||||
sad=0;
|
||||
for(i=8;i-->0;){
|
||||
int j;
|
||||
for(j=0;j<8;j++)sad+=abs(_src[j]-(_ref1[j]+_ref2[j]>>1));
|
||||
if(sad>_thresh)break;
|
||||
_src+=_ystride;
|
||||
_ref1+=_ystride;
|
||||
_ref2+=_ystride;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
static void oc_diff_hadamard(ogg_int16_t _buf[64],const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int t4;
|
||||
int t5;
|
||||
int t6;
|
||||
int t7;
|
||||
int r;
|
||||
/*Hadamard stage 1:*/
|
||||
t0=_src[0]-_ref[0]+_src[4]-_ref[4];
|
||||
t4=_src[0]-_ref[0]-_src[4]+_ref[4];
|
||||
t1=_src[1]-_ref[1]+_src[5]-_ref[5];
|
||||
t5=_src[1]-_ref[1]-_src[5]+_ref[5];
|
||||
t2=_src[2]-_ref[2]+_src[6]-_ref[6];
|
||||
t6=_src[2]-_ref[2]-_src[6]+_ref[6];
|
||||
t3=_src[3]-_ref[3]+_src[7]-_ref[7];
|
||||
t7=_src[3]-_ref[3]-_src[7]+_ref[7];
|
||||
/*Hadamard stage 2:*/
|
||||
r=t0;
|
||||
t0+=t2;
|
||||
t2=r-t2;
|
||||
r=t1;
|
||||
t1+=t3;
|
||||
t3=r-t3;
|
||||
r=t4;
|
||||
t4+=t6;
|
||||
t6=r-t6;
|
||||
r=t5;
|
||||
t5+=t7;
|
||||
t7=r-t7;
|
||||
/*Hadamard stage 3:*/
|
||||
_buf[0*8+i]=(ogg_int16_t)(t0+t1);
|
||||
_buf[1*8+i]=(ogg_int16_t)(t0-t1);
|
||||
_buf[2*8+i]=(ogg_int16_t)(t2+t3);
|
||||
_buf[3*8+i]=(ogg_int16_t)(t2-t3);
|
||||
_buf[4*8+i]=(ogg_int16_t)(t4+t5);
|
||||
_buf[5*8+i]=(ogg_int16_t)(t4-t5);
|
||||
_buf[6*8+i]=(ogg_int16_t)(t6+t7);
|
||||
_buf[7*8+i]=(ogg_int16_t)(t6-t7);
|
||||
_src+=_ystride;
|
||||
_ref+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
static void oc_diff_hadamard2(ogg_int16_t _buf[64],const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int t4;
|
||||
int t5;
|
||||
int t6;
|
||||
int t7;
|
||||
int r;
|
||||
/*Hadamard stage 1:*/
|
||||
r=_ref1[0]+_ref2[0]>>1;
|
||||
t4=_ref1[4]+_ref2[4]>>1;
|
||||
t0=_src[0]-r+_src[4]-t4;
|
||||
t4=_src[0]-r-_src[4]+t4;
|
||||
r=_ref1[1]+_ref2[1]>>1;
|
||||
t5=_ref1[5]+_ref2[5]>>1;
|
||||
t1=_src[1]-r+_src[5]-t5;
|
||||
t5=_src[1]-r-_src[5]+t5;
|
||||
r=_ref1[2]+_ref2[2]>>1;
|
||||
t6=_ref1[6]+_ref2[6]>>1;
|
||||
t2=_src[2]-r+_src[6]-t6;
|
||||
t6=_src[2]-r-_src[6]+t6;
|
||||
r=_ref1[3]+_ref2[3]>>1;
|
||||
t7=_ref1[7]+_ref2[7]>>1;
|
||||
t3=_src[3]-r+_src[7]-t7;
|
||||
t7=_src[3]-r-_src[7]+t7;
|
||||
/*Hadamard stage 2:*/
|
||||
r=t0;
|
||||
t0+=t2;
|
||||
t2=r-t2;
|
||||
r=t1;
|
||||
t1+=t3;
|
||||
t3=r-t3;
|
||||
r=t4;
|
||||
t4+=t6;
|
||||
t6=r-t6;
|
||||
r=t5;
|
||||
t5+=t7;
|
||||
t7=r-t7;
|
||||
/*Hadamard stage 3:*/
|
||||
_buf[0*8+i]=(ogg_int16_t)(t0+t1);
|
||||
_buf[1*8+i]=(ogg_int16_t)(t0-t1);
|
||||
_buf[2*8+i]=(ogg_int16_t)(t2+t3);
|
||||
_buf[3*8+i]=(ogg_int16_t)(t2-t3);
|
||||
_buf[4*8+i]=(ogg_int16_t)(t4+t5);
|
||||
_buf[5*8+i]=(ogg_int16_t)(t4-t5);
|
||||
_buf[6*8+i]=(ogg_int16_t)(t6+t7);
|
||||
_buf[7*8+i]=(ogg_int16_t)(t6-t7);
|
||||
_src+=_ystride;
|
||||
_ref1+=_ystride;
|
||||
_ref2+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
static void oc_intra_hadamard(ogg_int16_t _buf[64],const unsigned char *_src,
|
||||
int _ystride){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int t4;
|
||||
int t5;
|
||||
int t6;
|
||||
int t7;
|
||||
int r;
|
||||
/*Hadamard stage 1:*/
|
||||
t0=_src[0]+_src[4];
|
||||
t4=_src[0]-_src[4];
|
||||
t1=_src[1]+_src[5];
|
||||
t5=_src[1]-_src[5];
|
||||
t2=_src[2]+_src[6];
|
||||
t6=_src[2]-_src[6];
|
||||
t3=_src[3]+_src[7];
|
||||
t7=_src[3]-_src[7];
|
||||
/*Hadamard stage 2:*/
|
||||
r=t0;
|
||||
t0+=t2;
|
||||
t2=r-t2;
|
||||
r=t1;
|
||||
t1+=t3;
|
||||
t3=r-t3;
|
||||
r=t4;
|
||||
t4+=t6;
|
||||
t6=r-t6;
|
||||
r=t5;
|
||||
t5+=t7;
|
||||
t7=r-t7;
|
||||
/*Hadamard stage 3:*/
|
||||
_buf[0*8+i]=(ogg_int16_t)(t0+t1);
|
||||
_buf[1*8+i]=(ogg_int16_t)(t0-t1);
|
||||
_buf[2*8+i]=(ogg_int16_t)(t2+t3);
|
||||
_buf[3*8+i]=(ogg_int16_t)(t2-t3);
|
||||
_buf[4*8+i]=(ogg_int16_t)(t4+t5);
|
||||
_buf[5*8+i]=(ogg_int16_t)(t4-t5);
|
||||
_buf[6*8+i]=(ogg_int16_t)(t6+t7);
|
||||
_buf[7*8+i]=(ogg_int16_t)(t6-t7);
|
||||
_src+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned oc_hadamard_sad_thresh(const ogg_int16_t _buf[64],unsigned _thresh){
|
||||
unsigned sad;
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int t4;
|
||||
int t5;
|
||||
int t6;
|
||||
int t7;
|
||||
int r;
|
||||
int i;
|
||||
sad=0;
|
||||
for(i=0;i<8;i++){
|
||||
/*Hadamard stage 1:*/
|
||||
t0=_buf[i*8+0]+_buf[i*8+4];
|
||||
t4=_buf[i*8+0]-_buf[i*8+4];
|
||||
t1=_buf[i*8+1]+_buf[i*8+5];
|
||||
t5=_buf[i*8+1]-_buf[i*8+5];
|
||||
t2=_buf[i*8+2]+_buf[i*8+6];
|
||||
t6=_buf[i*8+2]-_buf[i*8+6];
|
||||
t3=_buf[i*8+3]+_buf[i*8+7];
|
||||
t7=_buf[i*8+3]-_buf[i*8+7];
|
||||
/*Hadamard stage 2:*/
|
||||
r=t0;
|
||||
t0+=t2;
|
||||
t2=r-t2;
|
||||
r=t1;
|
||||
t1+=t3;
|
||||
t3=r-t3;
|
||||
r=t4;
|
||||
t4+=t6;
|
||||
t6=r-t6;
|
||||
r=t5;
|
||||
t5+=t7;
|
||||
t7=r-t7;
|
||||
/*Hadamard stage 3:*/
|
||||
r=abs(t0+t1);
|
||||
r+=abs(t0-t1);
|
||||
r+=abs(t2+t3);
|
||||
r+=abs(t2-t3);
|
||||
r+=abs(t4+t5);
|
||||
r+=abs(t4-t5);
|
||||
r+=abs(t6+t7);
|
||||
r+=abs(t6-t7);
|
||||
sad+=r;
|
||||
if(sad>_thresh)break;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride,
|
||||
unsigned _thresh){
|
||||
return (*_enc->opt_vtable.frag_satd_thresh)(_src,_ref,_ystride,_thresh);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride,unsigned _thresh){
|
||||
ogg_int16_t buf[64];
|
||||
oc_diff_hadamard(buf,_src,_ref,_ystride);
|
||||
return oc_hadamard_sad_thresh(buf,_thresh);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref1,
|
||||
const unsigned char *_ref2,int _ystride,unsigned _thresh){
|
||||
return (*_enc->opt_vtable.frag_satd2_thresh)(_src,_ref1,_ref2,_ystride,
|
||||
_thresh);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
|
||||
unsigned _thresh){
|
||||
ogg_int16_t buf[64];
|
||||
oc_diff_hadamard2(buf,_src,_ref1,_ref2,_ystride);
|
||||
return oc_hadamard_sad_thresh(buf,_thresh);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,int _ystride){
|
||||
return (*_enc->opt_vtable.frag_intra_satd)(_src,_ystride);
|
||||
}
|
||||
|
||||
unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride){
|
||||
ogg_int16_t buf[64];
|
||||
oc_intra_hadamard(buf,_src,_ystride);
|
||||
return oc_hadamard_sad_thresh(buf,UINT_MAX)
|
||||
-abs(buf[0]+buf[1]+buf[2]+buf[3]+buf[4]+buf[5]+buf[6]+buf[7]);
|
||||
}
|
||||
|
||||
void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst,
|
||||
const unsigned char *_src1,const unsigned char *_src2,int _ystride){
|
||||
(*_enc->opt_vtable.frag_copy2)(_dst,_src1,_src2,_ystride);
|
||||
}
|
||||
|
||||
void oc_enc_frag_copy2_c(unsigned char *_dst,
|
||||
const unsigned char *_src1,const unsigned char *_src2,int _ystride){
|
||||
int i;
|
||||
int j;
|
||||
for(i=8;i-->0;){
|
||||
for(j=0;j<8;j++)_dst[j]=_src1[j]+_src2[j]>>1;
|
||||
_dst+=_ystride;
|
||||
_src1+=_ystride;
|
||||
_src2+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc,
|
||||
unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]){
|
||||
(*_enc->opt_vtable.frag_recon_intra)(_dst,_ystride,_residue);
|
||||
}
|
||||
|
||||
void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst,
|
||||
const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){
|
||||
(*_enc->opt_vtable.frag_recon_inter)(_dst,_src,_ystride,_residue);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "internal.h"
|
||||
#include "enquant.h"
|
||||
#include "huffenc.h"
|
||||
|
||||
|
||||
|
||||
/*Packs a series of octets from a given byte array into the pack buffer.
|
||||
_opb: The pack buffer to store the octets in.
|
||||
_buf: The byte array containing the bytes to pack.
|
||||
_len: The number of octets to pack.*/
|
||||
static void oc_pack_octets(oggpack_buffer *_opb,const char *_buf,int _len){
|
||||
int i;
|
||||
for(i=0;i<_len;i++)oggpackB_write(_opb,_buf[i],8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int oc_state_flushheader(oc_theora_state *_state,int *_packet_state,
|
||||
oggpack_buffer *_opb,const th_quant_info *_qinfo,
|
||||
const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS],
|
||||
const char *_vendor,th_comment *_tc,ogg_packet *_op){
|
||||
unsigned char *packet;
|
||||
int b_o_s;
|
||||
if(_op==NULL)return TH_EFAULT;
|
||||
switch(*_packet_state){
|
||||
/*Codec info header.*/
|
||||
case OC_PACKET_INFO_HDR:{
|
||||
if(_state==NULL)return TH_EFAULT;
|
||||
oggpackB_reset(_opb);
|
||||
/*Mark this packet as the info header.*/
|
||||
oggpackB_write(_opb,0x80,8);
|
||||
/*Write the codec string.*/
|
||||
oc_pack_octets(_opb,"theora",6);
|
||||
/*Write the codec bitstream version.*/
|
||||
oggpackB_write(_opb,TH_VERSION_MAJOR,8);
|
||||
oggpackB_write(_opb,TH_VERSION_MINOR,8);
|
||||
oggpackB_write(_opb,TH_VERSION_SUB,8);
|
||||
/*Describe the encoded frame.*/
|
||||
oggpackB_write(_opb,_state->info.frame_width>>4,16);
|
||||
oggpackB_write(_opb,_state->info.frame_height>>4,16);
|
||||
oggpackB_write(_opb,_state->info.pic_width,24);
|
||||
oggpackB_write(_opb,_state->info.pic_height,24);
|
||||
oggpackB_write(_opb,_state->info.pic_x,8);
|
||||
oggpackB_write(_opb,_state->info.pic_y,8);
|
||||
oggpackB_write(_opb,_state->info.fps_numerator,32);
|
||||
oggpackB_write(_opb,_state->info.fps_denominator,32);
|
||||
oggpackB_write(_opb,_state->info.aspect_numerator,24);
|
||||
oggpackB_write(_opb,_state->info.aspect_denominator,24);
|
||||
oggpackB_write(_opb,_state->info.colorspace,8);
|
||||
oggpackB_write(_opb,_state->info.target_bitrate,24);
|
||||
oggpackB_write(_opb,_state->info.quality,6);
|
||||
oggpackB_write(_opb,_state->info.keyframe_granule_shift,5);
|
||||
oggpackB_write(_opb,_state->info.pixel_fmt,2);
|
||||
/*Spare configuration bits.*/
|
||||
oggpackB_write(_opb,0,3);
|
||||
b_o_s=1;
|
||||
}break;
|
||||
/*Comment header.*/
|
||||
case OC_PACKET_COMMENT_HDR:{
|
||||
int vendor_len;
|
||||
int i;
|
||||
if(_tc==NULL)return TH_EFAULT;
|
||||
vendor_len=strlen(_vendor);
|
||||
oggpackB_reset(_opb);
|
||||
/*Mark this packet as the comment header.*/
|
||||
oggpackB_write(_opb,0x81,8);
|
||||
/*Write the codec string.*/
|
||||
oc_pack_octets(_opb,"theora",6);
|
||||
/*Write the vendor string.*/
|
||||
oggpack_write(_opb,vendor_len,32);
|
||||
oc_pack_octets(_opb,_vendor,vendor_len);
|
||||
oggpack_write(_opb,_tc->comments,32);
|
||||
for(i=0;i<_tc->comments;i++){
|
||||
if(_tc->user_comments[i]!=NULL){
|
||||
oggpack_write(_opb,_tc->comment_lengths[i],32);
|
||||
oc_pack_octets(_opb,_tc->user_comments[i],_tc->comment_lengths[i]);
|
||||
}
|
||||
else oggpack_write(_opb,0,32);
|
||||
}
|
||||
b_o_s=0;
|
||||
}break;
|
||||
/*Codec setup header.*/
|
||||
case OC_PACKET_SETUP_HDR:{
|
||||
int ret;
|
||||
oggpackB_reset(_opb);
|
||||
/*Mark this packet as the setup header.*/
|
||||
oggpackB_write(_opb,0x82,8);
|
||||
/*Write the codec string.*/
|
||||
oc_pack_octets(_opb,"theora",6);
|
||||
/*Write the quantizer tables.*/
|
||||
oc_quant_params_pack(_opb,_qinfo);
|
||||
/*Write the huffman codes.*/
|
||||
ret=oc_huff_codes_pack(_opb,_codes);
|
||||
/*This should never happen, because we validate the tables when they
|
||||
are set.
|
||||
If you see, it's a good chance memory is being corrupted.*/
|
||||
if(ret<0)return ret;
|
||||
b_o_s=0;
|
||||
}break;
|
||||
/*No more headers to emit.*/
|
||||
default:return 0;
|
||||
}
|
||||
/*This is kind of fugly: we hand the user a buffer which they do not own.
|
||||
We will overwrite it when the next packet is output, so the user better be
|
||||
done with it by then.
|
||||
Vorbis is little better: it hands back buffers that it will free the next
|
||||
time the headers are requested, or when the encoder is cleared.
|
||||
Hopefully libogg2 will make this much cleaner.*/
|
||||
packet=oggpackB_get_buffer(_opb);
|
||||
/*If there's no packet, malloc failed while writing.*/
|
||||
if(packet==NULL)return TH_EFAULT;
|
||||
_op->packet=packet;
|
||||
_op->bytes=oggpackB_bytes(_opb);
|
||||
_op->b_o_s=b_o_s;
|
||||
_op->e_o_s=0;
|
||||
_op->granulepos=0;
|
||||
_op->packetno=*_packet_state+3;
|
||||
return ++(*_packet_state)+3;
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: encint.h 16753 2009-12-19 00:52:46Z tterribe $
|
||||
|
||||
********************************************************************/
|
||||
#if !defined(_encint_H)
|
||||
# define _encint_H (1)
|
||||
# include "theora/theoraenc.h"
|
||||
# include "internal.h"
|
||||
# include "ocintrin.h"
|
||||
# include "mathops.h"
|
||||
# include "enquant.h"
|
||||
# include "huffenc.h"
|
||||
/*# define OC_COLLECT_METRICS*/
|
||||
|
||||
|
||||
|
||||
typedef oc_mv oc_mv2[2];
|
||||
|
||||
typedef struct oc_enc_opt_vtable oc_enc_opt_vtable;
|
||||
typedef struct oc_mb_enc_info oc_mb_enc_info;
|
||||
typedef struct oc_mode_scheme_chooser oc_mode_scheme_chooser;
|
||||
typedef struct oc_iir_filter oc_iir_filter;
|
||||
typedef struct oc_frame_metrics oc_frame_metrics;
|
||||
typedef struct oc_rc_state oc_rc_state;
|
||||
typedef struct th_enc_ctx oc_enc_ctx;
|
||||
typedef struct oc_token_checkpoint oc_token_checkpoint;
|
||||
|
||||
|
||||
|
||||
/*Constants for the packet-out state machine specific to the encoder.*/
|
||||
|
||||
/*Next packet to emit: Data packet, but none are ready yet.*/
|
||||
#define OC_PACKET_EMPTY (0)
|
||||
/*Next packet to emit: Data packet, and one is ready.*/
|
||||
#define OC_PACKET_READY (1)
|
||||
|
||||
/*All features enabled.*/
|
||||
#define OC_SP_LEVEL_SLOW (0)
|
||||
/*Enable early skip.*/
|
||||
#define OC_SP_LEVEL_EARLY_SKIP (1)
|
||||
/*Disable motion compensation.*/
|
||||
#define OC_SP_LEVEL_NOMC (2)
|
||||
/*Maximum valid speed level.*/
|
||||
#define OC_SP_LEVEL_MAX (2)
|
||||
|
||||
|
||||
/*The bits used for each of the MB mode codebooks.*/
|
||||
extern const unsigned char OC_MODE_BITS[2][OC_NMODES];
|
||||
|
||||
/*The bits used for each of the MV codebooks.*/
|
||||
extern const unsigned char OC_MV_BITS[2][64];
|
||||
|
||||
/*The minimum value that can be stored in a SB run for each codeword.
|
||||
The last entry is the upper bound on the length of a single SB run.*/
|
||||
extern const ogg_uint16_t OC_SB_RUN_VAL_MIN[8];
|
||||
/*The bits used for each SB run codeword.*/
|
||||
extern const unsigned char OC_SB_RUN_CODE_NBITS[7];
|
||||
|
||||
/*The bits used for each block run length (starting with 1).*/
|
||||
extern const unsigned char OC_BLOCK_RUN_CODE_NBITS[30];
|
||||
|
||||
|
||||
|
||||
/*Encoder specific functions with accelerated variants.*/
|
||||
struct oc_enc_opt_vtable{
|
||||
unsigned (*frag_sad)(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride);
|
||||
unsigned (*frag_sad_thresh)(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride,unsigned _thresh);
|
||||
unsigned (*frag_sad2_thresh)(const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
|
||||
unsigned _thresh);
|
||||
unsigned (*frag_satd_thresh)(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride,unsigned _thresh);
|
||||
unsigned (*frag_satd2_thresh)(const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
|
||||
unsigned _thresh);
|
||||
unsigned (*frag_intra_satd)(const unsigned char *_src,int _ystride);
|
||||
void (*frag_sub)(ogg_int16_t _diff[64],const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride);
|
||||
void (*frag_sub_128)(ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,int _ystride);
|
||||
void (*frag_copy2)(unsigned char *_dst,
|
||||
const unsigned char *_src1,const unsigned char *_src2,int _ystride);
|
||||
void (*frag_recon_intra)(unsigned char *_dst,int _ystride,
|
||||
const ogg_int16_t _residue[64]);
|
||||
void (*frag_recon_inter)(unsigned char *_dst,
|
||||
const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]);
|
||||
void (*fdct8x8)(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
|
||||
};
|
||||
|
||||
|
||||
void oc_enc_vtable_init(oc_enc_ctx *_enc);
|
||||
|
||||
|
||||
|
||||
/*Encoder-specific macroblock information.*/
|
||||
struct oc_mb_enc_info{
|
||||
/*Neighboring macro blocks that have MVs available from the current frame.*/
|
||||
unsigned cneighbors[4];
|
||||
/*Neighboring macro blocks to use for MVs from the previous frame.*/
|
||||
unsigned pneighbors[4];
|
||||
/*The number of current-frame neighbors.*/
|
||||
unsigned char ncneighbors;
|
||||
/*The number of previous-frame neighbors.*/
|
||||
unsigned char npneighbors;
|
||||
/*Flags indicating which MB modes have been refined.*/
|
||||
unsigned char refined;
|
||||
/*Motion vectors for a macro block for the current frame and the
|
||||
previous two frames.
|
||||
Each is a set of 2 vectors against OC_FRAME_GOLD and OC_FRAME_PREV, which
|
||||
can be used to estimate constant velocity and constant acceleration
|
||||
predictors.
|
||||
Uninitialized MVs are (0,0).*/
|
||||
oc_mv2 analysis_mv[3];
|
||||
/*Current unrefined analysis MVs.*/
|
||||
oc_mv unref_mv[2];
|
||||
/*Unrefined block MVs.*/
|
||||
oc_mv block_mv[4];
|
||||
/*Refined block MVs.*/
|
||||
oc_mv ref_mv[4];
|
||||
/*Minimum motion estimation error from the analysis stage.*/
|
||||
ogg_uint16_t error[2];
|
||||
/*MB error for half-pel refinement for each frame type.*/
|
||||
unsigned satd[2];
|
||||
/*Block error for half-pel refinement.*/
|
||||
unsigned block_satd[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*State machine to estimate the opportunity cost of coding a MB mode.*/
|
||||
struct oc_mode_scheme_chooser{
|
||||
/*Pointers to the a list containing the index of each mode in the mode
|
||||
alphabet used by each scheme.
|
||||
The first entry points to the dynamic scheme0_ranks, while the remaining 7
|
||||
point to the constant entries stored in OC_MODE_SCHEMES.*/
|
||||
const unsigned char *mode_ranks[8];
|
||||
/*The ranks for each mode when coded with scheme 0.
|
||||
These are optimized so that the more frequent modes have lower ranks.*/
|
||||
unsigned char scheme0_ranks[OC_NMODES];
|
||||
/*The list of modes, sorted in descending order of frequency, that
|
||||
corresponds to the ranks above.*/
|
||||
unsigned char scheme0_list[OC_NMODES];
|
||||
/*The number of times each mode has been chosen so far.*/
|
||||
int mode_counts[OC_NMODES];
|
||||
/*The list of mode coding schemes, sorted in ascending order of bit cost.*/
|
||||
unsigned char scheme_list[8];
|
||||
/*The number of bits used by each mode coding scheme.*/
|
||||
ptrdiff_t scheme_bits[8];
|
||||
};
|
||||
|
||||
|
||||
void oc_mode_scheme_chooser_init(oc_mode_scheme_chooser *_chooser);
|
||||
|
||||
|
||||
|
||||
/*A 2nd order low-pass Bessel follower.
|
||||
We use this for rate control because it has fast reaction time, but is
|
||||
critically damped.*/
|
||||
struct oc_iir_filter{
|
||||
ogg_int32_t c[2];
|
||||
ogg_int64_t g;
|
||||
ogg_int32_t x[2];
|
||||
ogg_int32_t y[2];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*The 2-pass metrics associated with a single frame.*/
|
||||
struct oc_frame_metrics{
|
||||
/*The log base 2 of the scale factor for this frame in Q24 format.*/
|
||||
ogg_int32_t log_scale;
|
||||
/*The number of application-requested duplicates of this frame.*/
|
||||
unsigned dup_count:31;
|
||||
/*The frame type from pass 1.*/
|
||||
unsigned frame_type:1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*Rate control state information.*/
|
||||
struct oc_rc_state{
|
||||
/*The target average bits per frame.*/
|
||||
ogg_int64_t bits_per_frame;
|
||||
/*The current buffer fullness (bits available to be used).*/
|
||||
ogg_int64_t fullness;
|
||||
/*The target buffer fullness.
|
||||
This is where we'd like to be by the last keyframe the appears in the next
|
||||
buf_delay frames.*/
|
||||
ogg_int64_t target;
|
||||
/*The maximum buffer fullness (total size of the buffer).*/
|
||||
ogg_int64_t max;
|
||||
/*The log of the number of pixels in a frame in Q57 format.*/
|
||||
ogg_int64_t log_npixels;
|
||||
/*The exponent used in the rate model in Q8 format.*/
|
||||
unsigned exp[2];
|
||||
/*The number of frames to distribute the buffer usage over.*/
|
||||
int buf_delay;
|
||||
/*The total drop count from the previous frame.
|
||||
This includes duplicates explicitly requested via the
|
||||
TH_ENCCTL_SET_DUP_COUNT API as well as frames we chose to drop ourselves.*/
|
||||
ogg_uint32_t prev_drop_count;
|
||||
/*The log of an estimated scale factor used to obtain the real framerate, for
|
||||
VFR sources or, e.g., 12 fps content doubled to 24 fps, etc.*/
|
||||
ogg_int64_t log_drop_scale;
|
||||
/*The log of estimated scale factor for the rate model in Q57 format.*/
|
||||
ogg_int64_t log_scale[2];
|
||||
/*The log of the target quantizer level in Q57 format.*/
|
||||
ogg_int64_t log_qtarget;
|
||||
/*Will we drop frames to meet bitrate target?*/
|
||||
unsigned char drop_frames;
|
||||
/*Do we respect the maximum buffer fullness?*/
|
||||
unsigned char cap_overflow;
|
||||
/*Can the reservoir go negative?*/
|
||||
unsigned char cap_underflow;
|
||||
/*Second-order lowpass filters to track scale and VFR.*/
|
||||
oc_iir_filter scalefilter[2];
|
||||
int inter_count;
|
||||
int inter_delay;
|
||||
int inter_delay_target;
|
||||
oc_iir_filter vfrfilter;
|
||||
/*Two-pass mode state.
|
||||
0 => 1-pass encoding.
|
||||
1 => 1st pass of 2-pass encoding.
|
||||
2 => 2nd pass of 2-pass encoding.*/
|
||||
int twopass;
|
||||
/*Buffer for current frame metrics.*/
|
||||
unsigned char twopass_buffer[48];
|
||||
/*The number of bytes in the frame metrics buffer.
|
||||
When 2-pass encoding is enabled, this is set to 0 after each frame is
|
||||
submitted, and must be non-zero before the next frame will be accepted.*/
|
||||
int twopass_buffer_bytes;
|
||||
int twopass_buffer_fill;
|
||||
/*Whether or not to force the next frame to be a keyframe.*/
|
||||
unsigned char twopass_force_kf;
|
||||
/*The metrics for the previous frame.*/
|
||||
oc_frame_metrics prev_metrics;
|
||||
/*The metrics for the current frame.*/
|
||||
oc_frame_metrics cur_metrics;
|
||||
/*The buffered metrics for future frames.*/
|
||||
oc_frame_metrics *frame_metrics;
|
||||
int nframe_metrics;
|
||||
int cframe_metrics;
|
||||
/*The index of the current frame in the circular metric buffer.*/
|
||||
int frame_metrics_head;
|
||||
/*The frame count of each type (keyframes, delta frames, and dup frames);
|
||||
32 bits limits us to 2.268 years at 60 fps.*/
|
||||
ogg_uint32_t frames_total[3];
|
||||
/*The number of frames of each type yet to be processed.*/
|
||||
ogg_uint32_t frames_left[3];
|
||||
/*The sum of the scale values for each frame type.*/
|
||||
ogg_int64_t scale_sum[2];
|
||||
/*The start of the window over which the current scale sums are taken.*/
|
||||
int scale_window0;
|
||||
/*The end of the window over which the current scale sums are taken.*/
|
||||
int scale_window_end;
|
||||
/*The frame count of each type in the current 2-pass window; this does not
|
||||
include dup frames.*/
|
||||
int nframes[3];
|
||||
/*The total accumulated estimation bias.*/
|
||||
ogg_int64_t rate_bias;
|
||||
};
|
||||
|
||||
|
||||
void oc_rc_state_init(oc_rc_state *_rc,oc_enc_ctx *_enc);
|
||||
void oc_rc_state_clear(oc_rc_state *_rc);
|
||||
|
||||
void oc_enc_rc_resize(oc_enc_ctx *_enc);
|
||||
int oc_enc_select_qi(oc_enc_ctx *_enc,int _qti,int _clamp);
|
||||
void oc_enc_calc_lambda(oc_enc_ctx *_enc,int _frame_type);
|
||||
int oc_enc_update_rc_state(oc_enc_ctx *_enc,
|
||||
long _bits,int _qti,int _qi,int _trial,int _droppable);
|
||||
int oc_enc_rc_2pass_out(oc_enc_ctx *_enc,unsigned char **_buf);
|
||||
int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes);
|
||||
|
||||
|
||||
|
||||
/*The internal encoder state.*/
|
||||
struct th_enc_ctx{
|
||||
/*Shared encoder/decoder state.*/
|
||||
oc_theora_state state;
|
||||
/*Buffer in which to assemble packets.*/
|
||||
oggpack_buffer opb;
|
||||
/*Encoder-specific macroblock information.*/
|
||||
oc_mb_enc_info *mb_info;
|
||||
/*DC coefficients after prediction.*/
|
||||
ogg_int16_t *frag_dc;
|
||||
/*The list of coded macro blocks, in coded order.*/
|
||||
unsigned *coded_mbis;
|
||||
/*The number of coded macro blocks.*/
|
||||
size_t ncoded_mbis;
|
||||
/*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 becomes
|
||||
positive when a frame has been processed and data packets are ready.*/
|
||||
int packet_state;
|
||||
/*The maximum distance between keyframes.*/
|
||||
ogg_uint32_t keyframe_frequency_force;
|
||||
/*The number of duplicates to produce for the next frame.*/
|
||||
ogg_uint32_t dup_count;
|
||||
/*The number of duplicates remaining to be emitted for the current frame.*/
|
||||
ogg_uint32_t nqueued_dups;
|
||||
/*The number of duplicates emitted for the last frame.*/
|
||||
ogg_uint32_t prev_dup_count;
|
||||
/*The current speed level.*/
|
||||
int sp_level;
|
||||
/*Whether or not VP3 compatibility mode has been enabled.*/
|
||||
unsigned char vp3_compatible;
|
||||
/*Whether or not any INTER frames have been coded.*/
|
||||
unsigned char coded_inter_frame;
|
||||
/*Whether or not previous frame was dropped.*/
|
||||
unsigned char prevframe_dropped;
|
||||
/*Stores most recently chosen Huffman tables for each frame type, DC and AC
|
||||
coefficients, and luma and chroma tokens.
|
||||
The actual Huffman table used for a given coefficient depends not only on
|
||||
the choice made here, but also its index in the zig-zag ordering.*/
|
||||
unsigned char huff_idxs[2][2][2];
|
||||
/*Current count of bits used by each MV coding mode.*/
|
||||
size_t mv_bits[2];
|
||||
/*The mode scheme chooser for estimating mode coding costs.*/
|
||||
oc_mode_scheme_chooser chooser;
|
||||
/*The number of vertical super blocks in an MCU.*/
|
||||
int mcu_nvsbs;
|
||||
/*The SSD error for skipping each fragment in the current MCU.*/
|
||||
unsigned *mcu_skip_ssd;
|
||||
/*The DCT token lists for each coefficient and each plane.*/
|
||||
unsigned char **dct_tokens[3];
|
||||
/*The extra bits associated with each DCT token.*/
|
||||
ogg_uint16_t **extra_bits[3];
|
||||
/*The number of DCT tokens for each coefficient for each plane.*/
|
||||
ptrdiff_t ndct_tokens[3][64];
|
||||
/*Pending EOB runs for each coefficient for each plane.*/
|
||||
ogg_uint16_t eob_run[3][64];
|
||||
/*The offset of the first DCT token for each coefficient for each plane.*/
|
||||
unsigned char dct_token_offs[3][64];
|
||||
/*The last DC coefficient for each plane and reference frame.*/
|
||||
int dc_pred_last[3][3];
|
||||
#if defined(OC_COLLECT_METRICS)
|
||||
/*Fragment SATD statistics for MB mode estimation metrics.*/
|
||||
unsigned *frag_satd;
|
||||
/*Fragment SSD statistics for MB mode estimation metrics.*/
|
||||
unsigned *frag_ssd;
|
||||
#endif
|
||||
/*The R-D optimization parameter.*/
|
||||
int lambda;
|
||||
/*The huffman tables in use.*/
|
||||
th_huff_code huff_codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
|
||||
/*The quantization parameters in use.*/
|
||||
th_quant_info qinfo;
|
||||
oc_iquant *enquant_tables[64][3][2];
|
||||
oc_iquant_table enquant_table_data[64][3][2];
|
||||
/*An "average" quantizer for each quantizer type (INTRA or INTER) and qi
|
||||
value.
|
||||
This is used to paramterize the rate control decisions.
|
||||
They are kept in the log domain to simplify later processing.
|
||||
Keep in mind these are DCT domain quantizers, and so are scaled by an
|
||||
additional factor of 4 from the pixel domain.*/
|
||||
ogg_int64_t log_qavg[2][64];
|
||||
/*The buffer state used to drive rate control.*/
|
||||
oc_rc_state rc;
|
||||
/*Table for encoder acceleration functions.*/
|
||||
oc_enc_opt_vtable opt_vtable;
|
||||
};
|
||||
|
||||
|
||||
void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode);
|
||||
int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode);
|
||||
#if defined(OC_COLLECT_METRICS)
|
||||
void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc);
|
||||
void oc_enc_mode_metrics_dump(oc_enc_ctx *_enc);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*Perform fullpel motion search for a single MB against both reference frames.*/
|
||||
void oc_mcenc_search(oc_enc_ctx *_enc,int _mbi);
|
||||
/*Refine a MB MV for one frame.*/
|
||||
void oc_mcenc_refine1mv(oc_enc_ctx *_enc,int _mbi,int _frame);
|
||||
/*Refine the block MVs.*/
|
||||
void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi);
|
||||
|
||||
|
||||
|
||||
/*Used to rollback a tokenlog transaction when we retroactively decide to skip
|
||||
a fragment.
|
||||
A checkpoint is taken right before each token is added.*/
|
||||
struct oc_token_checkpoint{
|
||||
/*The color plane the token was added to.*/
|
||||
unsigned char pli;
|
||||
/*The zig-zag index the token was added to.*/
|
||||
unsigned char zzi;
|
||||
/*The outstanding EOB run count before the token was added.*/
|
||||
ogg_uint16_t eob_run;
|
||||
/*The token count before the token was added.*/
|
||||
ptrdiff_t ndct_tokens;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void oc_enc_tokenize_start(oc_enc_ctx *_enc);
|
||||
int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi,
|
||||
ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct,
|
||||
int _zzi,oc_token_checkpoint **_stack,int _acmin);
|
||||
void oc_enc_tokenlog_rollback(oc_enc_ctx *_enc,
|
||||
const oc_token_checkpoint *_stack,int _n);
|
||||
void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc,
|
||||
int _pli,int _fragy0,int _frag_yend);
|
||||
void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli,
|
||||
const ptrdiff_t *_coded_fragis,ptrdiff_t _ncoded_fragis,
|
||||
int _prev_ndct_tokens1,int _prev_eob_run1);
|
||||
void oc_enc_tokenize_finish(oc_enc_ctx *_enc);
|
||||
|
||||
|
||||
|
||||
/*Utility routine to encode one of the header packets.*/
|
||||
int oc_state_flushheader(oc_theora_state *_state,int *_packet_state,
|
||||
oggpack_buffer *_opb,const th_quant_info *_qinfo,
|
||||
const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS],
|
||||
const char *_vendor,th_comment *_tc,ogg_packet *_op);
|
||||
|
||||
|
||||
|
||||
/*Encoder-specific accelerated functions.*/
|
||||
void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride);
|
||||
void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,int _ystride);
|
||||
unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride);
|
||||
unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride,
|
||||
unsigned _thresh);
|
||||
unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref1,
|
||||
const unsigned char *_ref2,int _ystride,unsigned _thresh);
|
||||
unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride,
|
||||
unsigned _thresh);
|
||||
unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,const unsigned char *_ref1,
|
||||
const unsigned char *_ref2,int _ystride,unsigned _thresh);
|
||||
unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc,
|
||||
const unsigned char *_src,int _ystride);
|
||||
void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst,
|
||||
const unsigned char *_src1,const unsigned char *_src2,int _ystride);
|
||||
void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc,
|
||||
unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]);
|
||||
void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst,
|
||||
const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]);
|
||||
void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64],
|
||||
const ogg_int16_t _x[64]);
|
||||
|
||||
/*Default pure-C implementations.*/
|
||||
void oc_enc_vtable_init_c(oc_enc_ctx *_enc);
|
||||
|
||||
void oc_enc_frag_sub_c(ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,const unsigned char *_ref,int _ystride);
|
||||
void oc_enc_frag_sub_128_c(ogg_int16_t _diff[64],
|
||||
const unsigned char *_src,int _ystride);
|
||||
void oc_enc_frag_copy2_c(unsigned char *_dst,
|
||||
const unsigned char *_src1,const unsigned char *_src2,int _ystride);
|
||||
unsigned oc_enc_frag_sad_c(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride);
|
||||
unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride,unsigned _thresh);
|
||||
unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
|
||||
unsigned _thresh);
|
||||
unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref,int _ystride,unsigned _thresh);
|
||||
unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src,
|
||||
const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
|
||||
unsigned _thresh);
|
||||
unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride);
|
||||
void oc_enc_fdct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: encoder_disabled.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#include "apiwrapper.h"
|
||||
#include "encint.h"
|
||||
|
||||
th_enc_ctx *th_encode_alloc(const th_info *_info){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void th_encode_free(th_enc_ctx *_enc){}
|
||||
|
||||
|
||||
int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int th_encode_flushheader(th_enc_ctx *_enc,th_comment *_tc,ogg_packet *_op){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int theora_encode_init(theora_state *_te,theora_info *_ci){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int theora_encode_YUVin(theora_state *_te,yuv_buffer *_yuv){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int theora_encode_packetout(theora_state *_te,int _last_p,ogg_packet *_op){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int theora_encode_header(theora_state *_te,ogg_packet *_op){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int theora_encode_comment(theora_comment *_tc,ogg_packet *_op){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
|
||||
int theora_encode_tables(theora_state *_te,ogg_packet *_op){
|
||||
return OC_DISABLED;
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: enquant.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "encint.h"
|
||||
|
||||
|
||||
|
||||
void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo){
|
||||
const th_quant_ranges *qranges;
|
||||
const th_quant_base *base_mats[2*3*64];
|
||||
int indices[2][3][64];
|
||||
int nbase_mats;
|
||||
int nbits;
|
||||
int ci;
|
||||
int qi;
|
||||
int qri;
|
||||
int qti;
|
||||
int pli;
|
||||
int qtj;
|
||||
int plj;
|
||||
int bmi;
|
||||
int i;
|
||||
i=_qinfo->loop_filter_limits[0];
|
||||
for(qi=1;qi<64;qi++)i=OC_MAXI(i,_qinfo->loop_filter_limits[qi]);
|
||||
nbits=OC_ILOG_32(i);
|
||||
oggpackB_write(_opb,nbits,3);
|
||||
for(qi=0;qi<64;qi++){
|
||||
oggpackB_write(_opb,_qinfo->loop_filter_limits[qi],nbits);
|
||||
}
|
||||
/*580 bits for VP3.*/
|
||||
i=1;
|
||||
for(qi=0;qi<64;qi++)i=OC_MAXI(_qinfo->ac_scale[qi],i);
|
||||
nbits=OC_ILOGNZ_32(i);
|
||||
oggpackB_write(_opb,nbits-1,4);
|
||||
for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->ac_scale[qi],nbits);
|
||||
/*516 bits for VP3.*/
|
||||
i=1;
|
||||
for(qi=0;qi<64;qi++)i=OC_MAXI(_qinfo->dc_scale[qi],i);
|
||||
nbits=OC_ILOGNZ_32(i);
|
||||
oggpackB_write(_opb,nbits-1,4);
|
||||
for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->dc_scale[qi],nbits);
|
||||
/*Consolidate any duplicate base matrices.*/
|
||||
nbase_mats=0;
|
||||
for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
|
||||
qranges=_qinfo->qi_ranges[qti]+pli;
|
||||
for(qri=0;qri<=qranges->nranges;qri++){
|
||||
for(bmi=0;;bmi++){
|
||||
if(bmi>=nbase_mats){
|
||||
base_mats[bmi]=qranges->base_matrices+qri;
|
||||
indices[qti][pli][qri]=nbase_mats++;
|
||||
break;
|
||||
}
|
||||
else if(memcmp(base_mats[bmi][0],qranges->base_matrices[qri],
|
||||
sizeof(base_mats[bmi][0]))==0){
|
||||
indices[qti][pli][qri]=bmi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Write out the list of unique base matrices.
|
||||
1545 bits for VP3 matrices.*/
|
||||
oggpackB_write(_opb,nbase_mats-1,9);
|
||||
for(bmi=0;bmi<nbase_mats;bmi++){
|
||||
for(ci=0;ci<64;ci++)oggpackB_write(_opb,base_mats[bmi][0][ci],8);
|
||||
}
|
||||
/*Now store quant ranges and their associated indices into the base matrix
|
||||
list.
|
||||
46 bits for VP3 matrices.*/
|
||||
nbits=OC_ILOG_32(nbase_mats-1);
|
||||
for(i=0;i<6;i++){
|
||||
qti=i/3;
|
||||
pli=i%3;
|
||||
qranges=_qinfo->qi_ranges[qti]+pli;
|
||||
if(i>0){
|
||||
if(qti>0){
|
||||
if(qranges->nranges==_qinfo->qi_ranges[qti-1][pli].nranges&&
|
||||
memcmp(qranges->sizes,_qinfo->qi_ranges[qti-1][pli].sizes,
|
||||
qranges->nranges*sizeof(qranges->sizes[0]))==0&&
|
||||
memcmp(indices[qti][pli],indices[qti-1][pli],
|
||||
(qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){
|
||||
oggpackB_write(_opb,1,2);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
qtj=(i-1)/3;
|
||||
plj=(i-1)%3;
|
||||
if(qranges->nranges==_qinfo->qi_ranges[qtj][plj].nranges&&
|
||||
memcmp(qranges->sizes,_qinfo->qi_ranges[qtj][plj].sizes,
|
||||
qranges->nranges*sizeof(qranges->sizes[0]))==0&&
|
||||
memcmp(indices[qti][pli],indices[qtj][plj],
|
||||
(qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){
|
||||
oggpackB_write(_opb,0,1+(qti>0));
|
||||
continue;
|
||||
}
|
||||
oggpackB_write(_opb,1,1);
|
||||
}
|
||||
oggpackB_write(_opb,indices[qti][pli][0],nbits);
|
||||
for(qi=qri=0;qi<63;qri++){
|
||||
oggpackB_write(_opb,qranges->sizes[qri]-1,OC_ILOG_32(62-qi));
|
||||
qi+=qranges->sizes[qri];
|
||||
oggpackB_write(_opb,indices[qti][pli][qri+1],nbits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void oc_iquant_init(oc_iquant *_this,ogg_uint16_t _d){
|
||||
ogg_uint32_t t;
|
||||
int l;
|
||||
_d<<=1;
|
||||
l=OC_ILOGNZ_32(_d)-1;
|
||||
t=1+((ogg_uint32_t)1<<16+l)/_d;
|
||||
_this->m=(ogg_int16_t)(t-0x10000);
|
||||
_this->l=l;
|
||||
}
|
||||
|
||||
/*See comments at oc_dequant_tables_init() for how the quantization tables'
|
||||
storage should be initialized.*/
|
||||
void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2],
|
||||
oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo){
|
||||
int qi;
|
||||
int pli;
|
||||
int qti;
|
||||
/*Initialize the dequantization tables first.*/
|
||||
oc_dequant_tables_init(_dequant,NULL,_qinfo);
|
||||
/*Derive the quantization tables directly from the dequantization tables.*/
|
||||
for(qi=0;qi<64;qi++)for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
|
||||
int zzi;
|
||||
int plj;
|
||||
int qtj;
|
||||
int dupe;
|
||||
dupe=0;
|
||||
for(qtj=0;qtj<=qti;qtj++){
|
||||
for(plj=0;plj<(qtj<qti?3:pli);plj++){
|
||||
if(_dequant[qi][pli][qti]==_dequant[qi][plj][qtj]){
|
||||
dupe=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dupe)break;
|
||||
}
|
||||
if(dupe){
|
||||
_enquant[qi][pli][qti]=_enquant[qi][plj][qtj];
|
||||
continue;
|
||||
}
|
||||
/*In the original VP3.2 code, the rounding offset and the size of the
|
||||
dead zone around 0 were controlled by a "sharpness" parameter.
|
||||
We now R-D optimize the tokens for each block after quantization,
|
||||
so the rounding offset should always be 1/2, and an explicit dead
|
||||
zone is unnecessary.
|
||||
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(zzi=0;zzi<64;zzi++){
|
||||
oc_iquant_init(_enquant[qi][pli][qti]+zzi,
|
||||
_dequant[qi][pli][qti][zzi]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*This table gives the square root of the fraction of the squared magnitude of
|
||||
each DCT coefficient relative to the total, scaled by 2**16, for both INTRA
|
||||
and INTER modes.
|
||||
These values were measured after motion-compensated prediction, before
|
||||
quantization, over a large set of test video (from QCIF to 1080p) encoded at
|
||||
all possible rates.
|
||||
The DC coefficient takes into account the DPCM prediction (using the
|
||||
quantized values from neighboring blocks, as the encoder does, but still
|
||||
before quantization of the coefficient in the current block).
|
||||
The results differ significantly from the expected variance (e.g., using an
|
||||
AR(1) model of the signal with rho=0.95, as is frequently done to compute
|
||||
the coding gain of the DCT).
|
||||
We use them to estimate an "average" quantizer for a given quantizer matrix,
|
||||
as this is used to parameterize a number of the rate control decisions.
|
||||
These values are themselves probably quantizer-matrix dependent, since the
|
||||
shape of the matrix affects the noise distribution in the reference frames,
|
||||
but they should at least give us _some_ amount of adaptivity to different
|
||||
matrices, as opposed to hard-coding a table of average Q values for the
|
||||
current set.
|
||||
The main features they capture are that a) only a few of the quantizers in
|
||||
the upper-left corner contribute anything significant at all (though INTER
|
||||
mode is significantly flatter) and b) the DPCM prediction of the DC
|
||||
coefficient gives a very minor improvement in the INTRA case and a quite
|
||||
significant one in the INTER case (over the expected variance).*/
|
||||
static const ogg_uint16_t OC_RPSD[2][64]={
|
||||
{
|
||||
52725,17370,10399, 6867, 5115, 3798, 2942, 2076,
|
||||
17370, 9900, 6948, 4994, 3836, 2869, 2229, 1619,
|
||||
10399, 6948, 5516, 4202, 3376, 2573, 2015, 1461,
|
||||
6867, 4994, 4202, 3377, 2800, 2164, 1718, 1243,
|
||||
5115, 3836, 3376, 2800, 2391, 1884, 1530, 1091,
|
||||
3798, 2869, 2573, 2164, 1884, 1495, 1212, 873,
|
||||
2942, 2229, 2015, 1718, 1530, 1212, 1001, 704,
|
||||
2076, 1619, 1461, 1243, 1091, 873, 704, 474
|
||||
},
|
||||
{
|
||||
23411,15604,13529,11601,10683, 8958, 7840, 6142,
|
||||
15604,11901,10718, 9108, 8290, 6961, 6023, 4487,
|
||||
13529,10718, 9961, 8527, 7945, 6689, 5742, 4333,
|
||||
11601, 9108, 8527, 7414, 7084, 5923, 5175, 3743,
|
||||
10683, 8290, 7945, 7084, 6771, 5754, 4793, 3504,
|
||||
8958, 6961, 6689, 5923, 5754, 4679, 3936, 2989,
|
||||
7840, 6023, 5742, 5175, 4793, 3936, 3522, 2558,
|
||||
6142, 4487, 4333, 3743, 3504, 2989, 2558, 1829
|
||||
}
|
||||
};
|
||||
|
||||
/*The fraction of the squared magnitude of the residuals in each color channel
|
||||
relative to the total, scaled by 2**16, for each pixel format.
|
||||
These values were measured after motion-compensated prediction, before
|
||||
quantization, over a large set of test video encoded at all possible rates.
|
||||
TODO: These values are only from INTER frames; it should be re-measured for
|
||||
INTRA frames.*/
|
||||
static const ogg_uint16_t OC_PCD[4][3]={
|
||||
{59926, 3038, 2572},
|
||||
{55201, 5597, 4738},
|
||||
{55201, 5597, 4738},
|
||||
{47682, 9669, 8185}
|
||||
};
|
||||
|
||||
|
||||
/*Compute an "average" quantizer for each qi level.
|
||||
We do one for INTER and one for INTRA, since their behavior is very
|
||||
different, but average across chroma channels.
|
||||
The basic approach is to compute a harmonic average of the squared quantizer,
|
||||
weighted by the expected squared magnitude of the DCT coefficients.
|
||||
Under the (not quite true) assumption that DCT coefficients are
|
||||
Laplacian-distributed, this preserves the product Q*lambda, where
|
||||
lambda=sqrt(2/sigma**2) is the Laplacian distribution parameter (not to be
|
||||
confused with the lambda used in R-D optimization throughout most of the
|
||||
rest of the code).
|
||||
The value Q*lambda completely determines the entropy of the coefficients.*/
|
||||
void oc_enquant_qavg_init(ogg_int64_t _log_qavg[2][64],
|
||||
ogg_uint16_t *_dequant[64][3][2],int _pixel_fmt){
|
||||
int qi;
|
||||
int pli;
|
||||
int qti;
|
||||
int ci;
|
||||
for(qti=0;qti<2;qti++)for(qi=0;qi<64;qi++){
|
||||
ogg_int64_t q2;
|
||||
q2=0;
|
||||
for(pli=0;pli<3;pli++){
|
||||
ogg_uint32_t qp;
|
||||
qp=0;
|
||||
for(ci=0;ci<64;ci++){
|
||||
unsigned rq;
|
||||
unsigned qd;
|
||||
qd=_dequant[qi][pli][qti][OC_IZIG_ZAG[ci]];
|
||||
rq=(OC_RPSD[qti][ci]+(qd>>1))/qd;
|
||||
qp+=rq*(ogg_uint32_t)rq;
|
||||
}
|
||||
q2+=OC_PCD[_pixel_fmt][pli]*(ogg_int64_t)qp;
|
||||
}
|
||||
/*qavg=1.0/sqrt(q2).*/
|
||||
_log_qavg[qti][qi]=OC_Q57(48)-oc_blog64(q2)>>1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#if !defined(_enquant_H)
|
||||
# define _enquant_H (1)
|
||||
# include "quant.h"
|
||||
|
||||
typedef struct oc_iquant oc_iquant;
|
||||
|
||||
#define OC_QUANT_MAX_LOG (OC_Q57(OC_STATIC_ILOG_32(OC_QUANT_MAX)-1))
|
||||
|
||||
/*Used to compute x/d via ((x*m>>16)+x>>l)+(x<0))
|
||||
(i.e., one 16x16->16 mul, 2 shifts, and 2 adds).
|
||||
This is not an approximation; for 16-bit x and d, it is exact.*/
|
||||
struct oc_iquant{
|
||||
ogg_int16_t m;
|
||||
ogg_int16_t l;
|
||||
};
|
||||
|
||||
typedef oc_iquant oc_iquant_table[64];
|
||||
|
||||
|
||||
|
||||
void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo);
|
||||
void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2],
|
||||
oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo);
|
||||
void oc_enquant_qavg_init(ogg_int64_t _log_qavg[2][64],
|
||||
ogg_uint16_t *_dequant[64][3][2],int _pixel_fmt);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,422 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: fdct.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#include "encint.h"
|
||||
#include "dct.h"
|
||||
|
||||
|
||||
|
||||
/*Performs a forward 8 point Type-II DCT transform.
|
||||
The output is scaled by a factor of 2 from the orthonormal version of the
|
||||
transform.
|
||||
_y: The buffer to store the result in.
|
||||
Data will be placed the first 8 entries (e.g., in a row of an 8x8 block).
|
||||
_x: The input coefficients.
|
||||
Every 8th entry is used (e.g., from a column of an 8x8 block).*/
|
||||
static void oc_fdct8(ogg_int16_t _y[8],const ogg_int16_t *_x){
|
||||
int t0;
|
||||
int t1;
|
||||
int t2;
|
||||
int t3;
|
||||
int t4;
|
||||
int t5;
|
||||
int t6;
|
||||
int t7;
|
||||
int r;
|
||||
int s;
|
||||
int u;
|
||||
int v;
|
||||
/*Stage 1:*/
|
||||
/*0-7 butterfly.*/
|
||||
t0=_x[0<<3]+(int)_x[7<<3];
|
||||
t7=_x[0<<3]-(int)_x[7<<3];
|
||||
/*1-6 butterfly.*/
|
||||
t1=_x[1<<3]+(int)_x[6<<3];
|
||||
t6=_x[1<<3]-(int)_x[6<<3];
|
||||
/*2-5 butterfly.*/
|
||||
t2=_x[2<<3]+(int)_x[5<<3];
|
||||
t5=_x[2<<3]-(int)_x[5<<3];
|
||||
/*3-4 butterfly.*/
|
||||
t3=_x[3<<3]+(int)_x[4<<3];
|
||||
t4=_x[3<<3]-(int)_x[4<<3];
|
||||
/*Stage 2:*/
|
||||
/*0-3 butterfly.*/
|
||||
r=t0+t3;
|
||||
t3=t0-t3;
|
||||
t0=r;
|
||||
/*1-2 butterfly.*/
|
||||
r=t1+t2;
|
||||
t2=t1-t2;
|
||||
t1=r;
|
||||
/*6-5 butterfly.*/
|
||||
r=t6+t5;
|
||||
t5=t6-t5;
|
||||
t6=r;
|
||||
/*Stages 3 and 4 are where all the approximation occurs.
|
||||
These are chosen to be as close to an exact inverse of the approximations
|
||||
made in the iDCT as possible, while still using mostly 16-bit arithmetic.
|
||||
We use some 16x16->32 signed MACs, but those still commonly execute in 1
|
||||
cycle on a 16-bit DSP.
|
||||
For example, s=(27146*t5+0x4000>>16)+t5+(t5!=0) is an exact inverse of
|
||||
t5=(OC_C4S4*s>>16).
|
||||
That is, applying the latter to the output of the former will recover t5
|
||||
exactly (over the valid input range of t5, -23171...23169).
|
||||
We increase the rounding bias to 0xB500 in this particular case so that
|
||||
errors inverting the subsequent butterfly are not one-sided (e.g., the
|
||||
mean error is very close to zero).
|
||||
The (t5!=0) term could be replaced simply by 1, but we want to send 0 to 0.
|
||||
The fDCT of an all-zeros block will still not be zero, because of the
|
||||
biases we added at the very beginning of the process, but it will be close
|
||||
enough that it is guaranteed to round to zero.*/
|
||||
/*Stage 3:*/
|
||||
/*4-5 butterfly.*/
|
||||
s=(27146*t5+0xB500>>16)+t5+(t5!=0)>>1;
|
||||
r=t4+s;
|
||||
t5=t4-s;
|
||||
t4=r;
|
||||
/*7-6 butterfly.*/
|
||||
s=(27146*t6+0xB500>>16)+t6+(t6!=0)>>1;
|
||||
r=t7+s;
|
||||
t6=t7-s;
|
||||
t7=r;
|
||||
/*Stage 4:*/
|
||||
/*0-1 butterfly.*/
|
||||
r=(27146*t0+0x4000>>16)+t0+(t0!=0);
|
||||
s=(27146*t1+0xB500>>16)+t1+(t1!=0);
|
||||
u=r+s>>1;
|
||||
v=r-u;
|
||||
_y[0]=u;
|
||||
_y[4]=v;
|
||||
/*3-2 rotation by 6pi/16*/
|
||||
u=(OC_C6S2*t2+OC_C2S6*t3+0x6CB7>>16)+(t3!=0);
|
||||
s=(OC_C6S2*u>>16)-t2;
|
||||
v=(s*21600+0x2800>>18)+s+(s!=0);
|
||||
_y[2]=u;
|
||||
_y[6]=v;
|
||||
/*6-5 rotation by 3pi/16*/
|
||||
u=(OC_C5S3*t6+OC_C3S5*t5+0x0E3D>>16)+(t5!=0);
|
||||
s=t6-(OC_C5S3*u>>16);
|
||||
v=(s*26568+0x3400>>17)+s+(s!=0);
|
||||
_y[5]=u;
|
||||
_y[3]=v;
|
||||
/*7-4 rotation by 7pi/16*/
|
||||
u=(OC_C7S1*t4+OC_C1S7*t7+0x7B1B>>16)+(t7!=0);
|
||||
s=(OC_C7S1*u>>16)-t4;
|
||||
v=(s*20539+0x3000>>20)+s+(s!=0);
|
||||
_y[1]=u;
|
||||
_y[7]=v;
|
||||
}
|
||||
|
||||
void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64],
|
||||
const ogg_int16_t _x[64]){
|
||||
(*_enc->opt_vtable.fdct8x8)(_y,_x);
|
||||
}
|
||||
|
||||
/*Performs a forward 8x8 Type-II DCT transform.
|
||||
The output is scaled by a factor of 4 relative to the 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_enc_fdct8x8_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];
|
||||
int i;
|
||||
/*Add two extra bits of working precision to improve accuracy; any more and
|
||||
we could overflow.*/
|
||||
for(i=0;i<64;i++)w[i]=_x[i]<<2;
|
||||
/*These biases correct for some systematic error that remains in the full
|
||||
fDCT->iDCT round trip.*/
|
||||
w[0]+=(w[0]!=0)+1;
|
||||
w[1]++;
|
||||
w[8]--;
|
||||
/*Transform columns of w into rows of _y.*/
|
||||
for(in=w,out=_y,end=out+64;out<end;in++,out+=8)oc_fdct8(out,in);
|
||||
/*Transform columns of _y into rows of w.*/
|
||||
for(in=_y,out=w,end=out+64;out<end;in++,out+=8)oc_fdct8(out,in);
|
||||
/*Round the result back to the external working precision (which is still
|
||||
scaled by four relative to the orthogonal result).
|
||||
TODO: We should just update the external working precision.*/
|
||||
for(i=0;i<64;i++)_y[i]=w[i]+2>>2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*This does not seem to outperform simple LFE border padding before MC.
|
||||
It yields higher PSNR, but much higher bitrate usage.*/
|
||||
#if 0
|
||||
typedef struct oc_extension_info oc_extension_info;
|
||||
|
||||
|
||||
|
||||
/*Information needed to pad boundary blocks.
|
||||
We multiply each row/column by an extension matrix that fills in the padding
|
||||
values as a linear combination of the active values, so that an equivalent
|
||||
number of coefficients are forced to zero.
|
||||
This costs at most 16 multiplies, the same as a 1-D fDCT itself, and as
|
||||
little as 7 multiplies.
|
||||
We compute the extension matrices for every possible shape in advance, as
|
||||
there are only 35.
|
||||
The coefficients for all matrices are stored in a single array to take
|
||||
advantage of the overlap and repetitiveness of many of the shapes.
|
||||
A similar technique is applied to the offsets into this array.
|
||||
This reduces the required table storage by about 48%.
|
||||
See tools/extgen.c for details.
|
||||
We could conceivably do the same for all 256 possible shapes.*/
|
||||
struct oc_extension_info{
|
||||
/*The mask of the active pixels in the shape.*/
|
||||
short mask;
|
||||
/*The number of active pixels in the shape.*/
|
||||
short na;
|
||||
/*The extension matrix.
|
||||
This is (8-na)xna*/
|
||||
const ogg_int16_t *const *ext;
|
||||
/*The pixel indices: na active pixels followed by 8-na padding pixels.*/
|
||||
unsigned char pi[8];
|
||||
/*The coefficient indices: na unconstrained coefficients followed by 8-na
|
||||
coefficients to be forced to zero.*/
|
||||
unsigned char ci[8];
|
||||
};
|
||||
|
||||
|
||||
/*The number of shapes we need.*/
|
||||
#define OC_NSHAPES (35)
|
||||
|
||||
static const ogg_int16_t OC_EXT_COEFFS[229]={
|
||||
0x7FFF,0xE1F8,0x6903,0xAA79,0x5587,0x7FFF,0x1E08,0x7FFF,
|
||||
0x5587,0xAA79,0x6903,0xE1F8,0x7FFF,0x0000,0x0000,0x0000,
|
||||
0x7FFF,0x0000,0x0000,0x7FFF,0x8000,0x7FFF,0x0000,0x0000,
|
||||
0x7FFF,0xE1F8,0x1E08,0xB0A7,0xAA1D,0x337C,0x7FFF,0x4345,
|
||||
0x2267,0x4345,0x7FFF,0x337C,0xAA1D,0xB0A7,0x8A8C,0x4F59,
|
||||
0x03B4,0xE2D6,0x7FFF,0x2CF3,0x7FFF,0xE2D6,0x03B4,0x4F59,
|
||||
0x8A8C,0x1103,0x7AEF,0x5225,0xDF60,0xC288,0xDF60,0x5225,
|
||||
0x7AEF,0x1103,0x668A,0xD6EE,0x3A16,0x0E6C,0xFA07,0x0E6C,
|
||||
0x3A16,0xD6EE,0x668A,0x2A79,0x2402,0x980F,0x50F5,0x4882,
|
||||
0x50F5,0x980F,0x2402,0x2A79,0xF976,0x2768,0x5F22,0x2768,
|
||||
0xF976,0x1F91,0x76C1,0xE9AE,0x76C1,0x1F91,0x7FFF,0xD185,
|
||||
0x0FC8,0xD185,0x7FFF,0x4F59,0x4345,0xED62,0x4345,0x4F59,
|
||||
0xF574,0x5D99,0x2CF3,0x5D99,0xF574,0x5587,0x3505,0x30FC,
|
||||
0xF482,0x953C,0xEAC4,0x7FFF,0x4F04,0x7FFF,0xEAC4,0x953C,
|
||||
0xF482,0x30FC,0x4F04,0x273D,0xD8C3,0x273D,0x1E09,0x61F7,
|
||||
0x1E09,0x273D,0xD8C3,0x273D,0x4F04,0x30FC,0xA57E,0x153C,
|
||||
0x6AC4,0x3C7A,0x1E08,0x3C7A,0x6AC4,0x153C,0xA57E,0x7FFF,
|
||||
0xA57E,0x5A82,0x6AC4,0x153C,0xC386,0xE1F8,0xC386,0x153C,
|
||||
0x6AC4,0x5A82,0xD8C3,0x273D,0x7FFF,0xE1F7,0x7FFF,0x273D,
|
||||
0xD8C3,0x4F04,0x30FC,0xD8C3,0x273D,0xD8C3,0x30FC,0x4F04,
|
||||
0x1FC8,0x67AD,0x1853,0xE038,0x1853,0x67AD,0x1FC8,0x4546,
|
||||
0xE038,0x1FC8,0x3ABA,0x1FC8,0xE038,0x4546,0x3505,0x5587,
|
||||
0xF574,0xBC11,0x78F4,0x4AFB,0xE6F3,0x4E12,0x3C11,0xF8F4,
|
||||
0x4AFB,0x3C7A,0xF88B,0x3C11,0x78F4,0xCAFB,0x7FFF,0x08CC,
|
||||
0x070C,0x236D,0x5587,0x236D,0x070C,0xF88B,0x3C7A,0x4AFB,
|
||||
0xF8F4,0x3C11,0x7FFF,0x153C,0xCAFB,0x153C,0x7FFF,0x1E08,
|
||||
0xE1F8,0x7FFF,0x08CC,0x7FFF,0xCAFB,0x78F4,0x3C11,0x4E12,
|
||||
0xE6F3,0x4AFB,0x78F4,0xBC11,0xFE3D,0x7FFF,0xFE3D,0x2F3A,
|
||||
0x7FFF,0x2F3A,0x89BC,0x7FFF,0x89BC
|
||||
};
|
||||
|
||||
static const ogg_int16_t *const OC_EXT_ROWS[96]={
|
||||
OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,
|
||||
OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 0,OC_EXT_COEFFS+ 6,
|
||||
OC_EXT_COEFFS+ 27,OC_EXT_COEFFS+ 38,OC_EXT_COEFFS+ 43,OC_EXT_COEFFS+ 32,
|
||||
OC_EXT_COEFFS+ 49,OC_EXT_COEFFS+ 58,OC_EXT_COEFFS+ 67,OC_EXT_COEFFS+ 71,
|
||||
OC_EXT_COEFFS+ 62,OC_EXT_COEFFS+ 53,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,
|
||||
OC_EXT_COEFFS+ 14,OC_EXT_COEFFS+ 13,OC_EXT_COEFFS+ 76,OC_EXT_COEFFS+ 81,
|
||||
OC_EXT_COEFFS+ 86,OC_EXT_COEFFS+ 91,OC_EXT_COEFFS+ 96,OC_EXT_COEFFS+ 98,
|
||||
OC_EXT_COEFFS+ 93,OC_EXT_COEFFS+ 88,OC_EXT_COEFFS+ 83,OC_EXT_COEFFS+ 78,
|
||||
OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 12,
|
||||
OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,
|
||||
OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 103,OC_EXT_COEFFS+ 108,
|
||||
OC_EXT_COEFFS+ 126,OC_EXT_COEFFS+ 16,OC_EXT_COEFFS+ 137,OC_EXT_COEFFS+ 141,
|
||||
OC_EXT_COEFFS+ 20,OC_EXT_COEFFS+ 130,OC_EXT_COEFFS+ 113,OC_EXT_COEFFS+ 116,
|
||||
OC_EXT_COEFFS+ 146,OC_EXT_COEFFS+ 153,OC_EXT_COEFFS+ 160,OC_EXT_COEFFS+ 167,
|
||||
OC_EXT_COEFFS+ 170,OC_EXT_COEFFS+ 163,OC_EXT_COEFFS+ 156,OC_EXT_COEFFS+ 149,
|
||||
OC_EXT_COEFFS+ 119,OC_EXT_COEFFS+ 122,OC_EXT_COEFFS+ 174,OC_EXT_COEFFS+ 177,
|
||||
OC_EXT_COEFFS+ 182,OC_EXT_COEFFS+ 187,OC_EXT_COEFFS+ 192,OC_EXT_COEFFS+ 197,
|
||||
OC_EXT_COEFFS+ 202,OC_EXT_COEFFS+ 207,OC_EXT_COEFFS+ 210,OC_EXT_COEFFS+ 215,
|
||||
OC_EXT_COEFFS+ 179,OC_EXT_COEFFS+ 189,OC_EXT_COEFFS+ 24,OC_EXT_COEFFS+ 204,
|
||||
OC_EXT_COEFFS+ 184,OC_EXT_COEFFS+ 194,OC_EXT_COEFFS+ 212,OC_EXT_COEFFS+ 199,
|
||||
OC_EXT_COEFFS+ 217,OC_EXT_COEFFS+ 100,OC_EXT_COEFFS+ 134,OC_EXT_COEFFS+ 135,
|
||||
OC_EXT_COEFFS+ 135,OC_EXT_COEFFS+ 12,OC_EXT_COEFFS+ 15,OC_EXT_COEFFS+ 134,
|
||||
OC_EXT_COEFFS+ 134,OC_EXT_COEFFS+ 135,OC_EXT_COEFFS+ 220,OC_EXT_COEFFS+ 223,
|
||||
OC_EXT_COEFFS+ 226,OC_EXT_COEFFS+ 227,OC_EXT_COEFFS+ 224,OC_EXT_COEFFS+ 221
|
||||
};
|
||||
|
||||
static const oc_extension_info OC_EXTENSION_INFO[OC_NSHAPES]={
|
||||
{0x7F,7,OC_EXT_ROWS+ 0,{0,1,2,3,4,5,6,7},{0,1,2,4,5,6,7,3}},
|
||||
{0xFE,7,OC_EXT_ROWS+ 7,{1,2,3,4,5,6,7,0},{0,1,2,4,5,6,7,3}},
|
||||
{0x3F,6,OC_EXT_ROWS+ 8,{0,1,2,3,4,5,7,6},{0,1,3,4,6,7,5,2}},
|
||||
{0xFC,6,OC_EXT_ROWS+ 10,{2,3,4,5,6,7,1,0},{0,1,3,4,6,7,5,2}},
|
||||
{0x1F,5,OC_EXT_ROWS+ 12,{0,1,2,3,4,7,6,5},{0,2,3,5,7,6,4,1}},
|
||||
{0xF8,5,OC_EXT_ROWS+ 15,{3,4,5,6,7,2,1,0},{0,2,3,5,7,6,4,1}},
|
||||
{0x0F,4,OC_EXT_ROWS+ 18,{0,1,2,3,7,6,5,4},{0,2,4,6,7,5,3,1}},
|
||||
{0xF0,4,OC_EXT_ROWS+ 18,{4,5,6,7,3,2,1,0},{0,2,4,6,7,5,3,1}},
|
||||
{0x07,3,OC_EXT_ROWS+ 22,{0,1,2,7,6,5,4,3},{0,3,6,7,5,4,2,1}},
|
||||
{0xE0,3,OC_EXT_ROWS+ 27,{5,6,7,4,3,2,1,0},{0,3,6,7,5,4,2,1}},
|
||||
{0x03,2,OC_EXT_ROWS+ 32,{0,1,7,6,5,4,3,2},{0,4,7,6,5,3,2,1}},
|
||||
{0xC0,2,OC_EXT_ROWS+ 32,{6,7,5,4,3,2,1,0},{0,4,7,6,5,3,2,1}},
|
||||
{0x01,1,OC_EXT_ROWS+ 0,{0,7,6,5,4,3,2,1},{0,7,6,5,4,3,2,1}},
|
||||
{0x80,1,OC_EXT_ROWS+ 0,{7,6,5,4,3,2,1,0},{0,7,6,5,4,3,2,1}},
|
||||
{0x7E,6,OC_EXT_ROWS+ 42,{1,2,3,4,5,6,7,0},{0,1,2,5,6,7,4,3}},
|
||||
{0x7C,5,OC_EXT_ROWS+ 44,{2,3,4,5,6,7,1,0},{0,1,4,5,7,6,3,2}},
|
||||
{0x3E,5,OC_EXT_ROWS+ 47,{1,2,3,4,5,7,6,0},{0,1,4,5,7,6,3,2}},
|
||||
{0x78,4,OC_EXT_ROWS+ 50,{3,4,5,6,7,2,1,0},{0,4,5,7,6,3,2,1}},
|
||||
{0x3C,4,OC_EXT_ROWS+ 54,{2,3,4,5,7,6,1,0},{0,3,4,7,6,5,2,1}},
|
||||
{0x1E,4,OC_EXT_ROWS+ 58,{1,2,3,4,7,6,5,0},{0,4,5,7,6,3,2,1}},
|
||||
{0x70,3,OC_EXT_ROWS+ 62,{4,5,6,7,3,2,1,0},{0,5,7,6,4,3,2,1}},
|
||||
{0x38,3,OC_EXT_ROWS+ 67,{3,4,5,7,6,2,1,0},{0,5,6,7,4,3,2,1}},
|
||||
{0x1C,3,OC_EXT_ROWS+ 72,{2,3,4,7,6,5,1,0},{0,5,6,7,4,3,2,1}},
|
||||
{0x0E,3,OC_EXT_ROWS+ 77,{1,2,3,7,6,5,4,0},{0,5,7,6,4,3,2,1}},
|
||||
{0x60,2,OC_EXT_ROWS+ 82,{5,6,7,4,3,2,1,0},{0,2,7,6,5,4,3,1}},
|
||||
{0x30,2,OC_EXT_ROWS+ 36,{4,5,7,6,3,2,1,0},{0,4,7,6,5,3,2,1}},
|
||||
{0x18,2,OC_EXT_ROWS+ 90,{3,4,7,6,5,2,1,0},{0,1,7,6,5,4,3,2}},
|
||||
{0x0C,2,OC_EXT_ROWS+ 34,{2,3,7,6,5,4,1,0},{0,4,7,6,5,3,2,1}},
|
||||
{0x06,2,OC_EXT_ROWS+ 84,{1,2,7,6,5,4,3,0},{0,2,7,6,5,4,3,1}},
|
||||
{0x40,1,OC_EXT_ROWS+ 0,{6,7,5,4,3,2,1,0},{0,7,6,5,4,3,2,1}},
|
||||
{0x20,1,OC_EXT_ROWS+ 0,{5,7,6,4,3,2,1,0},{0,7,6,5,4,3,2,1}},
|
||||
{0x10,1,OC_EXT_ROWS+ 0,{4,7,6,5,3,2,1,0},{0,7,6,5,4,3,2,1}},
|
||||
{0x08,1,OC_EXT_ROWS+ 0,{3,7,6,5,4,2,1,0},{0,7,6,5,4,3,2,1}},
|
||||
{0x04,1,OC_EXT_ROWS+ 0,{2,7,6,5,4,3,1,0},{0,7,6,5,4,3,2,1}},
|
||||
{0x02,1,OC_EXT_ROWS+ 0,{1,7,6,5,4,3,2,0},{0,7,6,5,4,3,2,1}}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*Pads a single column of a partial block and then performs a forward Type-II
|
||||
DCT on the result.
|
||||
The input is scaled by a factor of 4 and biased appropriately for the current
|
||||
fDCT implementation.
|
||||
The output is scaled by an additional factor of 2 from the orthonormal
|
||||
version of the transform.
|
||||
_y: The buffer to store the result in.
|
||||
Data will be placed the first 8 entries (e.g., in a row of an 8x8 block).
|
||||
_x: The input coefficients.
|
||||
Every 8th entry is used (e.g., from a column of an 8x8 block).
|
||||
_e: The extension information for the shape.*/
|
||||
static void oc_fdct8_ext(ogg_int16_t _y[8],ogg_int16_t *_x,
|
||||
const oc_extension_info *_e){
|
||||
const unsigned char *pi;
|
||||
int na;
|
||||
na=_e->na;
|
||||
pi=_e->pi;
|
||||
if(na==1){
|
||||
int ci;
|
||||
/*While the branch below is still correct for shapes with na==1, we can
|
||||
perform the entire transform with just 1 multiply in this case instead
|
||||
of 23.*/
|
||||
_y[0]=(ogg_int16_t)(OC_DIV2_16(OC_C4S4*(_x[pi[0]])));
|
||||
for(ci=1;ci<8;ci++)_y[ci]=0;
|
||||
}
|
||||
else{
|
||||
const ogg_int16_t *const *ext;
|
||||
int zpi;
|
||||
int api;
|
||||
int nz;
|
||||
/*First multiply by the extension matrix to compute the padding values.*/
|
||||
nz=8-na;
|
||||
ext=_e->ext;
|
||||
for(zpi=0;zpi<nz;zpi++){
|
||||
ogg_int32_t v;
|
||||
v=0;
|
||||
for(api=0;api<na;api++){
|
||||
v+=ext[zpi][api]*(ogg_int32_t)(_x[pi[api]<<3]<<1);
|
||||
}
|
||||
_x[pi[na+zpi]<<3]=(ogg_int16_t)(v+0x8000>>16)+1>>1;
|
||||
}
|
||||
oc_fdct8(_y,_x);
|
||||
}
|
||||
}
|
||||
|
||||
/*Performs a forward 8x8 Type-II DCT transform on blocks which overlap the
|
||||
border of the picture region.
|
||||
This method ONLY works with rectangular regions.
|
||||
_border: A description of which pixels are inside the border.
|
||||
_y: The buffer to store the result in.
|
||||
This may be the same as _x.
|
||||
_x: The input pixel values.
|
||||
Pixel values outside the border will be ignored.*/
|
||||
void oc_fdct8x8_border(const oc_border_info *_border,
|
||||
ogg_int16_t _y[64],const ogg_int16_t _x[64]){
|
||||
ogg_int16_t *in;
|
||||
ogg_int16_t *out;
|
||||
ogg_int16_t w[64];
|
||||
ogg_int64_t mask;
|
||||
const oc_extension_info *cext;
|
||||
const oc_extension_info *rext;
|
||||
int cmask;
|
||||
int rmask;
|
||||
int ri;
|
||||
int ci;
|
||||
/*Identify the shapes of the non-zero rows and columns.*/
|
||||
rmask=cmask=0;
|
||||
mask=_border->mask;
|
||||
for(ri=0;ri<8;ri++){
|
||||
/*This aggregation is _only_ correct for rectangular masks.*/
|
||||
cmask|=((mask&0xFF)!=0)<<ri;
|
||||
rmask|=mask&0xFF;
|
||||
mask>>=8;
|
||||
}
|
||||
/*Find the associated extension info for these shapes.*/
|
||||
if(cmask==0xFF)cext=NULL;
|
||||
else for(cext=OC_EXTENSION_INFO;cext->mask!=cmask;){
|
||||
/*If we somehow can't find the shape, then just do an unpadded fDCT.
|
||||
It won't be efficient, but it should still be correct.*/
|
||||
if(++cext>=OC_EXTENSION_INFO+OC_NSHAPES){
|
||||
oc_enc_fdct8x8_c(_y,_x);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(rmask==0xFF)rext=NULL;
|
||||
else for(rext=OC_EXTENSION_INFO;rext->mask!=rmask;){
|
||||
/*If we somehow can't find the shape, then just do an unpadded fDCT.
|
||||
It won't be efficient, but it should still be correct.*/
|
||||
if(++rext>=OC_EXTENSION_INFO+OC_NSHAPES){
|
||||
oc_enc_fdct8x8_c(_y,_x);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*Add two extra bits of working precision to improve accuracy; any more and
|
||||
we could overflow.*/
|
||||
for(ci=0;ci<64;ci++)w[ci]=_x[ci]<<2;
|
||||
/*These biases correct for some systematic error that remains in the full
|
||||
fDCT->iDCT round trip.
|
||||
We can safely add them before padding, since if these pixel values are
|
||||
overwritten, we didn't care what they were anyway (and the unbiased values
|
||||
will usually yield smaller DCT coefficient magnitudes).*/
|
||||
w[0]+=(w[0]!=0)+1;
|
||||
w[1]++;
|
||||
w[8]--;
|
||||
/*Transform the columns.
|
||||
We can ignore zero columns without a problem.*/
|
||||
in=w;
|
||||
out=_y;
|
||||
if(cext==NULL)for(ci=0;ci<8;ci++)oc_fdct8(out+(ci<<3),in+ci);
|
||||
else for(ci=0;ci<8;ci++)if(rmask&(1<<ci))oc_fdct8_ext(out+(ci<<3),in+ci,cext);
|
||||
/*Transform the rows.
|
||||
We transform even rows that are supposedly zero, because rounding errors
|
||||
may make them slightly non-zero, and this will give a more precise
|
||||
reconstruction with very small quantizers.*/
|
||||
in=_y;
|
||||
out=w;
|
||||
if(rext==NULL)for(ri=0;ri<8;ri++)oc_fdct8(out+(ri<<3),in+ri);
|
||||
else for(ri=0;ri<8;ri++)oc_fdct8_ext(out+(ri<<3),in+ri,rext);
|
||||
/*Round the result back to the external working precision (which is still
|
||||
scaled by four relative to the orthogonal result).
|
||||
TODO: We should just update the external working precision.*/
|
||||
for(ci=0;ci<64;ci++)_y[ci]=w[ci]+2>>2;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: fragment.c 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
#include <string.h>
|
||||
#include "internal.h"
|
||||
|
||||
void oc_frag_copy(const oc_theora_state *_state,unsigned char *_dst,
|
||||
const unsigned char *_src,int _ystride){
|
||||
(*_state->opt_vtable.frag_copy)(_dst,_src,_ystride);
|
||||
}
|
||||
|
||||
void oc_frag_copy_c(unsigned char *_dst,const unsigned char *_src,int _ystride){
|
||||
int i;
|
||||
for(i=8;i-->0;){
|
||||
memcpy(_dst,_src,8*sizeof(*_dst));
|
||||
_dst+=_ystride;
|
||||
_src+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
void oc_frag_recon_intra(const oc_theora_state *_state,unsigned char *_dst,
|
||||
int _ystride,const ogg_int16_t _residue[64]){
|
||||
_state->opt_vtable.frag_recon_intra(_dst,_ystride,_residue);
|
||||
}
|
||||
|
||||
void oc_frag_recon_intra_c(unsigned char *_dst,int _ystride,
|
||||
const ogg_int16_t _residue[64]){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int j;
|
||||
for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+128);
|
||||
_dst+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst,
|
||||
const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){
|
||||
_state->opt_vtable.frag_recon_inter(_dst,_src,_ystride,_residue);
|
||||
}
|
||||
|
||||
void oc_frag_recon_inter_c(unsigned char *_dst,
|
||||
const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int j;
|
||||
for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+_src[j]);
|
||||
_dst+=_ystride;
|
||||
_src+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
void oc_frag_recon_inter2(const oc_theora_state *_state,unsigned char *_dst,
|
||||
const unsigned char *_src1,const unsigned char *_src2,int _ystride,
|
||||
const ogg_int16_t _residue[64]){
|
||||
_state->opt_vtable.frag_recon_inter2(_dst,_src1,_src2,_ystride,_residue);
|
||||
}
|
||||
|
||||
void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1,
|
||||
const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]){
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
int j;
|
||||
for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+(_src1[j]+_src2[j]>>1));
|
||||
_dst+=_ystride;
|
||||
_src1+=_ystride;
|
||||
_src2+=_ystride;
|
||||
}
|
||||
}
|
||||
|
||||
void oc_restore_fpu(const oc_theora_state *_state){
|
||||
_state->opt_vtable.restore_fpu();
|
||||
}
|
||||
|
||||
void oc_restore_fpu_c(void){}
|
||||
@@ -0,0 +1,489 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: huffdec.c 16702 2009-11-15 00:40:55Z tterribe $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.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 number of internal tokens associated with each of the spec tokens.*/
|
||||
static const unsigned char OC_DCT_TOKEN_MAP_ENTRIES[TH_NDCT_TOKENS]={
|
||||
1,1,1,4,8,1,1,8,1,1,1,1,1,2,2,2,2,4,8,2,2,2,4,2,2,2,2,2,8,2,4,8
|
||||
};
|
||||
|
||||
/*The map from external spec-defined tokens to internal tokens.
|
||||
This is constructed so that any extra bits read with the original token value
|
||||
can be masked off the least significant bits of its internal token index.
|
||||
In addition, all of the tokens which require additional extra bits are placed
|
||||
at the start of the list, and grouped by type.
|
||||
OC_DCT_REPEAT_RUN3_TOKEN is placed first, as it is an extra-special case, so
|
||||
giving it index 0 may simplify comparisons on some architectures.
|
||||
These requirements require some substantial reordering.*/
|
||||
static const unsigned char OC_DCT_TOKEN_MAP[TH_NDCT_TOKENS]={
|
||||
/*OC_DCT_EOB1_TOKEN (0 extra bits)*/
|
||||
15,
|
||||
/*OC_DCT_EOB2_TOKEN (0 extra bits)*/
|
||||
16,
|
||||
/*OC_DCT_EOB3_TOKEN (0 extra bits)*/
|
||||
17,
|
||||
/*OC_DCT_REPEAT_RUN0_TOKEN (2 extra bits)*/
|
||||
88,
|
||||
/*OC_DCT_REPEAT_RUN1_TOKEN (3 extra bits)*/
|
||||
80,
|
||||
/*OC_DCT_REPEAT_RUN2_TOKEN (4 extra bits)*/
|
||||
1,
|
||||
/*OC_DCT_REPEAT_RUN3_TOKEN (12 extra bits)*/
|
||||
0,
|
||||
/*OC_DCT_SHORT_ZRL_TOKEN (3 extra bits)*/
|
||||
48,
|
||||
/*OC_DCT_ZRL_TOKEN (6 extra bits)*/
|
||||
14,
|
||||
/*OC_ONE_TOKEN (0 extra bits)*/
|
||||
56,
|
||||
/*OC_MINUS_ONE_TOKEN (0 extra bits)*/
|
||||
57,
|
||||
/*OC_TWO_TOKEN (0 extra bits)*/
|
||||
58,
|
||||
/*OC_MINUS_TWO_TOKEN (0 extra bits)*/
|
||||
59,
|
||||
/*OC_DCT_VAL_CAT2 (1 extra bit)*/
|
||||
60,
|
||||
62,
|
||||
64,
|
||||
66,
|
||||
/*OC_DCT_VAL_CAT3 (2 extra bits)*/
|
||||
68,
|
||||
/*OC_DCT_VAL_CAT4 (3 extra bits)*/
|
||||
72,
|
||||
/*OC_DCT_VAL_CAT5 (4 extra bits)*/
|
||||
2,
|
||||
/*OC_DCT_VAL_CAT6 (5 extra bits)*/
|
||||
4,
|
||||
/*OC_DCT_VAL_CAT7 (6 extra bits)*/
|
||||
6,
|
||||
/*OC_DCT_VAL_CAT8 (10 extra bits)*/
|
||||
8,
|
||||
/*OC_DCT_RUN_CAT1A (1 extra bit)*/
|
||||
18,
|
||||
20,
|
||||
22,
|
||||
24,
|
||||
26,
|
||||
/*OC_DCT_RUN_CAT1B (3 extra bits)*/
|
||||
32,
|
||||
/*OC_DCT_RUN_CAT1C (4 extra bits)*/
|
||||
12,
|
||||
/*OC_DCT_RUN_CAT2A (2 extra bits)*/
|
||||
28,
|
||||
/*OC_DCT_RUN_CAT2B (3 extra bits)*/
|
||||
40
|
||||
};
|
||||
|
||||
/*These three functions are really part of the bitpack.c module, but
|
||||
they are only used here.
|
||||
Declaring local static versions so they can be inlined saves considerable
|
||||
function call overhead.*/
|
||||
|
||||
static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
|
||||
const unsigned char *ptr;
|
||||
const unsigned char *stop;
|
||||
oc_pb_window window;
|
||||
int available;
|
||||
window=_b->window;
|
||||
available=_b->bits;
|
||||
ptr=_b->ptr;
|
||||
stop=_b->stop;
|
||||
/*This version of _refill() doesn't bother setting eof because we won't
|
||||
check for it after we've started decoding DCT tokens.*/
|
||||
if(ptr>=stop)available=OC_LOTS_OF_BITS;
|
||||
while(available<=OC_PB_WINDOW_SIZE-8){
|
||||
available+=8;
|
||||
window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
|
||||
if(ptr>=stop)available=OC_LOTS_OF_BITS;
|
||||
}
|
||||
_b->ptr=ptr;
|
||||
if(_bits>available)window|=*ptr>>(available&7);
|
||||
_b->bits=available;
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
/*Read in bits without advancing the bit pointer.
|
||||
Here we assume 0<=_bits&&_bits<=32.*/
|
||||
static long oc_pack_look(oc_pack_buf *_b,int _bits){
|
||||
oc_pb_window window;
|
||||
int available;
|
||||
long result;
|
||||
window=_b->window;
|
||||
available=_b->bits;
|
||||
if(_bits==0)return 0;
|
||||
if(_bits>available)_b->window=window=oc_pack_refill(_b,_bits);
|
||||
result=window>>OC_PB_WINDOW_SIZE-_bits;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*Advance the bit pointer.*/
|
||||
static void oc_pack_adv(oc_pack_buf *_b,int _bits){
|
||||
/*We ignore the special cases for _bits==0 and _bits==32 here, since they are
|
||||
never used actually used.
|
||||
OC_HUFF_SLUSH (defined below) would have to be at least 27 to actually read
|
||||
32 bits in a single go, and would require a 32 GB lookup table (assuming
|
||||
8 byte pointers, since 4 byte pointers couldn't fit such a table).*/
|
||||
_b->window<<=_bits;
|
||||
_b->bits-=_bits;
|
||||
}
|
||||
|
||||
|
||||
/*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)
|
||||
|
||||
|
||||
/*Determines the size in bytes of 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 number of bytes required to store the node.*/
|
||||
static size_t oc_huff_node_size(int _nbits){
|
||||
size_t size;
|
||||
size=_ogg_offsetof(oc_huff_node,nodes);
|
||||
if(_nbits>0)size+=sizeof(oc_huff_node *)*(1<<_nbits);
|
||||
return size;
|
||||
}
|
||||
|
||||
static oc_huff_node *oc_huff_node_init(char **_storage,size_t _size,int _nbits){
|
||||
oc_huff_node *ret;
|
||||
ret=(oc_huff_node *)*_storage;
|
||||
ret->nbits=(unsigned char)_nbits;
|
||||
(*_storage)+=_size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*Determines the size in bytes of a Huffman tree.
|
||||
_nbits: The depth of the subtree.
|
||||
If this is 0, the node is a leaf node.
|
||||
Otherwise storage for 1<<_nbits pointers are added for children.
|
||||
Return: The number of bytes required to store the tree.*/
|
||||
static size_t oc_huff_tree_size(const oc_huff_node *_node){
|
||||
size_t size;
|
||||
size=oc_huff_node_size(_node->nbits);
|
||||
if(_node->nbits){
|
||||
int nchildren;
|
||||
int i;
|
||||
nchildren=1<<_node->nbits;
|
||||
for(i=0;i<nchildren;i+=1<<_node->nbits-_node->nodes[i]->depth){
|
||||
size+=oc_huff_tree_size(_node->nodes[i]);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/*Unpacks a sub-tree from the given buffer.
|
||||
_opb: The buffer to unpack from.
|
||||
_binodes: The nodes to store the sub-tree in.
|
||||
_nbinodes: The number of nodes available for the sub-tree.
|
||||
Return: 0 on success, or a negative value on error.*/
|
||||
static int oc_huff_tree_unpack(oc_pack_buf *_opb,
|
||||
oc_huff_node *_binodes,int _nbinodes){
|
||||
oc_huff_node *binode;
|
||||
long bits;
|
||||
int nused;
|
||||
if(_nbinodes<1)return TH_EBADHEADER;
|
||||
binode=_binodes;
|
||||
nused=0;
|
||||
bits=oc_pack_read1(_opb);
|
||||
if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
|
||||
/*Read an internal node:*/
|
||||
if(!bits){
|
||||
int ret;
|
||||
nused++;
|
||||
binode->nbits=1;
|
||||
binode->depth=1;
|
||||
binode->nodes[0]=_binodes+nused;
|
||||
ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused);
|
||||
if(ret>=0){
|
||||
nused+=ret;
|
||||
binode->nodes[1]=_binodes+nused;
|
||||
ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused);
|
||||
}
|
||||
if(ret<0)return ret;
|
||||
nused+=ret;
|
||||
}
|
||||
/*Read a leaf node:*/
|
||||
else{
|
||||
int ntokens;
|
||||
int token;
|
||||
int i;
|
||||
bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
|
||||
if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
|
||||
/*Find out how many internal tokens we translate this external token into.*/
|
||||
ntokens=OC_DCT_TOKEN_MAP_ENTRIES[bits];
|
||||
if(_nbinodes<2*ntokens-1)return TH_EBADHEADER;
|
||||
/*Fill in a complete binary tree pointing to the internal tokens.*/
|
||||
for(i=1;i<ntokens;i<<=1){
|
||||
int j;
|
||||
binode=_binodes+nused;
|
||||
nused+=i;
|
||||
for(j=0;j<i;j++){
|
||||
binode[j].nbits=1;
|
||||
binode[j].depth=1;
|
||||
binode[j].nodes[0]=_binodes+nused+2*j;
|
||||
binode[j].nodes[1]=_binodes+nused+2*j+1;
|
||||
}
|
||||
}
|
||||
/*And now the leaf nodes with those tokens.*/
|
||||
token=OC_DCT_TOKEN_MAP[bits];
|
||||
for(i=0;i<ntokens;i++){
|
||||
binode=_binodes+nused++;
|
||||
binode->nbits=0;
|
||||
binode->depth=1;
|
||||
binode->token=token+i;
|
||||
}
|
||||
}
|
||||
return nused;
|
||||
}
|
||||
|
||||
/*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);
|
||||
}
|
||||
}
|
||||
|
||||
/*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,
|
||||
char **_storage){
|
||||
oc_huff_node *ret;
|
||||
ret=oc_huff_node_init(_storage,oc_huff_node_size(_node->nbits),_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],_storage);
|
||||
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;
|
||||
}
|
||||
|
||||
static size_t oc_huff_tree_collapse_size(oc_huff_node *_binode,int _depth){
|
||||
size_t size;
|
||||
int mindepth;
|
||||
int depth;
|
||||
int loccupancy;
|
||||
int occupancy;
|
||||
if(_binode->nbits!=0&&_depth>0){
|
||||
return oc_huff_tree_collapse_size(_binode->nodes[0],_depth-1)+
|
||||
oc_huff_tree_collapse_size(_binode->nodes[1],_depth-1);
|
||||
}
|
||||
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--;
|
||||
size=oc_huff_node_size(depth);
|
||||
if(depth>0){
|
||||
size+=oc_huff_tree_collapse_size(_binode->nodes[0],depth-1);
|
||||
size+=oc_huff_tree_collapse_size(_binode->nodes[1],depth-1);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode,
|
||||
char **_storage);
|
||||
|
||||
/*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,char **_storage){
|
||||
if(_level<=0||_binode->nbits==0){
|
||||
int i;
|
||||
_binode->depth=(unsigned char)(_depth-_level);
|
||||
_nodes[0]=oc_huff_tree_collapse(_binode,_storage);
|
||||
for(i=1;i<1<<_level;i++)_nodes[i]=_nodes[0];
|
||||
}
|
||||
else{
|
||||
_level--;
|
||||
oc_huff_node_fill(_nodes,_binode->nodes[0],_level,_depth,_storage);
|
||||
_nodes+=1<<_level;
|
||||
oc_huff_node_fill(_nodes,_binode->nodes[1],_level,_depth,_storage);
|
||||
}
|
||||
}
|
||||
|
||||
/*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,
|
||||
char **_storage){
|
||||
oc_huff_node *root;
|
||||
size_t size;
|
||||
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<=0)return oc_huff_tree_copy(_binode,_storage);
|
||||
size=oc_huff_node_size(depth);
|
||||
root=oc_huff_node_init(_storage,size,depth);
|
||||
root->depth=_binode->depth;
|
||||
oc_huff_node_fill(root->nodes,_binode,depth,depth,_storage);
|
||||
return root;
|
||||
}
|
||||
|
||||
/*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(oc_pack_buf *_opb,
|
||||
oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
|
||||
int i;
|
||||
for(i=0;i<TH_NHUFFMAN_TABLES;i++){
|
||||
oc_huff_node nodes[511];
|
||||
char *storage;
|
||||
size_t size;
|
||||
int ret;
|
||||
/*Unpack the full tree into a temporary buffer.*/
|
||||
ret=oc_huff_tree_unpack(_opb,nodes,sizeof(nodes)/sizeof(*nodes));
|
||||
if(ret<0)return ret;
|
||||
/*Figure out how big the collapsed tree will be.*/
|
||||
size=oc_huff_tree_collapse_size(nodes,0);
|
||||
storage=(char *)_ogg_calloc(1,size);
|
||||
if(storage==NULL)return TH_EFAULT;
|
||||
/*And collapse it.*/
|
||||
_nodes[i]=oc_huff_tree_collapse(nodes,&storage);
|
||||
}
|
||||
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.*/
|
||||
int 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++){
|
||||
size_t size;
|
||||
char *storage;
|
||||
size=oc_huff_tree_size(_src[i]);
|
||||
storage=(char *)_ogg_calloc(1,size);
|
||||
if(storage==NULL){
|
||||
while(i-->0)_ogg_free(_dst[i]);
|
||||
return TH_EFAULT;
|
||||
}
|
||||
_dst[i]=oc_huff_tree_copy(_src[i],&storage);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*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++)_ogg_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(oc_pack_buf *_opb,const oc_huff_node *_node){
|
||||
long bits;
|
||||
while(_node->nbits!=0){
|
||||
bits=oc_pack_look(_opb,_node->nbits);
|
||||
_node=_node->nodes[bits];
|
||||
oc_pack_adv(_opb,_node->depth);
|
||||
}
|
||||
return _node->token;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/********************************************************************
|
||||
* *
|
||||
* 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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: huffdec.h 16503 2009-08-22 18:14:02Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
#if !defined(_huffdec_H)
|
||||
# define _huffdec_H (1)
|
||||
# include "huffman.h"
|
||||
# include "bitpack.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[2];
|
||||
};
|
||||
|
||||
|
||||
|
||||
int oc_huff_trees_unpack(oc_pack_buf *_opb,
|
||||
oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
|
||||
int 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(oc_pack_buf *_opb,const oc_huff_node *_node);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,910 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include "huffenc.h"
|
||||
|
||||
|
||||
|
||||
/*The default Huffman codes used for VP3.1.*/
|
||||
const th_huff_code TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]={
|
||||
{
|
||||
{0x002D, 6},{0x0026, 7},{0x0166, 9},{0x004E, 8},
|
||||
{0x02CE,10},{0x059E,11},{0x027D,11},{0x0008, 5},
|
||||
{0x04F9,12},{0x000F, 4},{0x000E, 4},{0x001B, 5},
|
||||
{0x0006, 4},{0x0008, 4},{0x0005, 4},{0x001A, 5},
|
||||
{0x0015, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3},
|
||||
{0x0000, 3},{0x0009, 4},{0x0017, 5},{0x0029, 6},
|
||||
{0x0028, 6},{0x00B2, 8},{0x04F8,12},{0x059F,11},
|
||||
{0x009E, 9},{0x013F,10},{0x0012, 6},{0x0058, 7}
|
||||
},
|
||||
{
|
||||
{0x0010, 5},{0x0047, 7},{0x01FF, 9},{0x008C, 8},
|
||||
{0x03FC,10},{0x046A,11},{0x0469,11},{0x0022, 6},
|
||||
{0x11A1,13},{0x000E, 4},{0x000D, 4},{0x0004, 4},
|
||||
{0x0005, 4},{0x0009, 4},{0x0006, 4},{0x001E, 5},
|
||||
{0x0016, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3},
|
||||
{0x0000, 3},{0x000A, 4},{0x0017, 5},{0x007D, 7},
|
||||
{0x007E, 7},{0x011B, 9},{0x08D1,12},{0x03FD,10},
|
||||
{0x046B,11},{0x11A0,13},{0x007C, 7},{0x00FE, 8}
|
||||
},
|
||||
{
|
||||
{0x0016, 5},{0x0020, 6},{0x0086, 8},{0x0087, 8},
|
||||
{0x0367,10},{0x06CC,11},{0x06CB,11},{0x006E, 7},
|
||||
{0x366D,14},{0x000F, 4},{0x000E, 4},{0x0004, 4},
|
||||
{0x0005, 4},{0x000A, 4},{0x0006, 4},{0x001A, 5},
|
||||
{0x0011, 5},{0x0007, 4},{0x000C, 4},{0x0001, 3},
|
||||
{0x0000, 3},{0x0009, 4},{0x0017, 5},{0x006F, 7},
|
||||
{0x006D, 7},{0x0364,10},{0x0D9A,12},{0x06CA,11},
|
||||
{0x1B37,13},{0x366C,14},{0x0042, 7},{0x00D8, 8}
|
||||
},
|
||||
{
|
||||
{0x0000, 4},{0x002D, 6},{0x00F7, 8},{0x0058, 7},
|
||||
{0x0167, 9},{0x02CB,10},{0x02CA,10},{0x000E, 6},
|
||||
{0x1661,13},{0x0003, 3},{0x0002, 3},{0x0008, 4},
|
||||
{0x0009, 4},{0x000D, 4},{0x0002, 4},{0x001F, 5},
|
||||
{0x0017, 5},{0x0001, 4},{0x000C, 4},{0x000E, 4},
|
||||
{0x000A, 4},{0x0006, 5},{0x0078, 7},{0x000F, 6},
|
||||
{0x007A, 7},{0x0164, 9},{0x0599,11},{0x02CD,10},
|
||||
{0x0B31,12},{0x1660,13},{0x0079, 7},{0x00F6, 8}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x003C, 6},{0x000F, 7},{0x007A, 7},
|
||||
{0x001D, 8},{0x0020, 9},{0x0072,10},{0x0006, 6},
|
||||
{0x0399,13},{0x0004, 3},{0x0005, 3},{0x0005, 4},
|
||||
{0x0006, 4},{0x000E, 4},{0x0004, 4},{0x0000, 4},
|
||||
{0x0019, 5},{0x0002, 4},{0x000D, 4},{0x0007, 4},
|
||||
{0x001F, 5},{0x0030, 6},{0x0011, 8},{0x0031, 6},
|
||||
{0x0005, 6},{0x0021, 9},{0x00E7,11},{0x0038, 9},
|
||||
{0x01CD,12},{0x0398,13},{0x007B, 7},{0x0009, 7}
|
||||
},
|
||||
{
|
||||
{0x0009, 4},{0x0002, 5},{0x0074, 7},{0x0007, 6},
|
||||
{0x00EC, 8},{0x00D1, 9},{0x01A6,10},{0x0006, 6},
|
||||
{0x0D21,13},{0x0005, 3},{0x0006, 3},{0x0008, 4},
|
||||
{0x0007, 4},{0x000F, 4},{0x0004, 4},{0x0000, 4},
|
||||
{0x001C, 5},{0x0002, 4},{0x0005, 4},{0x0003, 4},
|
||||
{0x000C, 5},{0x0035, 7},{0x01A7,10},{0x001B, 6},
|
||||
{0x0077, 7},{0x01A5,10},{0x0349,11},{0x00D0, 9},
|
||||
{0x0691,12},{0x0D20,13},{0x0075, 7},{0x00ED, 8}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x000C, 5},{0x0012, 6},{0x001B, 6},
|
||||
{0x00B7, 8},{0x016C, 9},{0x0099, 9},{0x005A, 7},
|
||||
{0x16D8,13},{0x0007, 3},{0x0006, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0000, 3},{0x0005, 4},{0x0017, 5},
|
||||
{0x000E, 5},{0x0002, 4},{0x0003, 4},{0x000F, 5},
|
||||
{0x001A, 6},{0x004D, 8},{0x2DB3,14},{0x002C, 6},
|
||||
{0x0011, 6},{0x02DA,10},{0x05B7,11},{0x0098, 9},
|
||||
{0x0B6D,12},{0x2DB2,14},{0x0010, 6},{0x0027, 7}
|
||||
},
|
||||
{
|
||||
{0x000D, 4},{0x000F, 5},{0x001D, 6},{0x0008, 5},
|
||||
{0x0051, 7},{0x0056, 8},{0x00AF, 9},{0x002A, 7},
|
||||
{0x148A,13},{0x0007, 3},{0x0000, 2},{0x0008, 4},
|
||||
{0x0009, 4},{0x000C, 4},{0x0006, 4},{0x0017, 5},
|
||||
{0x000B, 5},{0x0016, 5},{0x0015, 5},{0x0009, 5},
|
||||
{0x0050, 7},{0x00AE, 9},{0x2917,14},{0x001C, 6},
|
||||
{0x0014, 6},{0x0290,10},{0x0523,11},{0x0149, 9},
|
||||
{0x0A44,12},{0x2916,14},{0x0053, 7},{0x00A5, 8}
|
||||
},
|
||||
{
|
||||
{0x0001, 4},{0x001D, 6},{0x00F5, 8},{0x00F4, 8},
|
||||
{0x024D,10},{0x0499,11},{0x0498,11},{0x0001, 5},
|
||||
{0x0021, 6},{0x0006, 3},{0x0005, 3},{0x0006, 4},
|
||||
{0x0005, 4},{0x0002, 4},{0x0007, 5},{0x0025, 6},
|
||||
{0x007B, 7},{0x001C, 6},{0x0020, 6},{0x000D, 6},
|
||||
{0x0048, 7},{0x0092, 8},{0x0127, 9},{0x000E, 4},
|
||||
{0x0004, 4},{0x0011, 5},{0x000C, 6},{0x003C, 6},
|
||||
{0x000F, 5},{0x0000, 5},{0x001F, 5},{0x0013, 5}
|
||||
},
|
||||
{
|
||||
{0x0005, 4},{0x003C, 6},{0x0040, 7},{0x000D, 7},
|
||||
{0x0031, 9},{0x0061,10},{0x0060,10},{0x0002, 5},
|
||||
{0x00F5, 8},{0x0006, 3},{0x0005, 3},{0x0007, 4},
|
||||
{0x0006, 4},{0x0002, 4},{0x0009, 5},{0x0025, 6},
|
||||
{0x0007, 6},{0x0021, 6},{0x0024, 6},{0x0010, 6},
|
||||
{0x0041, 7},{0x00F4, 8},{0x0019, 8},{0x000E, 4},
|
||||
{0x0003, 4},{0x0011, 5},{0x0011, 6},{0x003F, 6},
|
||||
{0x003E, 6},{0x007B, 7},{0x0000, 4},{0x0013, 5}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x0007, 5},{0x0001, 6},{0x0009, 6},
|
||||
{0x0131, 9},{0x0261,10},{0x0260,10},{0x0015, 6},
|
||||
{0x0001, 7},{0x0007, 3},{0x0006, 3},{0x0008, 4},
|
||||
{0x0007, 4},{0x0006, 4},{0x0012, 5},{0x002F, 6},
|
||||
{0x0014, 6},{0x0027, 6},{0x002D, 6},{0x0016, 6},
|
||||
{0x004D, 7},{0x0099, 8},{0x0000, 7},{0x0004, 4},
|
||||
{0x0001, 4},{0x0005, 5},{0x0017, 6},{0x002E, 6},
|
||||
{0x002C, 6},{0x0008, 6},{0x0006, 5},{0x0001, 5}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x000E, 5},{0x0017, 6},{0x002A, 6},
|
||||
{0x0010, 7},{0x00F9,10},{0x00F8,10},{0x001E, 7},
|
||||
{0x003F, 8},{0x0007, 3},{0x0006, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0006, 4},{0x000F, 5},{0x0005, 5},
|
||||
{0x0016, 6},{0x0029, 6},{0x002B, 6},{0x0015, 6},
|
||||
{0x0050, 7},{0x0011, 7},{0x007D, 9},{0x0004, 4},
|
||||
{0x0017, 5},{0x0006, 5},{0x0014, 6},{0x002C, 6},
|
||||
{0x002D, 6},{0x000E, 6},{0x0009, 6},{0x0051, 7}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0018, 5},{0x002F, 6},{0x000D, 5},
|
||||
{0x0053, 7},{0x0295,10},{0x0294,10},{0x00A4, 8},
|
||||
{0x007C, 8},{0x0000, 2},{0x0007, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x001B, 5},{0x000C, 5},{0x0028, 6},
|
||||
{0x006A, 7},{0x001E, 6},{0x001D, 6},{0x0069, 7},
|
||||
{0x00D7, 8},{0x007D, 8},{0x014B, 9},{0x0019, 5},
|
||||
{0x0016, 5},{0x002E, 6},{0x001C, 6},{0x002B, 6},
|
||||
{0x002A, 6},{0x0068, 7},{0x003F, 7},{0x00D6, 8}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x001B, 5},{0x000C, 5},{0x0018, 5},
|
||||
{0x0029, 6},{0x007F, 8},{0x02F0,10},{0x0198, 9},
|
||||
{0x0179, 9},{0x0000, 2},{0x0007, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x001A, 5},{0x000D, 5},{0x002A, 6},
|
||||
{0x0064, 7},{0x001E, 6},{0x0067, 7},{0x005F, 7},
|
||||
{0x00CD, 8},{0x007E, 8},{0x02F1,10},{0x0016, 5},
|
||||
{0x000E, 5},{0x002E, 6},{0x0065, 7},{0x002B, 6},
|
||||
{0x0028, 6},{0x003E, 7},{0x00BD, 8},{0x0199, 9}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0007, 4},{0x0016, 5},{0x0006, 4},
|
||||
{0x0036, 6},{0x005C, 7},{0x015D, 9},{0x015C, 9},
|
||||
{0x02BF,10},{0x0000, 2},{0x0007, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0018, 5},{0x0034, 6},{0x002A, 6},
|
||||
{0x005E, 7},{0x006A, 7},{0x0064, 7},{0x005D, 7},
|
||||
{0x00CB, 8},{0x00AD, 8},{0x02BE,10},{0x0014, 5},
|
||||
{0x0033, 6},{0x006E, 7},{0x005F, 7},{0x006F, 7},
|
||||
{0x006B, 7},{0x00CA, 8},{0x00AC, 8},{0x015E, 9}
|
||||
},
|
||||
{
|
||||
{0x000F, 4},{0x001D, 5},{0x0018, 5},{0x000B, 4},
|
||||
{0x0019, 5},{0x0029, 6},{0x00D6, 8},{0x0551,11},
|
||||
{0x0AA1,12},{0x0001, 2},{0x0000, 2},{0x0009, 4},
|
||||
{0x0008, 4},{0x001B, 5},{0x0038, 6},{0x0028, 6},
|
||||
{0x0057, 7},{0x006A, 7},{0x0068, 7},{0x0056, 7},
|
||||
{0x00E5, 8},{0x0155, 9},{0x0AA0,12},{0x0073, 7},
|
||||
{0x0069, 7},{0x00D7, 8},{0x00AB, 8},{0x00E4, 8},
|
||||
{0x00A9, 8},{0x0151, 9},{0x0150, 9},{0x02A9,10}
|
||||
},
|
||||
{
|
||||
{0x0008, 5},{0x0025, 7},{0x017A, 9},{0x02F7,10},
|
||||
{0x0BDB,12},{0x17B4,13},{0x2F6B,14},{0x001D, 5},
|
||||
{0x2F6A,14},{0x0008, 4},{0x0007, 4},{0x0001, 4},
|
||||
{0x0002, 4},{0x000A, 4},{0x0006, 4},{0x0000, 4},
|
||||
{0x001C, 5},{0x0009, 4},{0x000D, 4},{0x000F, 4},
|
||||
{0x000C, 4},{0x0003, 4},{0x000A, 5},{0x0016, 5},
|
||||
{0x0013, 6},{0x005D, 7},{0x0024, 7},{0x00BC, 8},
|
||||
{0x005C, 7},{0x05EC,11},{0x000B, 5},{0x005F, 7}
|
||||
},
|
||||
{
|
||||
{0x000F, 5},{0x0010, 6},{0x004B, 8},{0x00C6, 8},
|
||||
{0x031D,10},{0x0C71,12},{0x0C70,12},{0x0001, 4},
|
||||
{0x0C73,12},{0x0008, 4},{0x0009, 4},{0x0002, 4},
|
||||
{0x0003, 4},{0x000B, 4},{0x0006, 4},{0x0000, 4},
|
||||
{0x001C, 5},{0x0005, 4},{0x000D, 4},{0x000F, 4},
|
||||
{0x000A, 4},{0x0019, 5},{0x0013, 6},{0x001D, 5},
|
||||
{0x0030, 6},{0x0062, 7},{0x0024, 7},{0x004A, 8},
|
||||
{0x018F, 9},{0x0C72,12},{0x000E, 5},{0x0011, 6}
|
||||
},
|
||||
{
|
||||
{0x001B, 5},{0x0003, 6},{0x008D, 8},{0x0040, 7},
|
||||
{0x0239,10},{0x0471,11},{0x08E0,12},{0x0003, 4},
|
||||
{0x11C3,13},{0x000A, 4},{0x0009, 4},{0x0004, 4},
|
||||
{0x0005, 4},{0x000E, 4},{0x0007, 4},{0x0001, 4},
|
||||
{0x001E, 5},{0x0006, 4},{0x000C, 4},{0x000B, 4},
|
||||
{0x0002, 4},{0x0000, 5},{0x0041, 7},{0x001F, 5},
|
||||
{0x0022, 6},{0x0002, 6},{0x008F, 8},{0x008C, 8},
|
||||
{0x011D, 9},{0x11C2,13},{0x001A, 5},{0x0021, 6}
|
||||
},
|
||||
{
|
||||
{0x001F, 5},{0x0003, 6},{0x0003, 7},{0x0043, 7},
|
||||
{0x000B, 9},{0x0015,10},{0x0051,12},{0x0003, 4},
|
||||
{0x0050,12},{0x000D, 4},{0x000C, 4},{0x0004, 4},
|
||||
{0x0006, 4},{0x000E, 4},{0x000A, 4},{0x0001, 4},
|
||||
{0x001E, 5},{0x0005, 4},{0x0009, 4},{0x0007, 4},
|
||||
{0x0011, 5},{0x0002, 6},{0x0004, 8},{0x0002, 4},
|
||||
{0x002D, 6},{0x0020, 6},{0x0042, 7},{0x0001, 7},
|
||||
{0x0000, 7},{0x0029,11},{0x0017, 5},{0x002C, 6}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x001F, 6},{0x003A, 7},{0x005D, 7},
|
||||
{0x0173, 9},{0x02E4,10},{0x172D,13},{0x0004, 4},
|
||||
{0x172C,13},{0x000F, 4},{0x000E, 4},{0x0009, 4},
|
||||
{0x0008, 4},{0x000C, 4},{0x000A, 4},{0x0001, 4},
|
||||
{0x0016, 5},{0x0002, 4},{0x0005, 4},{0x001A, 5},
|
||||
{0x002F, 6},{0x0038, 7},{0x05CA,11},{0x0006, 4},
|
||||
{0x0037, 6},{0x001E, 6},{0x003B, 7},{0x0039, 7},
|
||||
{0x00B8, 8},{0x0B97,12},{0x0000, 4},{0x0036, 6}
|
||||
},
|
||||
{
|
||||
{0x0006, 4},{0x0037, 6},{0x005D, 7},{0x000C, 6},
|
||||
{0x00B9, 8},{0x02E3,10},{0x05C4,11},{0x0004, 4},
|
||||
{0x1715,13},{0x0000, 3},{0x000F, 4},{0x0008, 4},
|
||||
{0x0007, 4},{0x000C, 4},{0x0009, 4},{0x001D, 5},
|
||||
{0x0016, 5},{0x001C, 5},{0x001A, 5},{0x000B, 5},
|
||||
{0x005E, 7},{0x0170, 9},{0x1714,13},{0x000A, 4},
|
||||
{0x000A, 5},{0x0036, 6},{0x005F, 7},{0x001B, 7},
|
||||
{0x001A, 7},{0x0B8B,12},{0x0002, 4},{0x0007, 5}
|
||||
},
|
||||
{
|
||||
{0x000C, 4},{0x000B, 5},{0x0079, 7},{0x0022, 6},
|
||||
{0x00F0, 8},{0x0119, 9},{0x0230,10},{0x001D, 5},
|
||||
{0x08C4,12},{0x0001, 3},{0x0000, 3},{0x000A, 4},
|
||||
{0x0009, 4},{0x000B, 4},{0x0007, 4},{0x001C, 5},
|
||||
{0x003D, 6},{0x000D, 5},{0x0008, 5},{0x0015, 6},
|
||||
{0x008D, 8},{0x118B,13},{0x118A,13},{0x000D, 4},
|
||||
{0x0010, 5},{0x0009, 5},{0x0014, 6},{0x0047, 7},
|
||||
{0x00F1, 8},{0x0463,11},{0x001F, 5},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x001A, 5},{0x0033, 6},{0x000C, 5},
|
||||
{0x0046, 7},{0x01E3, 9},{0x03C5,10},{0x0017, 5},
|
||||
{0x1E21,13},{0x0002, 3},{0x0001, 3},{0x0009, 4},
|
||||
{0x000A, 4},{0x0007, 4},{0x001B, 5},{0x003D, 6},
|
||||
{0x001B, 6},{0x0022, 6},{0x0079, 7},{0x00F0, 8},
|
||||
{0x1E20,13},{0x1E23,13},{0x1E22,13},{0x000E, 4},
|
||||
{0x0016, 5},{0x0018, 5},{0x0032, 6},{0x001A, 6},
|
||||
{0x0047, 7},{0x0789,11},{0x001F, 5},{0x0010, 5}
|
||||
},
|
||||
{
|
||||
{0x001D, 5},{0x0061, 7},{0x004E, 8},{0x009E, 9},
|
||||
{0x027C,11},{0x09F5,13},{0x09F4,13},{0x0003, 4},
|
||||
{0x0060, 7},{0x0000, 3},{0x000F, 4},{0x000B, 4},
|
||||
{0x000A, 4},{0x0009, 4},{0x0005, 4},{0x000D, 5},
|
||||
{0x0031, 6},{0x0008, 5},{0x0038, 6},{0x0012, 6},
|
||||
{0x0026, 7},{0x013F,10},{0x04FB,12},{0x000D, 4},
|
||||
{0x0002, 4},{0x000C, 5},{0x0039, 6},{0x001C, 6},
|
||||
{0x000F, 5},{0x001D, 6},{0x0008, 4},{0x0019, 5}
|
||||
},
|
||||
{
|
||||
{0x0007, 4},{0x0019, 6},{0x00AB, 8},{0x00AA, 8},
|
||||
{0x0119,10},{0x0461,12},{0x0460,12},{0x001B, 5},
|
||||
{0x0047, 8},{0x0001, 3},{0x0000, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x0009, 4},{0x0005, 4},{0x000D, 5},
|
||||
{0x0035, 6},{0x003D, 6},{0x003C, 6},{0x0018, 6},
|
||||
{0x0022, 7},{0x008D, 9},{0x0231,11},{0x000E, 4},
|
||||
{0x001F, 5},{0x0009, 5},{0x002B, 6},{0x0010, 6},
|
||||
{0x0034, 6},{0x0054, 7},{0x0008, 4},{0x0014, 5}
|
||||
},
|
||||
{
|
||||
{0x000C, 4},{0x0005, 5},{0x0008, 6},{0x005B, 7},
|
||||
{0x004D, 9},{0x0131,11},{0x0261,12},{0x001A, 5},
|
||||
{0x0012, 7},{0x0000, 3},{0x000F, 4},{0x000A, 4},
|
||||
{0x0009, 4},{0x0006, 4},{0x001B, 5},{0x0006, 5},
|
||||
{0x001C, 6},{0x002C, 6},{0x0015, 6},{0x005A, 7},
|
||||
{0x0027, 8},{0x0099,10},{0x0260,12},{0x000E, 4},
|
||||
{0x0004, 4},{0x000F, 5},{0x0007, 5},{0x001D, 6},
|
||||
{0x000B, 5},{0x0014, 6},{0x0008, 4},{0x0017, 5}
|
||||
},
|
||||
{
|
||||
{0x000F, 4},{0x0013, 5},{0x0075, 7},{0x0024, 6},
|
||||
{0x0095, 8},{0x0251,10},{0x04A0,11},{0x0010, 5},
|
||||
{0x00C8, 8},{0x0002, 3},{0x0001, 3},{0x0001, 4},
|
||||
{0x0000, 4},{0x001A, 5},{0x0011, 5},{0x002C, 6},
|
||||
{0x0065, 7},{0x0074, 7},{0x004B, 7},{0x00C9, 8},
|
||||
{0x0129, 9},{0x0943,12},{0x0942,12},{0x0003, 3},
|
||||
{0x000A, 4},{0x001C, 5},{0x0018, 5},{0x0033, 6},
|
||||
{0x0017, 5},{0x002D, 6},{0x001B, 5},{0x003B, 6}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x001A, 5},{0x002D, 6},{0x0038, 6},
|
||||
{0x0028, 7},{0x0395,10},{0x0E51,12},{0x0037, 6},
|
||||
{0x00E4, 8},{0x0001, 3},{0x0000, 3},{0x001F, 5},
|
||||
{0x001E, 5},{0x0017, 5},{0x003A, 6},{0x0073, 7},
|
||||
{0x002A, 7},{0x002B, 7},{0x0029, 7},{0x01CB, 9},
|
||||
{0x0729,11},{0x1CA1,13},{0x1CA0,13},{0x0004, 3},
|
||||
{0x000A, 4},{0x0004, 4},{0x0018, 5},{0x0036, 6},
|
||||
{0x000B, 5},{0x002C, 6},{0x0019, 5},{0x003B, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0004, 4},{0x003F, 6},{0x0017, 5},
|
||||
{0x0075, 7},{0x01F5, 9},{0x07D1,11},{0x0017, 6},
|
||||
{0x01F6, 9},{0x0001, 3},{0x0000, 3},{0x001B, 5},
|
||||
{0x001A, 5},{0x000A, 5},{0x0032, 6},{0x0074, 7},
|
||||
{0x00F8, 8},{0x00F9, 8},{0x01F7, 9},{0x03E9,10},
|
||||
{0x0FA0,12},{0x1F43,13},{0x1F42,13},{0x0003, 3},
|
||||
{0x000A, 4},{0x001E, 5},{0x001C, 5},{0x003B, 6},
|
||||
{0x0018, 5},{0x0016, 6},{0x0016, 5},{0x0033, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0007, 4},{0x0018, 5},{0x001E, 5},
|
||||
{0x0036, 6},{0x0031, 7},{0x0177, 9},{0x0077, 7},
|
||||
{0x0176, 9},{0x0001, 3},{0x0000, 3},{0x001A, 5},
|
||||
{0x0019, 5},{0x003A, 6},{0x0019, 6},{0x005C, 7},
|
||||
{0x00BA, 8},{0x0061, 8},{0x00C1, 9},{0x0180,10},
|
||||
{0x0302,11},{0x0607,12},{0x0606,12},{0x0002, 3},
|
||||
{0x000A, 4},{0x001F, 5},{0x001C, 5},{0x0037, 6},
|
||||
{0x0016, 5},{0x0076, 7},{0x000D, 5},{0x002F, 6}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x000A, 4},{0x001A, 5},{0x000C, 4},
|
||||
{0x001D, 5},{0x0039, 6},{0x0078, 7},{0x005E, 7},
|
||||
{0x0393,11},{0x0002, 3},{0x0001, 3},{0x0016, 5},
|
||||
{0x000F, 5},{0x002E, 6},{0x005F, 7},{0x0073, 8},
|
||||
{0x00E5, 9},{0x01C8,10},{0x0E4A,13},{0x1C97,14},
|
||||
{0x1C96,14},{0x0E49,13},{0x0E48,13},{0x0004, 3},
|
||||
{0x0006, 4},{0x001F, 5},{0x001B, 5},{0x001D, 6},
|
||||
{0x0038, 6},{0x0038, 7},{0x003D, 6},{0x0079, 7}
|
||||
},
|
||||
{
|
||||
{0x000B, 5},{0x002B, 7},{0x0054, 8},{0x01B7, 9},
|
||||
{0x06D9,11},{0x0DB1,12},{0x0DB0,12},{0x0002, 4},
|
||||
{0x00AB, 9},{0x0009, 4},{0x000A, 4},{0x0007, 4},
|
||||
{0x0008, 4},{0x000F, 4},{0x000C, 4},{0x0003, 4},
|
||||
{0x001D, 5},{0x0004, 4},{0x000B, 4},{0x0006, 4},
|
||||
{0x001A, 5},{0x0003, 6},{0x00AA, 9},{0x0001, 4},
|
||||
{0x0000, 5},{0x0014, 6},{0x006C, 7},{0x00DA, 8},
|
||||
{0x0002, 6},{0x036D,10},{0x001C, 5},{0x0037, 6}
|
||||
},
|
||||
{
|
||||
{0x001D, 5},{0x0004, 6},{0x00B6, 8},{0x006A, 8},
|
||||
{0x05B9,11},{0x16E1,13},{0x16E0,13},{0x0007, 4},
|
||||
{0x016F, 9},{0x000C, 4},{0x000D, 4},{0x0009, 4},
|
||||
{0x0008, 4},{0x000F, 4},{0x000A, 4},{0x0003, 4},
|
||||
{0x0017, 5},{0x0002, 4},{0x0004, 4},{0x001C, 5},
|
||||
{0x002C, 6},{0x006B, 8},{0x0B71,12},{0x0005, 4},
|
||||
{0x0003, 5},{0x001B, 6},{0x005A, 7},{0x0034, 7},
|
||||
{0x0005, 6},{0x02DD,10},{0x0000, 4},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x007F, 7},{0x00A1, 8},{0x00A0, 8},
|
||||
{0x020C,10},{0x0834,12},{0x106B,13},{0x0007, 4},
|
||||
{0x0082, 8},{0x000E, 4},{0x000D, 4},{0x000B, 4},
|
||||
{0x000C, 4},{0x0000, 3},{0x0009, 4},{0x0002, 4},
|
||||
{0x0011, 5},{0x001E, 5},{0x0015, 5},{0x003E, 6},
|
||||
{0x0040, 7},{0x041B,11},{0x106A,13},{0x0006, 4},
|
||||
{0x000A, 5},{0x0029, 6},{0x007E, 7},{0x0051, 7},
|
||||
{0x0021, 6},{0x0107, 9},{0x0004, 4},{0x000B, 5}
|
||||
},
|
||||
{
|
||||
{0x0007, 4},{0x001B, 6},{0x00F6, 8},{0x00E9, 8},
|
||||
{0x03A1,10},{0x0740,11},{0x0E82,12},{0x001F, 5},
|
||||
{0x01EF, 9},{0x0001, 3},{0x0002, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x000D, 4},{0x0008, 4},{0x001C, 5},
|
||||
{0x0003, 5},{0x0012, 5},{0x0002, 5},{0x0075, 7},
|
||||
{0x01D1, 9},{0x1D07,13},{0x1D06,13},{0x000A, 4},
|
||||
{0x0013, 5},{0x003B, 6},{0x001A, 6},{0x007A, 7},
|
||||
{0x003C, 6},{0x01EE, 9},{0x0000, 4},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x000D, 4},{0x003D, 6},{0x0042, 7},{0x0037, 7},
|
||||
{0x00D9, 9},{0x0362,11},{0x06C6,12},{0x001F, 5},
|
||||
{0x0086, 8},{0x0001, 3},{0x0002, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x000A, 4},{0x0001, 4},{0x000F, 5},
|
||||
{0x0025, 6},{0x003C, 6},{0x001A, 6},{0x0087, 8},
|
||||
{0x01B0,10},{0x0D8F,13},{0x0D8E,13},{0x000E, 4},
|
||||
{0x0013, 5},{0x000C, 5},{0x0024, 6},{0x0020, 6},
|
||||
{0x0011, 5},{0x006D, 8},{0x0000, 4},{0x000E, 5}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x0012, 5},{0x0076, 7},{0x0077, 7},
|
||||
{0x014D, 9},{0x0533,11},{0x14C9,13},{0x0013, 5},
|
||||
{0x00A5, 8},{0x0002, 3},{0x0003, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x0008, 4},{0x001A, 5},{0x002B, 6},
|
||||
{0x0075, 7},{0x0074, 7},{0x00A7, 8},{0x0298,10},
|
||||
{0x14C8,13},{0x14CB,13},{0x14CA,13},{0x000F, 4},
|
||||
{0x001C, 5},{0x0007, 5},{0x002A, 6},{0x0028, 6},
|
||||
{0x001B, 5},{0x00A4, 8},{0x0002, 4},{0x0006, 5}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x001A, 5},{0x002B, 6},{0x003A, 6},
|
||||
{0x00ED, 8},{0x0283,10},{0x0A0A,12},{0x0004, 5},
|
||||
{0x00A1, 8},{0x0004, 3},{0x0003, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x001F, 5},{0x0006, 5},{0x0077, 7},
|
||||
{0x00A3, 8},{0x00A2, 8},{0x0140, 9},{0x1417,13},
|
||||
{0x1416,13},{0x0A09,12},{0x0A08,12},{0x0000, 3},
|
||||
{0x001E, 5},{0x0007, 5},{0x002A, 6},{0x0029, 6},
|
||||
{0x001C, 5},{0x00EC, 8},{0x001B, 5},{0x0005, 5}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0002, 4},{0x0018, 5},{0x001D, 5},
|
||||
{0x0035, 6},{0x00E4, 8},{0x01CF,11},{0x001D, 7},
|
||||
{0x0072, 9},{0x0004, 3},{0x0005, 3},{0x0006, 4},
|
||||
{0x0007, 4},{0x0006, 5},{0x0073, 7},{0x0038, 8},
|
||||
{0x01CE,11},{0x039B,12},{0x0398,12},{0x0733,13},
|
||||
{0x0732,13},{0x0735,13},{0x0734,13},{0x0000, 3},
|
||||
{0x001F, 5},{0x001B, 5},{0x0034, 6},{0x000F, 6},
|
||||
{0x001E, 5},{0x00E5, 8},{0x0019, 5},{0x0038, 6}
|
||||
},
|
||||
{
|
||||
{0x0016, 5},{0x0050, 7},{0x0172, 9},{0x02E7,10},
|
||||
{0x1732,13},{0x2E67,14},{0x2E66,14},{0x0006, 4},
|
||||
{0x0051, 7},{0x0001, 3},{0x0000, 3},{0x000D, 4},
|
||||
{0x000C, 4},{0x0009, 4},{0x001C, 5},{0x0009, 5},
|
||||
{0x001C, 6},{0x001D, 6},{0x005D, 7},{0x00B8, 8},
|
||||
{0x05CD,11},{0x1731,13},{0x1730,13},{0x000F, 4},
|
||||
{0x0005, 4},{0x000F, 5},{0x0008, 5},{0x0029, 6},
|
||||
{0x001D, 5},{0x002F, 6},{0x0008, 4},{0x0015, 5}
|
||||
},
|
||||
{
|
||||
{0x0009, 4},{0x0021, 6},{0x0040, 7},{0x00AD, 8},
|
||||
{0x02B0,10},{0x1589,13},{0x1588,13},{0x001C, 5},
|
||||
{0x005F, 7},{0x0000, 3},{0x000F, 4},{0x000D, 4},
|
||||
{0x000C, 4},{0x0006, 4},{0x0011, 5},{0x002A, 6},
|
||||
{0x0057, 7},{0x005E, 7},{0x0041, 7},{0x0159, 9},
|
||||
{0x0563,11},{0x158B,13},{0x158A,13},{0x0001, 3},
|
||||
{0x0005, 4},{0x0014, 5},{0x003B, 6},{0x002E, 6},
|
||||
{0x0004, 4},{0x003A, 6},{0x0007, 4},{0x0016, 5}
|
||||
},
|
||||
{
|
||||
{0x000E, 4},{0x0007, 5},{0x0046, 7},{0x0045, 7},
|
||||
{0x0064, 9},{0x032A,12},{0x0657,13},{0x0018, 5},
|
||||
{0x000D, 6},{0x0000, 3},{0x000F, 4},{0x000A, 4},
|
||||
{0x000B, 4},{0x001A, 5},{0x0036, 6},{0x0047, 7},
|
||||
{0x0044, 7},{0x0018, 7},{0x0033, 8},{0x00CB,10},
|
||||
{0x0656,13},{0x0329,12},{0x0328,12},{0x0002, 3},
|
||||
{0x0006, 4},{0x0019, 5},{0x000E, 5},{0x0037, 6},
|
||||
{0x0009, 4},{0x000F, 5},{0x0002, 4},{0x0010, 5}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x0018, 5},{0x0023, 6},{0x0077, 7},
|
||||
{0x0194, 9},{0x1956,13},{0x32AF,14},{0x003A, 6},
|
||||
{0x0076, 7},{0x0002, 3},{0x0001, 3},{0x001F, 5},
|
||||
{0x001E, 5},{0x0014, 5},{0x0022, 6},{0x0064, 7},
|
||||
{0x0197, 9},{0x0196, 9},{0x032B,10},{0x0654,11},
|
||||
{0x32AE,14},{0x1955,13},{0x1954,13},{0x0000, 3},
|
||||
{0x0009, 4},{0x001C, 5},{0x0015, 5},{0x0010, 5},
|
||||
{0x000D, 4},{0x0017, 5},{0x0016, 5},{0x0033, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0006, 4},{0x003E, 6},{0x0010, 5},
|
||||
{0x0048, 7},{0x093F,12},{0x24FA,14},{0x0032, 6},
|
||||
{0x0067, 7},{0x0002, 3},{0x0001, 3},{0x001B, 5},
|
||||
{0x001E, 5},{0x0034, 6},{0x0066, 7},{0x0092, 8},
|
||||
{0x0126, 9},{0x024E,10},{0x049E,11},{0x49F7,15},
|
||||
{0x49F6,15},{0x24F9,14},{0x24F8,14},{0x0000, 3},
|
||||
{0x0007, 4},{0x0018, 5},{0x0011, 5},{0x003F, 6},
|
||||
{0x000E, 4},{0x0013, 5},{0x0035, 6},{0x0025, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0008, 4},{0x0012, 5},{0x001C, 5},
|
||||
{0x001C, 6},{0x00EA, 9},{0x1D75,14},{0x001E, 6},
|
||||
{0x0066, 7},{0x0001, 3},{0x0002, 3},{0x001B, 5},
|
||||
{0x001A, 5},{0x001F, 6},{0x003B, 7},{0x0074, 8},
|
||||
{0x01D6,10},{0x03AF,11},{0x1D74,14},{0x1D77,14},
|
||||
{0x1D76,14},{0x0EB9,13},{0x0EB8,13},{0x000F, 4},
|
||||
{0x0006, 4},{0x0013, 5},{0x003B, 6},{0x003A, 6},
|
||||
{0x0000, 3},{0x0018, 5},{0x0032, 6},{0x0067, 7}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000A, 4},{0x001B, 5},{0x000C, 4},
|
||||
{0x000D, 5},{0x00E6, 8},{0x0684,11},{0x0072, 7},
|
||||
{0x00E7, 8},{0x0002, 3},{0x0001, 3},{0x0017, 5},
|
||||
{0x0016, 5},{0x0018, 6},{0x00D1, 8},{0x01A0, 9},
|
||||
{0x0686,11},{0x0D0F,12},{0x0D0A,12},{0x1A17,13},
|
||||
{0x1A16,13},{0x1A1D,13},{0x1A1C,13},{0x000F, 4},
|
||||
{0x001D, 5},{0x000E, 5},{0x0035, 6},{0x0038, 6},
|
||||
{0x0000, 3},{0x000F, 5},{0x0019, 6},{0x0069, 7}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x000C, 4},{0x001B, 5},{0x0000, 3},
|
||||
{0x0003, 4},{0x002E, 6},{0x0051, 9},{0x00BC, 8},
|
||||
{0x0053, 9},{0x0004, 3},{0x0002, 3},{0x0016, 5},
|
||||
{0x0015, 5},{0x0015, 7},{0x0050, 9},{0x00A4,10},
|
||||
{0x0294,12},{0x052B,13},{0x052A,13},{0x052D,13},
|
||||
{0x052C,13},{0x052F,13},{0x052E,13},{0x000E, 4},
|
||||
{0x001A, 5},{0x0004, 5},{0x0028, 6},{0x0029, 6},
|
||||
{0x000F, 4},{0x000B, 6},{0x005F, 7},{0x00BD, 8}
|
||||
},
|
||||
{
|
||||
{0x0003, 4},{0x0009, 6},{0x00D0, 8},{0x01A3, 9},
|
||||
{0x0344,10},{0x0D14,12},{0x1A2B,13},{0x0004, 4},
|
||||
{0x0015, 7},{0x0000, 3},{0x000F, 4},{0x000B, 4},
|
||||
{0x000C, 4},{0x000E, 4},{0x0009, 4},{0x001B, 5},
|
||||
{0x000A, 5},{0x0014, 5},{0x000D, 5},{0x002A, 6},
|
||||
{0x0014, 7},{0x068B,11},{0x1A2A,13},{0x0008, 4},
|
||||
{0x000B, 5},{0x002B, 6},{0x000B, 6},{0x0069, 7},
|
||||
{0x0035, 6},{0x0008, 6},{0x0007, 4},{0x000C, 5}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x003C, 6},{0x0032, 7},{0x0030, 7},
|
||||
{0x00C5, 9},{0x0621,12},{0x0620,12},{0x001F, 5},
|
||||
{0x0033, 7},{0x0001, 3},{0x0000, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x000C, 4},{0x0004, 4},{0x000D, 5},
|
||||
{0x0026, 6},{0x0027, 6},{0x0014, 6},{0x0063, 8},
|
||||
{0x0189,10},{0x0623,12},{0x0622,12},{0x000B, 4},
|
||||
{0x0012, 5},{0x003D, 6},{0x0022, 6},{0x0015, 6},
|
||||
{0x000B, 5},{0x0023, 6},{0x0007, 4},{0x0010, 5}
|
||||
},
|
||||
{
|
||||
{0x000F, 4},{0x000C, 5},{0x0043, 7},{0x0010, 6},
|
||||
{0x0044, 8},{0x0114,10},{0x0455,12},{0x0018, 5},
|
||||
{0x0023, 7},{0x0001, 3},{0x0000, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x0009, 4},{0x0019, 5},{0x0009, 5},
|
||||
{0x0017, 6},{0x0016, 6},{0x0042, 7},{0x008B, 9},
|
||||
{0x0454,12},{0x0457,12},{0x0456,12},{0x000B, 4},
|
||||
{0x0015, 5},{0x000A, 5},{0x0029, 6},{0x0020, 6},
|
||||
{0x000D, 5},{0x0028, 6},{0x0007, 4},{0x0011, 5}
|
||||
},
|
||||
{
|
||||
{0x0001, 3},{0x001A, 5},{0x0029, 6},{0x002A, 6},
|
||||
{0x00A0, 8},{0x0285,10},{0x1425,13},{0x0002, 5},
|
||||
{0x0000, 7},{0x0002, 3},{0x0003, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x0008, 4},{0x0012, 5},{0x0001, 6},
|
||||
{0x0051, 7},{0x0001, 7},{0x0143, 9},{0x0508,11},
|
||||
{0x1424,13},{0x1427,13},{0x1426,13},{0x000F, 4},
|
||||
{0x001C, 5},{0x0003, 5},{0x0037, 6},{0x002B, 6},
|
||||
{0x0013, 5},{0x0036, 6},{0x001D, 5},{0x0001, 5}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x001F, 5},{0x003D, 6},{0x0006, 5},
|
||||
{0x0016, 7},{0x0053, 9},{0x014A,11},{0x0034, 6},
|
||||
{0x002A, 8},{0x0002, 3},{0x0003, 3},{0x000B, 4},
|
||||
{0x000C, 4},{0x001C, 5},{0x0037, 6},{0x0017, 7},
|
||||
{0x002B, 8},{0x0028, 8},{0x00A4,10},{0x052D,13},
|
||||
{0x052C,13},{0x052F,13},{0x052E,13},{0x0000, 3},
|
||||
{0x001D, 5},{0x0007, 5},{0x0004, 5},{0x0035, 6},
|
||||
{0x0014, 5},{0x0036, 6},{0x0015, 5},{0x003C, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000A, 4},{0x0007, 5},{0x001D, 5},
|
||||
{0x0009, 6},{0x01F3, 9},{0x07C7,11},{0x0008, 6},
|
||||
{0x01F0, 9},{0x0003, 3},{0x0002, 3},{0x000D, 4},
|
||||
{0x000C, 4},{0x0017, 5},{0x007D, 7},{0x01F2, 9},
|
||||
{0x07C6,11},{0x07C5,11},{0x1F12,13},{0x3E27,14},
|
||||
{0x3E26,14},{0x1F11,13},{0x1F10,13},{0x0000, 3},
|
||||
{0x001E, 5},{0x0006, 5},{0x0039, 6},{0x0038, 6},
|
||||
{0x003F, 6},{0x002C, 6},{0x0005, 5},{0x002D, 6}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x0007, 4},{0x0018, 5},{0x0003, 4},
|
||||
{0x0005, 5},{0x0035, 7},{0x004F, 9},{0x0012, 7},
|
||||
{0x04E5,13},{0x0005, 3},{0x0004, 3},{0x000D, 4},
|
||||
{0x000E, 4},{0x0033, 6},{0x0026, 8},{0x009D,10},
|
||||
{0x04E4,13},{0x04E7,13},{0x04E6,13},{0x04E1,13},
|
||||
{0x04E0,13},{0x04E3,13},{0x04E2,13},{0x0000, 3},
|
||||
{0x001F, 5},{0x000C, 5},{0x003D, 6},{0x003C, 6},
|
||||
{0x0032, 6},{0x0034, 7},{0x001B, 6},{0x0008, 6}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x0004, 4},{0x001C, 5},{0x000F, 4},
|
||||
{0x0002, 4},{0x0007, 5},{0x0075, 7},{0x00E8, 8},
|
||||
{0x1D2A,13},{0x0005, 3},{0x0004, 3},{0x000D, 4},
|
||||
{0x000C, 4},{0x0077, 7},{0x0E96,12},{0x3A57,14},
|
||||
{0x3A56,14},{0x3A5D,14},{0x3A5C,14},{0x3A5F,14},
|
||||
{0x3A5E,14},{0x1D29,13},{0x1D28,13},{0x0003, 3},
|
||||
{0x0006, 5},{0x000A, 5},{0x002C, 7},{0x0017, 6},
|
||||
{0x0076, 7},{0x01D3, 9},{0x03A4,10},{0x002D, 7}
|
||||
},
|
||||
{
|
||||
{0x000A, 4},{0x0024, 6},{0x00BF, 8},{0x0085, 8},
|
||||
{0x0211,10},{0x0842,12},{0x1087,13},{0x0018, 5},
|
||||
{0x0020, 6},{0x0001, 3},{0x0002, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x0007, 4},{0x0013, 5},{0x0025, 6},
|
||||
{0x005E, 7},{0x0043, 7},{0x00BE, 8},{0x0109, 9},
|
||||
{0x1086,13},{0x0841,12},{0x0840,12},{0x000F, 4},
|
||||
{0x0001, 4},{0x0011, 5},{0x0000, 5},{0x002E, 6},
|
||||
{0x0019, 5},{0x0001, 5},{0x0006, 4},{0x0016, 5}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x000F, 5},{0x006F, 7},{0x0061, 7},
|
||||
{0x0374,10},{0x1BA8,13},{0x3753,14},{0x0012, 5},
|
||||
{0x0036, 6},{0x0000, 3},{0x0001, 3},{0x000A, 4},
|
||||
{0x000B, 4},{0x001A, 5},{0x0031, 6},{0x0060, 7},
|
||||
{0x00DC, 8},{0x01BB, 9},{0x06EB,11},{0x1BAB,13},
|
||||
{0x3752,14},{0x3755,14},{0x3754,14},{0x000E, 4},
|
||||
{0x0006, 4},{0x0013, 5},{0x000E, 5},{0x003E, 6},
|
||||
{0x0008, 4},{0x001E, 5},{0x0019, 5},{0x003F, 6}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x001C, 5},{0x0025, 6},{0x0024, 6},
|
||||
{0x01DA, 9},{0x1DBD,13},{0x3B7C,14},{0x003C, 6},
|
||||
{0x003D, 6},{0x0000, 3},{0x0001, 3},{0x000B, 4},
|
||||
{0x000A, 4},{0x000B, 5},{0x0077, 7},{0x00EC, 8},
|
||||
{0x03B6,10},{0x076E,11},{0x1DBF,13},{0x76FB,15},
|
||||
{0x76FA,15},{0x3B79,14},{0x3B78,14},{0x000D, 4},
|
||||
{0x001F, 5},{0x0013, 5},{0x000A, 5},{0x0008, 5},
|
||||
{0x000C, 4},{0x0008, 4},{0x0009, 5},{0x003A, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0003, 4},{0x0004, 5},{0x0010, 5},
|
||||
{0x008F, 8},{0x0475,11},{0x11D1,13},{0x0079, 7},
|
||||
{0x0027, 6},{0x0002, 3},{0x0003, 3},{0x0001, 4},
|
||||
{0x0000, 4},{0x0026, 6},{0x0046, 7},{0x011C, 9},
|
||||
{0x0477,11},{0x08ED,12},{0x11D0,13},{0x11D3,13},
|
||||
{0x11D2,13},{0x11D9,13},{0x11D8,13},{0x000D, 4},
|
||||
{0x001F, 5},{0x0012, 5},{0x0005, 5},{0x003D, 6},
|
||||
{0x000C, 4},{0x000E, 4},{0x0022, 6},{0x0078, 7}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x000C, 4},{0x001B, 5},{0x0000, 4},
|
||||
{0x0006, 6},{0x03E2,10},{0x3E3D,14},{0x000F, 7},
|
||||
{0x0034, 6},{0x0003, 3},{0x0002, 3},{0x001E, 5},
|
||||
{0x001D, 5},{0x007D, 7},{0x01F0, 9},{0x07C6,11},
|
||||
{0x3E3C,14},{0x3E3F,14},{0x3E3E,14},{0x3E39,14},
|
||||
{0x3E38,14},{0x3E3B,14},{0x3E3A,14},{0x0008, 4},
|
||||
{0x001C, 5},{0x0002, 5},{0x003F, 6},{0x0035, 6},
|
||||
{0x0009, 4},{0x0001, 3},{0x000E, 7},{0x00F9, 8}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000B, 4},{0x0001, 4},{0x000A, 4},
|
||||
{0x001E, 6},{0x00E0, 9},{0x0E1E,13},{0x0071, 8},
|
||||
{0x0039, 7},{0x0007, 3},{0x0006, 3},{0x000D, 5},
|
||||
{0x000C, 5},{0x0020, 7},{0x01C2,10},{0x1C3F,14},
|
||||
{0x1C3E,14},{0x0E19,13},{0x0E18,13},{0x0E1B,13},
|
||||
{0x0E1A,13},{0x0E1D,13},{0x0E1C,13},{0x0000, 4},
|
||||
{0x0009, 5},{0x001D, 6},{0x001F, 6},{0x0011, 6},
|
||||
{0x0005, 4},{0x0001, 3},{0x0043, 8},{0x0042, 8}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000D, 4},{0x0007, 4},{0x0002, 3},
|
||||
{0x0014, 5},{0x016C, 9},{0x16D1,13},{0x02DF,10},
|
||||
{0x016E, 9},{0x0000, 2},{0x0007, 3},{0x002C, 6},
|
||||
{0x002B, 6},{0x02DE,10},{0x16D0,13},{0x16D3,13},
|
||||
{0x16D2,13},{0x2DB5,14},{0x2DB4,14},{0x2DB7,14},
|
||||
{0x2DB6,14},{0x16D9,13},{0x16D8,13},{0x000C, 5},
|
||||
{0x002A, 6},{0x005A, 7},{0x001B, 6},{0x001A, 6},
|
||||
{0x0017, 5},{0x000C, 4},{0x05B7,11},{0x05B5,11}
|
||||
},
|
||||
{
|
||||
{0x0002, 2},{0x000F, 4},{0x001C, 5},{0x000C, 4},
|
||||
{0x003B, 6},{0x01AC, 9},{0x1AD8,13},{0x35B3,14},
|
||||
{0x35B2,14},{0x0001, 2},{0x0000, 2},{0x0069, 7},
|
||||
{0x0068, 7},{0x35BD,14},{0x35BC,14},{0x35BF,14},
|
||||
{0x35BE,14},{0x35B9,14},{0x35B8,14},{0x35BB,14},
|
||||
{0x35BA,14},{0x35B5,14},{0x35B4,14},{0x01A9, 9},
|
||||
{0x01A8, 9},{0x035A,10},{0x00D7, 8},{0x00D5, 8},
|
||||
{0x003A, 6},{0x001B, 5},{0x35B7,14},{0x35B6,14}
|
||||
},
|
||||
{
|
||||
{0x0000, 3},{0x0010, 5},{0x0072, 7},{0x0071, 7},
|
||||
{0x0154, 9},{0x0AAB,12},{0x0AA8,12},{0x0014, 5},
|
||||
{0x0070, 7},{0x0002, 3},{0x0003, 3},{0x000C, 4},
|
||||
{0x000B, 4},{0x0003, 4},{0x0011, 5},{0x0073, 7},
|
||||
{0x0054, 7},{0x00AB, 8},{0x02AB,10},{0x1553,13},
|
||||
{0x1552,13},{0x1555,13},{0x1554,13},{0x000D, 4},
|
||||
{0x001E, 5},{0x0012, 5},{0x003E, 6},{0x002B, 6},
|
||||
{0x0002, 4},{0x003F, 6},{0x001D, 5},{0x0013, 5}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x001F, 5},{0x0029, 6},{0x003D, 6},
|
||||
{0x000C, 7},{0x0069,10},{0x0345,13},{0x0002, 5},
|
||||
{0x0028, 6},{0x0002, 3},{0x0001, 3},{0x000E, 4},
|
||||
{0x000C, 4},{0x0015, 5},{0x0007, 6},{0x001B, 8},
|
||||
{0x006B,10},{0x006A,10},{0x0344,13},{0x0347,13},
|
||||
{0x0346,13},{0x01A1,12},{0x01A0,12},{0x000B, 4},
|
||||
{0x001A, 5},{0x0012, 5},{0x0000, 5},{0x003C, 6},
|
||||
{0x0008, 4},{0x001B, 5},{0x0013, 5},{0x0001, 5}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0004, 4},{0x003F, 6},{0x0014, 5},
|
||||
{0x0056, 7},{0x015C, 9},{0x15D5,13},{0x003C, 6},
|
||||
{0x002A, 6},{0x0000, 3},{0x0001, 3},{0x000E, 4},
|
||||
{0x000D, 4},{0x000C, 5},{0x00AF, 8},{0x02BB,10},
|
||||
{0x15D4,13},{0x15D7,13},{0x15D6,13},{0x15D1,13},
|
||||
{0x15D0,13},{0x15D3,13},{0x15D2,13},{0x000B, 4},
|
||||
{0x0019, 5},{0x000D, 5},{0x003E, 6},{0x0031, 6},
|
||||
{0x0007, 4},{0x0005, 4},{0x003D, 6},{0x0030, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0008, 4},{0x001A, 5},{0x0000, 4},
|
||||
{0x0036, 6},{0x0011, 8},{0x0106,12},{0x000A, 7},
|
||||
{0x006E, 7},{0x0002, 3},{0x0003, 3},{0x0003, 4},
|
||||
{0x0002, 4},{0x006F, 7},{0x0021, 9},{0x020F,13},
|
||||
{0x020E,13},{0x0101,12},{0x0100,12},{0x0103,12},
|
||||
{0x0102,12},{0x0105,12},{0x0104,12},{0x000C, 4},
|
||||
{0x001E, 5},{0x0003, 5},{0x003E, 6},{0x003F, 6},
|
||||
{0x0009, 4},{0x000E, 4},{0x000B, 7},{0x0009, 7}
|
||||
},
|
||||
{
|
||||
{0x0002, 3},{0x000E, 4},{0x001E, 5},{0x000C, 4},
|
||||
{0x001F, 5},{0x006E, 7},{0x00AD,10},{0x00AF,10},
|
||||
{0x0014, 7},{0x0004, 3},{0x0003, 3},{0x001A, 5},
|
||||
{0x0017, 5},{0x002A, 8},{0x0576,13},{0x0AEF,14},
|
||||
{0x0AEE,14},{0x0571,13},{0x0570,13},{0x0573,13},
|
||||
{0x0572,13},{0x0575,13},{0x0574,13},{0x0003, 4},
|
||||
{0x0016, 5},{0x0004, 5},{0x0036, 6},{0x000B, 6},
|
||||
{0x000A, 4},{0x0000, 3},{0x006F, 7},{0x00AC,10}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3},
|
||||
{0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13},
|
||||
{0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6},
|
||||
{0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13},
|
||||
{0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13},
|
||||
{0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3},
|
||||
{0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8},
|
||||
{0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3},
|
||||
{0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13},
|
||||
{0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6},
|
||||
{0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13},
|
||||
{0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13},
|
||||
{0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3},
|
||||
{0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8},
|
||||
{0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x0005, 4},{0x0003, 3},{0x0001, 3},
|
||||
{0x0004, 4},{0x002F, 6},{0x0526,11},{0x1495,13},
|
||||
{0x00A6, 8},{0x0007, 3},{0x0006, 3},{0x002D, 6},
|
||||
{0x002C, 6},{0x1494,13},{0x1497,13},{0x1496,13},
|
||||
{0x1491,13},{0x1490,13},{0x1493,13},{0x1492,13},
|
||||
{0x293D,14},{0x293C,14},{0x293F,14},{0x0000, 3},
|
||||
{0x0028, 6},{0x00A5, 8},{0x0148, 9},{0x00A7, 8},
|
||||
{0x002E, 6},{0x0015, 5},{0x0A4E,12},{0x293E,14}
|
||||
},
|
||||
{
|
||||
{0x0003, 3},{0x0011, 5},{0x0020, 6},{0x0074, 7},
|
||||
{0x010D, 9},{0x0863,12},{0x0860,12},{0x000A, 5},
|
||||
{0x0075, 7},{0x0001, 3},{0x0000, 3},{0x000B, 4},
|
||||
{0x000A, 4},{0x0018, 5},{0x0038, 6},{0x0042, 7},
|
||||
{0x010F, 9},{0x010E, 9},{0x0219,10},{0x10C3,13},
|
||||
{0x10C2,13},{0x10C5,13},{0x10C4,13},{0x000F, 4},
|
||||
{0x0004, 4},{0x0019, 5},{0x000B, 5},{0x0039, 6},
|
||||
{0x0009, 4},{0x001B, 5},{0x001A, 5},{0x003B, 6}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x0001, 4},{0x003E, 6},{0x0001, 5},
|
||||
{0x00E2, 8},{0x1C6F,13},{0x38D9,14},{0x0039, 6},
|
||||
{0x001F, 6},{0x0002, 3},{0x0001, 3},{0x0009, 4},
|
||||
{0x0008, 4},{0x0000, 5},{0x0070, 7},{0x01C7, 9},
|
||||
{0x038C,10},{0x071A,11},{0x38D8,14},{0x38DB,14},
|
||||
{0x38DA,14},{0x38DD,14},{0x38DC,14},{0x000D, 4},
|
||||
{0x001D, 5},{0x000E, 5},{0x003F, 6},{0x003C, 6},
|
||||
{0x000C, 4},{0x0006, 4},{0x003D, 6},{0x001E, 6}
|
||||
},
|
||||
{
|
||||
{0x0006, 3},{0x000B, 4},{0x0011, 5},{0x001E, 5},
|
||||
{0x0074, 7},{0x03AA,10},{0x1D5C,13},{0x0001, 6},
|
||||
{0x0021, 6},{0x0001, 3},{0x0002, 3},{0x0007, 4},
|
||||
{0x0006, 4},{0x003E, 6},{0x00EB, 8},{0x01D4, 9},
|
||||
{0x0EAF,12},{0x3ABB,14},{0x3ABA,14},{0x1D59,13},
|
||||
{0x1D58,13},{0x1D5B,13},{0x1D5A,13},{0x000A, 4},
|
||||
{0x001C, 5},{0x0001, 5},{0x003F, 6},{0x003B, 6},
|
||||
{0x0001, 4},{0x0009, 4},{0x0020, 6},{0x0000, 6}
|
||||
},
|
||||
{
|
||||
{0x0004, 3},{0x000A, 4},{0x0017, 5},{0x0004, 4},
|
||||
{0x0016, 6},{0x016A, 9},{0x16B1,13},{0x0017, 7},
|
||||
{0x005B, 7},{0x0006, 3},{0x0007, 3},{0x0001, 4},
|
||||
{0x0000, 4},{0x000A, 6},{0x02D7,10},{0x0B5A,12},
|
||||
{0x16B0,13},{0x16B3,13},{0x16B2,13},{0x2D6D,14},
|
||||
{0x2D6C,14},{0x2D6F,14},{0x2D6E,14},{0x0006, 4},
|
||||
{0x000A, 5},{0x0004, 5},{0x002C, 6},{0x0017, 6},
|
||||
{0x0003, 4},{0x0007, 4},{0x0016, 7},{0x00B4, 8}
|
||||
},
|
||||
{
|
||||
{0x0005, 3},{0x000D, 4},{0x0005, 4},{0x0009, 4},
|
||||
{0x0033, 6},{0x0193, 9},{0x192C,13},{0x0061, 8},
|
||||
{0x0031, 7},{0x0000, 2},{0x0007, 3},{0x0010, 5},
|
||||
{0x0011, 5},{0x00C8, 8},{0x192F,13},{0x325B,14},
|
||||
{0x325A,14},{0x1929,13},{0x1928,13},{0x192B,13},
|
||||
{0x192A,13},{0x325D,14},{0x325C,14},{0x0018, 5},
|
||||
{0x001A, 6},{0x001B, 6},{0x0065, 7},{0x0019, 6},
|
||||
{0x0004, 4},{0x0007, 4},{0x0060, 8},{0x0324,10}
|
||||
},
|
||||
{
|
||||
{0x0006, 3},{0x0000, 3},{0x0002, 4},{0x000F, 4},
|
||||
{0x0039, 6},{0x01D9, 9},{0x1D82,13},{0x0761,11},
|
||||
{0x03BE,10},{0x0001, 2},{0x0002, 2},{0x000F, 6},
|
||||
{0x000E, 6},{0x0762,11},{0x3B07,14},{0x3B06,14},
|
||||
{0x3B1D,14},{0x3B1C,14},{0x3B1F,14},{0x3B1E,14},
|
||||
{0x3B19,14},{0x3B18,14},{0x3B1B,14},{0x0038, 6},
|
||||
{0x01DE, 9},{0x00ED, 8},{0x03BF,10},{0x00EE, 8},
|
||||
{0x003A, 6},{0x0006, 5},{0x0EC0,12},{0x3B1A,14}
|
||||
},
|
||||
{
|
||||
{0x0000, 2},{0x0002, 3},{0x000F, 5},{0x0006, 4},
|
||||
{0x001C, 6},{0x01D0,10},{0x0E8C,13},{0x1D1B,14},
|
||||
{0x1D1A,14},{0x0003, 2},{0x0002, 2},{0x00EA, 9},
|
||||
{0x00E9, 9},{0x0E89,13},{0x0E88,13},{0x0E8B,13},
|
||||
{0x0E8A,13},{0x1D65,14},{0x1D64,14},{0x1D67,14},
|
||||
{0x1D66,14},{0x1D61,14},{0x1D60,14},{0x03AD,11},
|
||||
{0x1D63,14},{0x1D62,14},{0x1D1D,14},{0x1D1C,14},
|
||||
{0x003B, 7},{0x01D7,10},{0x1D1F,14},{0x1D1E,14}
|
||||
},
|
||||
{
|
||||
{0x0002, 2},{0x000F, 4},{0x001C, 5},{0x000C, 4},
|
||||
{0x003B, 6},{0x01AC, 9},{0x1AD8,13},{0x35B3,14},
|
||||
{0x35B2,14},{0x0001, 2},{0x0000, 2},{0x0069, 7},
|
||||
{0x0068, 7},{0x35BD,14},{0x35BC,14},{0x35BF,14},
|
||||
{0x35BE,14},{0x35B9,14},{0x35B8,14},{0x35BB,14},
|
||||
{0x35BA,14},{0x35B5,14},{0x35B4,14},{0x01A9, 9},
|
||||
{0x01A8, 9},{0x035A,10},{0x00D7, 8},{0x00D5, 8},
|
||||
{0x003A, 6},{0x001B, 5},{0x35B7,14},{0x35B6,14}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*A description of a Huffman code value used when encoding the tree.*/
|
||||
typedef struct{
|
||||
/*The bit pattern, left-shifted so that the MSB of all patterns is
|
||||
aligned.*/
|
||||
ogg_uint32_t pattern;
|
||||
/*The amount the bit pattern was shifted.*/
|
||||
int shift;
|
||||
/*The token this bit pattern represents.*/
|
||||
int token;
|
||||
}oc_huff_entry;
|
||||
|
||||
|
||||
|
||||
/*Compares two oc_huff_entry structures by their bit patterns.
|
||||
_c1: The first entry to compare.
|
||||
_c2: The second entry to compare.
|
||||
Return: <0 if _c1<_c2, >0 if _c1>_c2.*/
|
||||
static int huff_entry_cmp(const void *_c1,const void *_c2){
|
||||
ogg_uint32_t b1;
|
||||
ogg_uint32_t b2;
|
||||
b1=((const oc_huff_entry *)_c1)->pattern;
|
||||
b2=((const oc_huff_entry *)_c2)->pattern;
|
||||
return b1<b2?-1:b1>b2?1:0;
|
||||
}
|
||||
|
||||
/*Encodes a description of the given Huffman tables.
|
||||
Although the codes are stored in the encoder as flat arrays, in the bit
|
||||
stream and in the decoder they are structured as a tree.
|
||||
This function recovers the tree structure from the flat array and then
|
||||
writes it out.
|
||||
Note that the codes MUST form a Huffman code, and not merely a prefix-free
|
||||
code, since the binary tree is assumed to be full.
|
||||
_opb: The buffer to store the tree in.
|
||||
_codes: The Huffman tables to pack.
|
||||
Return: 0 on success, or a negative value if one of the given Huffman tables
|
||||
does not form a full, prefix-free code.*/
|
||||
int oc_huff_codes_pack(oggpack_buffer *_opb,
|
||||
const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]){
|
||||
int i;
|
||||
for(i=0;i<TH_NHUFFMAN_TABLES;i++){
|
||||
oc_huff_entry entries[TH_NDCT_TOKENS];
|
||||
int bpos;
|
||||
int maxlen;
|
||||
int mask;
|
||||
int j;
|
||||
/*First, find the maximum code length so we can align all the bit
|
||||
patterns.*/
|
||||
maxlen=_codes[i][0].nbits;
|
||||
for(j=1;j<TH_NDCT_TOKENS;j++){
|
||||
maxlen=OC_MAXI(_codes[i][j].nbits,maxlen);
|
||||
}
|
||||
mask=(1<<(maxlen>>1)<<(maxlen+1>>1))-1;
|
||||
/*Copy over the codes into our temporary workspace.
|
||||
The bit patterns are aligned, and the original entry each code is from
|
||||
is stored as well.*/
|
||||
for(j=0;j<TH_NDCT_TOKENS;j++){
|
||||
entries[j].shift=maxlen-_codes[i][j].nbits;
|
||||
entries[j].pattern=_codes[i][j].pattern<<entries[j].shift&mask;
|
||||
entries[j].token=j;
|
||||
}
|
||||
/*Sort the codes into ascending order.
|
||||
This is the order the leaves of the tree will be traversed.*/
|
||||
qsort(entries,TH_NDCT_TOKENS,sizeof(entries[0]),huff_entry_cmp);
|
||||
/*For each leaf of the tree:*/
|
||||
bpos=maxlen;
|
||||
for(j=0;j<TH_NDCT_TOKENS;j++){
|
||||
int bit;
|
||||
/*If this code has any bits at all.*/
|
||||
if(entries[j].shift<maxlen){
|
||||
/*Descend into the tree, writing a bit for each branch.*/
|
||||
for(;bpos>entries[j].shift;bpos--)oggpackB_write(_opb,0,1);
|
||||
/*Mark this as a leaf node, and write its value.*/
|
||||
oggpackB_write(_opb,1,1);
|
||||
oggpackB_write(_opb,entries[j].token,5);
|
||||
/*For each 1 branch we've descended, back up the tree until we reach a
|
||||
0 branch.*/
|
||||
bit=1<<bpos;
|
||||
for(;entries[j].pattern&bit;bpos++)bit<<=1;
|
||||
/*Validate the code.*/
|
||||
if(j+1<TH_NDCT_TOKENS){
|
||||
mask=~(bit-1)<<1;
|
||||
/*The next entry should have a 1 bit where we had a 0, and should
|
||||
match our code above that bit.
|
||||
This verifies both fullness and prefix-freeness simultaneously.*/
|
||||
if(!(entries[j+1].pattern&bit)||
|
||||
(entries[j].pattern&mask)!=(entries[j+1].pattern&mask)){
|
||||
return TH_EINVAL;
|
||||
}
|
||||
}
|
||||
/*If there are no more codes, we should have ascended back to the top
|
||||
of the tree.*/
|
||||
else if(bpos<maxlen)return TH_EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#if !defined(_huffenc_H)
|
||||
# define _huffenc_H (1)
|
||||
# include "huffman.h"
|
||||
|
||||
|
||||
|
||||
typedef th_huff_code th_huff_table[TH_NDCT_TOKENS];
|
||||
|
||||
|
||||
|
||||
extern const th_huff_code
|
||||
TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
|
||||
|
||||
|
||||
|
||||
int oc_huff_codes_pack(oggpack_buffer *_opb,
|
||||
const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]);
|
||||
|
||||
#endif
|
||||
@@ -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-2009 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function:
|
||||
last mod: $Id: huffman.h 16503 2009-08-22 18:14:02Z 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 unsigned char OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS];
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user